blob: 199d7d09d6f9309a80d8d1e7939260d31349109f [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <unistd.h>
28#include </usr/include/thread.h>
29
30
31/*
32 * Initialization.
33 */
34static void _init_thread _P0()
35{
36}
37
38/*
39 * Thread support.
40 */
41struct func_arg {
42 void (*func) _P((void *));
43 void *arg;
44};
45
46static void *new_func _P1(funcarg, void *funcarg)
47{
48 void (*func) _P((void *));
49 void *arg;
50
51 func = ((struct func_arg *) funcarg)->func;
52 arg = ((struct func_arg *) funcarg)->arg;
53 free(funcarg);
54 (*func)(arg);
55 return 0;
56}
57
58
59int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
60{
61 struct func_arg *funcarg;
62 int success = 0; /* init not needed when SOLARIS_THREADS and */
63 /* C_THREADS implemented properly */
64
65 dprintf(("start_new_thread called\n"));
66 if (!initialized)
67 init_thread();
68 funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
69 funcarg->func = func;
70 funcarg->arg = arg;
Guido van Rossum1ae940a1995-01-02 19:04:15 +000071 if (thr_create(0, 0, new_func, funcarg, THR_DETACHED, 0)) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000072 perror("thr_create");
73 free((void *) funcarg);
74 success = -1;
75 }
76 return success < 0 ? 0 : 1;
77}
78
Guido van Rossume944da81994-05-23 12:43:41 +000079long get_thread_ident _P0()
80{
81 if (!initialized)
82 init_thread();
83 return thr_self();
84}
85
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000086static void do_exit_thread _P1(no_cleanup, int no_cleanup)
87{
88 dprintf(("exit_thread called\n"));
89 if (!initialized)
90 if (no_cleanup)
91 _exit(0);
92 else
93 exit(0);
94 thr_exit(0);
95}
96
97void exit_thread _P0()
98{
99 do_exit_thread(0);
100}
101
102void _exit_thread _P0()
103{
104 do_exit_thread(1);
105}
106
107#ifndef NO_EXIT_PROG
108static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
109{
110 dprintf(("exit_prog(%d) called\n", status));
111 if (!initialized)
112 if (no_cleanup)
113 _exit(status);
114 else
115 exit(status);
116 if (no_cleanup)
117 _exit(status);
118 else
119 exit(status);
120}
121
122void exit_prog _P1(status, int status)
123{
124 do_exit_prog(status, 0);
125}
126
127void _exit_prog _P1(status, int status)
128{
129 do_exit_prog(status, 1);
130}
131#endif /* NO_EXIT_PROG */
132
133/*
134 * Lock support.
135 */
136type_lock allocate_lock _P0()
137{
138 mutex_t *lock;
139
140 dprintf(("allocate_lock called\n"));
141 if (!initialized)
142 init_thread();
143
144 lock = (mutex_t *) malloc(sizeof(mutex_t));
145 if (mutex_init(lock, USYNC_THREAD, 0)) {
146 perror("mutex_init");
147 free((void *) lock);
148 lock = 0;
149 }
150 dprintf(("allocate_lock() -> %lx\n", (long)lock));
151 return (type_lock) lock;
152}
153
154void free_lock _P1(lock, type_lock lock)
155{
156 dprintf(("free_lock(%lx) called\n", (long)lock));
157 mutex_destroy((mutex_t *) lock);
158 free((void *) lock);
159}
160
161int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
162{
163 int success;
164
165 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
166 if (waitflag)
167 success = mutex_lock((mutex_t *) lock);
168 else
169 success = mutex_trylock((mutex_t *) lock);
170 if (success < 0)
171 perror(waitflag ? "mutex_lock" : "mutex_trylock");
172 else
173 success = !success; /* solaris does it the other way round */
174 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
175 return success;
176}
177
178void release_lock _P1(lock, type_lock lock)
179{
180 dprintf(("release_lock(%lx) called\n", (long)lock));
181 if (mutex_unlock((mutex_t *) lock))
182 perror("mutex_unlock");
183}
184
185/*
186 * Semaphore support.
187 */
188type_sema allocate_sema _P1(value, int value)
189{
190 sema_t *sema;
191 dprintf(("allocate_sema called\n"));
192 if (!initialized)
193 init_thread();
194
195 sema = (sema_t *) malloc(sizeof(sema_t));
196 if (sema_init(sema, value, USYNC_THREAD, 0)) {
197 perror("sema_init");
198 free((void *) sema);
199 sema = 0;
200 }
201 dprintf(("allocate_sema() -> %lx\n", (long) sema));
202 return (type_sema) sema;
203}
204
205void free_sema _P1(sema, type_sema sema)
206{
207 dprintf(("free_sema(%lx) called\n", (long) sema));
208 if (sema_destroy((sema_t *) sema))
209 perror("sema_destroy");
210 free((void *) sema);
211}
212
213void down_sema _P1(sema, type_sema sema)
214{
215 dprintf(("down_sema(%lx) called\n", (long) sema));
216 if (sema_wait((sema_t *) sema))
217 perror("sema_wait");
218 dprintf(("down_sema(%lx) return\n", (long) sema));
219}
220
221void up_sema _P1(sema, type_sema sema)
222{
223 dprintf(("up_sema(%lx)\n", (long) sema));
224 if (sema_post((sema_t *) sema))
225 perror("sema_post");
226}