blob: b6c9df748ddc0b5e693ff102a883439a173f98e6 [file] [log] [blame]
Guido van Rossum34679b71993-01-26 13:33:44 +00001/***********************************************************
2Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
4
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
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025#include "thread.h"
26
Guido van Rossumf9f2e821992-08-17 08:59:08 +000027#ifdef DEBUG
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +000028static int thread_debug = 0;
Sjoerd Mullender66bca321993-12-03 16:54:45 +000029#define dprintf(args) ((thread_debug & 1) && printf args)
30#define d2printf(args) ((thread_debug & 8) && printf args)
Guido van Rossumf9f2e821992-08-17 08:59:08 +000031#else
32#define dprintf(args)
Sjoerd Mullender66bca321993-12-03 16:54:45 +000033#define d2printf(args)
Guido van Rossumf9f2e821992-08-17 08:59:08 +000034#endif
35
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036#ifdef __sgi
37#include <stdlib.h>
38#include <stdio.h>
39#include <signal.h>
40#include <sys/types.h>
41#include <sys/prctl.h>
42#include <ulocks.h>
Sjoerd Mullendere8934121993-01-13 12:08:48 +000043#include <errno.h>
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044
Sjoerd Mullender76ab5fe1993-01-13 12:49:46 +000045#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
Guido van Rossumf9f2e821992-08-17 08:59:08 +000046#define MAXPROC 100 /* max # of threads that can be started */
47
Sjoerd Mullender66bca321993-12-03 16:54:45 +000048static usptr_t *shared_arena;
Guido van Rossumf9f2e821992-08-17 08:59:08 +000049static ulock_t count_lock; /* protection for some variables */
50static ulock_t wait_lock; /* lock used to wait for other threads */
51static int waiting_for_threads; /* protected by count_lock */
52static int nthreads; /* protected by count_lock */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053static int exit_status;
Sjoerd Mullendered59d201993-01-06 13:36:38 +000054static int do_exit; /* indicates that the program is to exit */
Guido van Rossumf9f2e821992-08-17 08:59:08 +000055static int exiting; /* we're already exiting (for maybe_exit) */
56static pid_t my_pid; /* PID of main thread */
57static pid_t pidlist[MAXPROC]; /* PIDs of other threads */
58static int maxpidindex; /* # of PIDs in pidlist */
Sjoerd Mullender66bca321993-12-03 16:54:45 +000059#endif /* __sgi */
60#ifdef SOLARIS
61#include <stdlib.h>
62#include <stdio.h>
63#include <unistd.h>
64#include </usr/include/thread.h>
65#undef sun
Guido van Rossum1984f1e1992-08-04 12:41:02 +000066#endif
67#ifdef sun
68#include <lwp/lwp.h>
69#include <lwp/stackdep.h>
70
Guido van Rossumf9f2e821992-08-17 08:59:08 +000071#define STACKSIZE 1000 /* stacksize for a thread */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000072#define NSTACKS 2 /* # stacks to be put in cache initialy */
73
74struct lock {
75 int lock_locked;
76 cv_t lock_condvar;
77 mon_t lock_monitor;
78};
Sjoerd Mullender66bca321993-12-03 16:54:45 +000079#endif /* sun */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000080#ifdef C_THREADS
81#include <cthreads.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000082#endif /* C_THREADS */
83#ifdef _POSIX_THREADS
84#include <pthread.h>
85#endif /* _POSIX_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000086
87#ifdef __STDC__
88#define _P(args) args
89#define _P0() (void)
90#define _P1(v,t) (t)
91#define _P2(v1,t1,v2,t2) (t1,t2)
92#else
93#define _P(args) ()
94#define _P0() ()
95#define _P1(v,t) (v) t;
96#define _P2(v1,t1,v2,t2) (v1,v2) t1; t2;
Sjoerd Mullender66bca321993-12-03 16:54:45 +000097#endif /* __STDC__ */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098
99static int initialized;
100
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000101#ifdef __sgi
102/*
103 * This routine is called as a signal handler when another thread
104 * exits. When that happens, we must see whether we have to exit as
105 * well (because of an exit_prog()) or whether we should continue on.
106 */
107static void exit_sig _P0()
108{
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000109 d2printf(("exit_sig called\n"));
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000110 if (exiting && getpid() == my_pid) {
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000111 d2printf(("already exiting\n"));
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000112 return;
113 }
114 if (do_exit) {
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000115 d2printf(("exiting in exit_sig\n"));
116#ifdef DEBUG
117 if ((thread_debug & 8) == 0)
118 thread_debug &= ~1; /* don't produce debug messages */
119#endif
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000120 exit_thread();
121 }
122}
123
124/*
125 * This routine is called when a process calls exit(). If that wasn't
126 * done from the library, we do as if an exit_prog() was intended.
127 */
128static void maybe_exit _P0()
129{
130 dprintf(("maybe_exit called\n"));
131 if (exiting) {
132 dprintf(("already exiting\n"));
133 return;
134 }
135 exit_prog(0);
136}
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000137#endif /* __sgi */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000138
139/*
140 * Initialization.
141 */
142void init_thread _P0()
143{
144#ifdef __sgi
145 struct sigaction s;
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000146#ifdef USE_DL
147 long addr, size;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000148#endif /* USE_DL */
149#endif /* __sgi */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000150
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000151#ifdef DEBUG
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000152 char *p = getenv("THREADDEBUG");
153
154 if (p) {
155 if (*p)
156 thread_debug = atoi(p);
157 else
158 thread_debug = 1;
159 }
160#endif /* DEBUG */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000161 if (initialized)
162 return;
163 initialized = 1;
Sjoerd Mullendered59d201993-01-06 13:36:38 +0000164 dprintf(("init_thread called\n"));
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000165
166#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000167#ifdef USE_DL
168 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
169 perror("usconfig - CONF_INITSIZE (check)");
170 if (usconfig(CONF_INITSIZE, size) < 0)
171 perror("usconfig - CONF_INITSIZE (reset)");
Sjoerd Mullender76ab5fe1993-01-13 12:49:46 +0000172 addr = (long) dl_getrange(size + HDR_SIZE);
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000173 dprintf(("trying to use addr %lx-%lx for shared arena\n", addr, addr+size));
174 errno = 0;
175 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
176 perror("usconfig - CONF_ATTACHADDR (set)");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000177#endif /* USE_DL */
Sjoerd Mullendered59d201993-01-06 13:36:38 +0000178 if (usconfig(CONF_INITUSERS, 16) < 0)
179 perror("usconfig - CONF_INITUSERS");
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000180 my_pid = getpid(); /* so that we know which is the main thread */
181 atexit(maybe_exit);
182 s.sa_handler = exit_sig;
183 sigemptyset(&s.sa_mask);
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000184 /*sigaddset(&s.sa_mask, SIGUSR1);*/
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000185 s.sa_flags = 0;
186 sigaction(SIGUSR1, &s, 0);
Sjoerd Mullendered59d201993-01-06 13:36:38 +0000187 if (prctl(PR_SETEXITSIG, SIGUSR1) < 0)
188 perror("prctl - PR_SETEXITSIG");
189 if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
190 perror("usconfig - CONF_ARENATYPE");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000191#ifdef DEBUG
192 if (thread_debug & 4)
193 usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
194 else if (thread_debug & 2)
195 usconfig(CONF_LOCKTYPE, US_DEBUG);
196#endif /* DEBUG */
Sjoerd Mullendered59d201993-01-06 13:36:38 +0000197 if ((shared_arena = usinit(tmpnam(0))) == 0)
198 perror("usinit");
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000199#ifdef USE_DL
200 if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
201 perror("usconfig - CONF_ATTACHADDR (reset)");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000202#endif /* USE_DL */
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000203 if ((count_lock = usnewlock(shared_arena)) == NULL)
204 perror("usnewlock (count_lock)");
205 (void) usinitlock(count_lock);
206 if ((wait_lock = usnewlock(shared_arena)) == NULL)
207 perror("usnewlock (wait_lock)");
208 dprintf(("arena start: %lx, arena size: %ld\n", (long) shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000209#endif /* __sgi */
210#ifdef SOLARIS
211 /* nothing */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000212#endif
213#ifdef sun
214 lwp_setstkcache(STACKSIZE, NSTACKS);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000215#endif /* sun */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000216#ifdef C_THREADS
217 cthread_init();
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000218#endif /* C_THREADS */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +0000219}
220
221/*
222 * Thread support.
223 */
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000224#ifdef SOLARIS
225struct func_arg {
226 void (*func) _P((void *));
227 void *arg;
228};
229
230static void *new_func _P1(funcarg, void *funcarg)
231{
232 void (*func) _P((void *));
233 void *arg;
234
235 func = ((struct func_arg *) funcarg)->func;
236 arg = ((struct func_arg *) funcarg)->arg;
237 free(funcarg);
238 (*func)(arg);
239 return 0;
240}
241#endif /* SOLARIS */
242
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000243int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
244{
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000245#ifdef SOLARIS
246 struct func_arg *funcarg;
247#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000248#ifdef sun
249 thread_t tid;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000250#endif /* sun */
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000251#if defined(__sgi) && defined(USE_DL)
252 long addr, size;
253 static int local_initialized = 0;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000254#endif /* __sgi and USE_DL */
255#ifdef _POSIX_THREADS
256 pthread_t th;
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000257#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000258 int success = 0; /* init not needed when SOLARIS and */
259 /* C_THREADS implemented properly */
260
261 dprintf(("start_new_thread called\n"));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000262 if (!initialized)
263 init_thread();
264#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000265 switch (ussetlock(count_lock)) {
266 case 0: return 0;
267 case -1: perror("ussetlock (count_lock)");
268 }
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000269 if (maxpidindex >= MAXPROC)
270 success = -1;
271 else {
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000272#ifdef USE_DL
273 if (!local_initialized) {
274 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
275 perror("usconfig - CONF_INITSIZE (check)");
276 if (usconfig(CONF_INITSIZE, size) < 0)
277 perror("usconfig - CONF_INITSIZE (reset)");
Sjoerd Mullender76ab5fe1993-01-13 12:49:46 +0000278 addr = (long) dl_getrange(size + HDR_SIZE);
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000279 dprintf(("trying to use addr %lx-%lx for sproc\n", addr, addr+size));
280 errno = 0;
281 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
282 perror("usconfig - CONF_ATTACHADDR (set)");
283 }
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000284#endif /* USE_DL */
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000285 if ((success = sproc(func, PR_SALL, arg)) < 0)
286 perror("sproc");
287#ifdef USE_DL
288 if (!local_initialized) {
289 if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
290 perror("usconfig - CONF_ATTACHADDR (reset)");
291 local_initialized = 1;
292 }
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000293#endif /* USE_DL */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000294 if (success >= 0) {
295 nthreads++;
296 pidlist[maxpidindex++] = success;
297 }
298 }
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000299 if (usunsetlock(count_lock) < 0)
300 perror("usunsetlock (count_lock)");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000301#endif /* __sgi */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000302#ifdef SOLARIS
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000303 funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
304 funcarg->func = func;
305 funcarg->arg = arg;
306 if (thr_create(0, 0, new_func, funcarg, THR_NEW_LWP, 0)) {
307 perror("thr_create");
308 free((void *) funcarg);
309 success = -1;
310 }
311#endif /* SOLARIS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000312#ifdef sun
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000313 success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000314#endif /* sun */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000315#ifdef C_THREADS
316 (void) cthread_fork(func, arg);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000317#endif /* C_THREADS */
318#ifdef _POSIX_THREADS
319 pthread_create(&th, NULL, func, arg);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000320#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000321 return success < 0 ? 0 : 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000322}
323
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000324static void do_exit_thread _P1(no_cleanup, int no_cleanup)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000325{
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000326 dprintf(("exit_thread called\n"));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000327 if (!initialized)
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000328 if (no_cleanup)
329 _exit(0);
330 else
331 exit(0);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000332#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000333 if (ussetlock(count_lock) < 0)
334 perror("ussetlock (count_lock)");
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000335 nthreads--;
336 if (getpid() == my_pid) {
337 /* main thread; wait for other threads to exit */
338 exiting = 1;
339 if (do_exit) {
340 int i;
341
342 /* notify other threads */
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000343 if (nthreads >= 0) {
344 dprintf(("kill other threads\n"));
345 for (i = 0; i < maxpidindex; i++)
346 (void) kill(pidlist[i], SIGKILL);
347 _exit(exit_status);
348 }
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000349 }
350 waiting_for_threads = 1;
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000351 if (ussetlock(wait_lock) < 0)
352 perror("ussetlock (wait_lock)");
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000353 for (;;) {
354 if (nthreads < 0) {
355 dprintf(("really exit (%d)\n", exit_status));
356 if (no_cleanup)
357 _exit(exit_status);
358 else
359 exit(exit_status);
360 }
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000361 if (usunsetlock(count_lock) < 0)
362 perror("usunsetlock (count_lock)");
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000363 dprintf(("waiting for other threads (%d)\n", nthreads));
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000364 if (ussetlock(wait_lock) < 0)
365 perror("ussetlock (wait_lock)");
366 if (ussetlock(count_lock) < 0)
367 perror("ussetlock (count_lock)");
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000368 }
369 }
370 /* not the main thread */
371 if (waiting_for_threads) {
372 dprintf(("main thread is waiting\n"));
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000373 if (usunsetlock(wait_lock) < 0)
374 perror("usunsetlock (wait_lock)");
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000375 } else if (do_exit)
376 (void) kill(my_pid, SIGUSR1);
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000377 if (usunsetlock(count_lock) < 0)
378 perror("usunsetlock (count_lock)");
Guido van Rossumff4949e1992-08-05 19:58:53 +0000379 _exit(0);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000380#endif /* __sgi */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000381#ifdef SOLARIS
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000382 thr_exit(0);
383#endif /* SOLARIS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000384#ifdef sun
385 lwp_destroy(SELF);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000386#endif /* sun */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000387#ifdef C_THREADS
388 cthread_exit(0);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000389#endif /* C_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000390}
391
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000392void exit_thread _P0()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000393{
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000394 do_exit_thread(0);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000395}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000396
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000397void _exit_thread _P0()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000398{
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000399 do_exit_thread(1);
400}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000401
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000402static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
403{
404 dprintf(("exit_prog(%d) called\n", status));
405 if (!initialized)
406 if (no_cleanup)
407 _exit(status);
408 else
409 exit(status);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000410#ifdef __sgi
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000411 do_exit = 1;
412 exit_status = status;
413 do_exit_thread(no_cleanup);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414#endif
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000415#ifdef SOLARIS
416 if (no_cleanup)
417 _exit(status);
418 else
419 exit(status);
420#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000421#ifdef sun
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000422 pod_exit(status);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000423#endif
424}
425
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000426void exit_prog _P1(status, int status)
427{
428 do_exit_prog(status, 0);
429}
430
431void _exit_prog _P1(status, int status)
432{
433 do_exit_prog(status, 1);
434}
435
436/*
437 * Lock support.
438 */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000439type_lock allocate_lock _P0()
440{
441#ifdef __sgi
442 ulock_t lock;
443#endif
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000444#ifdef SOLARIS
445 mutex_t *lock;
446#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000447#ifdef sun
448 struct lock *lock;
449 extern char *malloc();
450#endif
451
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000452 dprintf(("allocate_lock called\n"));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000453 if (!initialized)
454 init_thread();
455
456#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000457 if ((lock = usnewlock(shared_arena)) == NULL)
458 perror("usnewlock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459 (void) usinitlock(lock);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000460#endif /* __sgi */
461#ifdef SOLARIS
462 lock = (mutex_t *) malloc(sizeof(mutex_t));
463 if (mutex_init(lock, USYNC_THREAD, 0)) {
464 perror("mutex_init");
465 free((void *) lock);
466 lock = 0;
467 }
468#endif /* SOLARIS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000469#ifdef sun
470 lock = (struct lock *) malloc(sizeof(struct lock));
471 lock->lock_locked = 0;
472 (void) mon_create(&lock->lock_monitor);
473 (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000474#endif /* sun */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000475 dprintf(("allocate_lock() -> %lx\n", (long)lock));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000476 return (type_lock) lock;
477}
478
479void free_lock _P1(lock, type_lock lock)
480{
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000481 dprintf(("free_lock(%lx) called\n", (long)lock));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000482#ifdef __sgi
483 usfreelock((ulock_t) lock, shared_arena);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000484#endif /* __sgi */
485#ifdef SOLARIS
486 mutex_destroy((mutex_t *) lock);
487 free((void *) lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000488#endif
489#ifdef sun
490 mon_destroy(((struct lock *) lock)->lock_monitor);
491 free((char *) lock);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000492#endif /* sun */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000493}
494
495int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
496{
497 int success;
498
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000499 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000500#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000501 errno = 0; /* clear it just in case */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000502 if (waitflag)
503 success = ussetlock((ulock_t) lock);
504 else
505 success = uscsetlock((ulock_t) lock, 1); /* Try it once */
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000506 if (success < 0)
507 perror(waitflag ? "ussetlock" : "uscsetlock");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000508#endif /* __sgi */
509#ifdef SOLARIS
510 if (waitflag)
511 success = mutex_lock((mutex_t *) lock);
512 else
513 success = mutex_trylock((mutex_t *) lock);
514 if (success < 0)
515 perror(waitflag ? "mutex_lock" : "mutex_trylock");
516 else
517 success = !success; /* solaris does it the other way round */
518#endif /* SOLARIS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000519#ifdef sun
520 success = 0;
521
522 (void) mon_enter(((struct lock *) lock)->lock_monitor);
523 if (waitflag)
524 while (((struct lock *) lock)->lock_locked)
525 cv_wait(((struct lock *) lock)->lock_condvar);
526 if (!((struct lock *) lock)->lock_locked) {
527 success = 1;
528 ((struct lock *) lock)->lock_locked = 1;
529 }
530 cv_broadcast(((struct lock *) lock)->lock_condvar);
531 mon_exit(((struct lock *) lock)->lock_monitor);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000532#endif /* sun */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000533 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000534 return success;
535}
536
537void release_lock _P1(lock, type_lock lock)
538{
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000539 dprintf(("release_lock(%lx) called\n", (long)lock));
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000540#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000541 if (usunsetlock((ulock_t) lock) < 0)
542 perror("usunsetlock");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000543#endif /* __sgi */
544#ifdef SOLARIS
545 if (mutex_unlock((mutex_t *) lock))
546 perror("mutex_unlock");
547#endif /* SOLARIS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000548#ifdef sun
549 (void) mon_enter(((struct lock *) lock)->lock_monitor);
550 ((struct lock *) lock)->lock_locked = 0;
551 cv_broadcast(((struct lock *) lock)->lock_condvar);
552 mon_exit(((struct lock *) lock)->lock_monitor);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000553#endif /* sun */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554}
555
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000556/*
557 * Semaphore support.
558 */
559type_sema allocate_sema _P1(value, int value)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000560{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000561#ifdef __sgi
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000562 usema_t *sema;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000563#endif /* __sgi */
564#ifdef SOLARIS
565 sema_t *sema;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000566#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000567
568 dprintf(("allocate_sema called\n"));
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000569 if (!initialized)
570 init_thread();
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000571
572#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000573 if ((sema = usnewsema(shared_arena, value)) == NULL)
574 perror("usnewsema");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000575#endif /* __sgi */
576#ifdef SOLARIS
577 sema = (sema_t *) malloc(sizeof(sema_t));
578 if (sema_init(sema, value, USYNC_THREAD, 0)) {
579 perror("sema_init");
580 free((void *) sema);
581 sema = 0;
582 }
583#endif /* SOLARIS */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000584 dprintf(("allocate_sema() -> %lx\n", (long) sema));
585 return (type_sema) sema;
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000586}
587
588void free_sema _P1(sema, type_sema sema)
589{
590 dprintf(("free_sema(%lx) called\n", (long) sema));
591#ifdef __sgi
592 usfreesema((usema_t *) sema, shared_arena);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000593#endif /* __sgi */
594#ifdef SOLARIS
595 if (sema_destroy((sema_t *) sema))
596 perror("sema_destroy");
597 free((void *) sema);
598#endif /* SOLARIS */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000599}
600
601void down_sema _P1(sema, type_sema sema)
602{
603 dprintf(("down_sema(%lx) called\n", (long) sema));
604#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000605 if (uspsema((usema_t *) sema) < 0)
606 perror("uspsema");
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000607#endif
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000608#ifdef SOLARIS
609 if (sema_wait((sema_t *) sema))
610 perror("sema_wait");
611#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000612 dprintf(("down_sema(%lx) return\n", (long) sema));
613}
614
615void up_sema _P1(sema, type_sema sema)
616{
617 dprintf(("up_sema(%lx)\n", (long) sema));
618#ifdef __sgi
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000619 if (usvsema((usema_t *) sema) < 0)
620 perror("usvsema");
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000621#endif /* __sgi */
622#ifdef SOLARIS
623 if (sema_post((sema_t *) sema))
624 perror("sema_post");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000625#endif
626}