blob: 4aa06cf8025505b4df84a5dbf4e583cb033149e1 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001#include "thread.h"
2
3#ifdef __sgi
4#include <stdlib.h>
5#include <stdio.h>
6#include <signal.h>
7#include <sys/types.h>
8#include <sys/prctl.h>
9#include <ulocks.h>
10
11static usptr_t *shared_arena;
12static int exit_status;
13static int do_exit;
14static int exiting;
15#endif
16#ifdef sun
17#include <lwp/lwp.h>
18#include <lwp/stackdep.h>
19
Guido van Rossumff4949e1992-08-05 19:58:53 +000020#define STACKSIZE 16000 /* stacksize for a thread */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000021#define NSTACKS 2 /* # stacks to be put in cache initialy */
22
23struct lock {
24 int lock_locked;
25 cv_t lock_condvar;
26 mon_t lock_monitor;
27};
28#endif
29#ifdef C_THREADS
30#include <cthreads.h>
31#endif
32
33#ifdef __STDC__
34#define _P(args) args
35#define _P0() (void)
36#define _P1(v,t) (t)
37#define _P2(v1,t1,v2,t2) (t1,t2)
38#else
39#define _P(args) ()
40#define _P0() ()
41#define _P1(v,t) (v) t;
42#define _P2(v1,t1,v2,t2) (v1,v2) t1; t2;
43#endif
44
45static int initialized;
46
47int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
48{
49#ifdef sun
50 thread_t tid;
51#endif
52#ifdef DEBUG
53 printf("start_new_thread called\n");
54#endif
55 if (!initialized)
56 init_thread();
57#ifdef __sgi
58 if (sproc(func, PR_SALL, arg) < 0)
59 return 0;
60 return 1;
61#endif
62#ifdef SOLARIS
63 (void) thread_create(0, 0, func, arg, THREAD_NEW_LWP);
64#endif
65#ifdef sun
66 if (lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg) < 0)
67 return 0;
68 return 1;
69#endif
70#ifdef C_THREADS
71 (void) cthread_fork(func, arg);
72#endif
73}
74
75#ifdef __sgi
76void maybe_exit _P0()
77{
78 if (exiting)
79 return;
80 exit_prog(0);
81}
82#endif
83
84void exit_thread _P0()
85{
86#ifdef DEBUG
87 printf("exit_thread called\n");
88#endif
89 if (!initialized)
90 exit(0);
91#ifdef __sgi
92 exiting = 1;
Guido van Rossumff4949e1992-08-05 19:58:53 +000093 _exit(0);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000094#endif
95#ifdef SOLARIS
96 thread_exit();
97#endif
98#ifdef sun
99 lwp_destroy(SELF);
100#endif
101#ifdef C_THREADS
102 cthread_exit(0);
103#endif
104}
105
106#ifdef __sgi
107static void exit_sig _P0()
108{
109#ifdef DEBUG
110 printf("exit_sig called\n");
111#endif
112 if (do_exit) {
113#ifdef DEBUG
114 printf("exiting in exit_sig\n");
115#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000116 _exit(exit_status);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000117 }
118}
119#endif
120
121void init_thread _P0()
122{
123#ifdef __sgi
124 struct sigaction s;
125#endif
126
127#ifdef DEBUG
128 printf("init_thread called\n");
129#endif
130 initialized = 1;
131
132#ifdef __sgi
133 atexit(maybe_exit);
134 s.sa_handler = exit_sig;
135 sigemptyset(&s.sa_mask);
136 sigaddset(&s.sa_mask, SIGUSR1);
137 s.sa_flags = 0;
138 sigaction(SIGUSR1, &s, 0);
139 prctl(PR_SETEXITSIG, SIGUSR1);
140 usconfig(CONF_ARENATYPE, US_SHAREDONLY);
141 /*usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);*/
142 shared_arena = usinit(tmpnam(0));
143#endif
144#ifdef sun
145 lwp_setstkcache(STACKSIZE, NSTACKS);
146#endif
147#ifdef C_THREADS
148 cthread_init();
149#endif
150}
151
152type_lock allocate_lock _P0()
153{
154#ifdef __sgi
155 ulock_t lock;
156#endif
157#ifdef sun
158 struct lock *lock;
159 extern char *malloc();
160#endif
161
162#ifdef DEBUG
163 printf("allocate_lock called\n");
164#endif
165 if (!initialized)
166 init_thread();
167
168#ifdef __sgi
169 lock = usnewlock(shared_arena);
170 (void) usinitlock(lock);
171#endif
172#ifdef sun
173 lock = (struct lock *) malloc(sizeof(struct lock));
174 lock->lock_locked = 0;
175 (void) mon_create(&lock->lock_monitor);
176 (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
177#endif
178#ifdef DEBUG
179 printf("allocate_lock() -> %lx\n", (long)lock);
180#endif
181 return (type_lock) lock;
182}
183
184void free_lock _P1(lock, type_lock lock)
185{
186#ifdef DEBUG
187 printf("free_lock(%lx) called\n", (long)lock);
188#endif
189#ifdef __sgi
190 usfreelock((ulock_t) lock, shared_arena);
191#endif
192#ifdef sun
193 mon_destroy(((struct lock *) lock)->lock_monitor);
194 free((char *) lock);
195#endif
196}
197
198int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
199{
200 int success;
201
202#ifdef DEBUG
203 printf("acquire_lock(%lx, %d) called\n", (long)lock, waitflag);
204#endif
205#ifdef __sgi
206 if (waitflag)
207 success = ussetlock((ulock_t) lock);
208 else
209 success = uscsetlock((ulock_t) lock, 1); /* Try it once */
210#endif
211#ifdef sun
212 success = 0;
213
214 (void) mon_enter(((struct lock *) lock)->lock_monitor);
215 if (waitflag)
216 while (((struct lock *) lock)->lock_locked)
217 cv_wait(((struct lock *) lock)->lock_condvar);
218 if (!((struct lock *) lock)->lock_locked) {
219 success = 1;
220 ((struct lock *) lock)->lock_locked = 1;
221 }
222 cv_broadcast(((struct lock *) lock)->lock_condvar);
223 mon_exit(((struct lock *) lock)->lock_monitor);
224#endif
225#ifdef DEBUG
226 printf("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success);
227#endif
228 return success;
229}
230
231void release_lock _P1(lock, type_lock lock)
232{
233#ifdef DEBUG
234 printf("release lock(%lx) called\n", (long)lock);
235#endif
236#ifdef __sgi
237 (void) usunsetlock((ulock_t) lock);
238#endif
239#ifdef sun
240 (void) mon_enter(((struct lock *) lock)->lock_monitor);
241 ((struct lock *) lock)->lock_locked = 0;
242 cv_broadcast(((struct lock *) lock)->lock_condvar);
243 mon_exit(((struct lock *) lock)->lock_monitor);
244#endif
245}
246
247void exit_prog _P1(status, int status)
248{
249#ifdef DEBUG
250 printf("exit_prog(%d) called\n", status);
251#endif
252 if (!initialized)
253 exit(status);
254#ifdef __sgi
255 exiting = 1;
256 do_exit = 1;
257 exit_status = status;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000258 _exit(status);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000259#endif
260#ifdef sun
261 pod_exit(status);
262#endif
263}