blob: 94b918245bcf3eee370c962c292e7ca2b923f412 [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#ifdef sun
26#define FLORIDA_HACKS
27#endif
28
29#ifdef FLORIDA_HACKS
30/* Hacks for Florida State Posix threads implementation */
31#undef _POSIX_THREADS
Guido van Rossumb98b1b31994-05-11 08:42:04 +000032#include "/ufs/guido/src/python/Contrib/pthreads/src/pthread.h"
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000033#define pthread_attr_default ((pthread_attr_t *)0)
34#define pthread_mutexattr_default ((pthread_mutexattr_t *)0)
35#define pthread_condattr_default ((pthread_condattr_t *)0)
36#define TRYLOCK_OFFSET 1
37#else /* !FLORIDA_HACKS */
38#include <pthread.h>
39#define TRYLOCK_OFFSET 0
40#endif /* FLORIDA_HACKS */
41#include <stdlib.h>
42
Guido van Rossumb98b1b31994-05-11 08:42:04 +000043/* A pthread mutex isn't sufficient to model the Python lock type
44 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
45 * following are undefined:
46 * -> a thread tries to lock a mutex it already has locked
47 * -> a thread tries to unlock a mutex locked by a different thread
48 * pthread mutexes are designed for serializing threads over short pieces
49 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000050 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +000051 *
52 * The pthread_lock struct implements a Python lock as a "locked?" bit
53 * and a <condition, mutex> pair. In general, if the bit can be acquired
54 * instantly, it is, else the pair is used to block the thread until the
55 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000056 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +000057
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000058typedef struct {
Guido van Rossumb98b1b31994-05-11 08:42:04 +000059 char locked; /* 0=unlocked, 1=locked */
60 /* a <cond, mutex> pair to handle an acquire of a locked lock */
61 pthread_cond_t lock_released;
62 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000063} pthread_lock;
64
Guido van Rossumb98b1b31994-05-11 08:42:04 +000065#define CHECK_STATUS(name) if (status < 0) { perror(name); error=1; }
66
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000067/*
68 * Initialization.
69 */
70static void _init_thread _P0()
71{
72}
73
74/*
75 * Thread support.
76 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +000077
78
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000079int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
80{
81#if defined(SGI_THREADS) && defined(USE_DL)
82 long addr, size;
83 static int local_initialized = 0;
84#endif /* SGI_THREADS and USE_DL */
85 pthread_t th;
Guido van Rossume944da81994-05-23 12:43:41 +000086 int success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000087 dprintf(("start_new_thread called\n"));
88 if (!initialized)
89 init_thread();
90 success = pthread_create(&th, pthread_attr_default, func, arg);
91 return success < 0 ? 0 : 1;
92}
93
Guido van Rossume944da81994-05-23 12:43:41 +000094long get_thread_ident _P0()
95{
96 if (!initialized)
97 init_thread();
98 return (long) pthread_self();
99}
100
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000101static void do_exit_thread _P1(no_cleanup, int no_cleanup)
102{
103 dprintf(("exit_thread called\n"));
104 if (!initialized)
105 if (no_cleanup)
106 _exit(0);
107 else
108 exit(0);
109}
110
111void exit_thread _P0()
112{
113 do_exit_thread(0);
114}
115
116void _exit_thread _P0()
117{
118 do_exit_thread(1);
119}
120
121#ifndef NO_EXIT_PROG
122static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
123{
124 dprintf(("exit_prog(%d) called\n", status));
125 if (!initialized)
126 if (no_cleanup)
127 _exit(status);
128 else
129 exit(status);
130}
131
132void exit_prog _P1(status, int status)
133{
134 do_exit_prog(status, 0);
135}
136
137void _exit_prog _P1(status, int status)
138{
139 do_exit_prog(status, 1);
140}
141#endif /* NO_EXIT_PROG */
142
143/*
144 * Lock support.
145 */
146type_lock allocate_lock _P0()
147{
148 pthread_lock *lock;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000149 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000150
151 dprintf(("allocate_lock called\n"));
152 if (!initialized)
153 init_thread();
154
155 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000156 if (lock) {
157 lock->locked = 0;
158
159 status = pthread_mutex_init(&lock->mut,
160 pthread_mutexattr_default);
161 CHECK_STATUS("pthread_mutex_init");
162
163 status = pthread_cond_init(&lock->lock_released,
164 pthread_condattr_default);
165 CHECK_STATUS("pthread_cond_init");
166
167 if (error) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000168 free((void *)lock);
169 lock = 0;
170 }
171 }
172
173 dprintf(("allocate_lock() -> %lx\n", (long)lock));
174 return (type_lock) lock;
175}
176
177void free_lock _P1(lock, type_lock lock)
178{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000179 pthread_lock *thelock = (pthread_lock *)lock;
180 int status, error = 0;
181
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000182 dprintf(("free_lock(%lx) called\n", (long)lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000183
184 status = pthread_mutex_destroy( &thelock->mut );
185 CHECK_STATUS("pthread_mutex_destroy");
186
187 status = pthread_cond_destroy( &thelock->lock_released );
188 CHECK_STATUS("pthread_cond_destroy");
189
190 free((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000191}
192
193int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
194{
195 int success;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000196 pthread_lock *thelock = (pthread_lock *)lock;
197 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000198
199 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000200
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000201 status = pthread_mutex_lock( &thelock->mut );
202 CHECK_STATUS("pthread_mutex_lock[1]");
203 success = thelock->locked == 0;
204 if (success) thelock->locked = 1;
205 status = pthread_mutex_unlock( &thelock->mut );
206 CHECK_STATUS("pthread_mutex_unlock[1]");
207
208 if ( !success && waitflag ) {
209 /* continue trying until we get the lock */
210
211 /* mut must be locked by me -- part of the condition
212 * protocol */
213 status = pthread_mutex_lock( &thelock->mut );
214 CHECK_STATUS("pthread_mutex_lock[2]");
215 while ( thelock->locked ) {
216 status = pthread_cond_wait(&thelock->lock_released,
217 &thelock->mut);
218 CHECK_STATUS("pthread_cond_wait");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000219 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000220 thelock->locked = 1;
221 status = pthread_mutex_unlock( &thelock->mut );
222 CHECK_STATUS("pthread_mutex_unlock[2]");
223 success = 1;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000224 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000225 if (error) success = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000226 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
227 return success;
228}
229
230void release_lock _P1(lock, type_lock lock)
231{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000232 pthread_lock *thelock = (pthread_lock *)lock;
233 int status, error = 0;
234
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000235 dprintf(("release_lock(%lx) called\n", (long)lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000236
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000237 status = pthread_mutex_lock( &thelock->mut );
238 CHECK_STATUS("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000239
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000240 thelock->locked = 0;
241
242 status = pthread_mutex_unlock( &thelock->mut );
243 CHECK_STATUS("pthread_mutex_unlock[3]");
244
245 /* wake up someone (anyone, if any) waiting on the lock */
246 status = pthread_cond_signal( &thelock->lock_released );
247 CHECK_STATUS("pthread_cond_signal");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000248}
249
250/*
251 * Semaphore support.
252 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000253/* NOTE: 100% non-functional at this time - tim */
254
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000255type_sema allocate_sema _P1(value, int value)
256{
257 char *sema = 0;
258 dprintf(("allocate_sema called\n"));
259 if (!initialized)
260 init_thread();
261
262 dprintf(("allocate_sema() -> %lx\n", (long) sema));
263 return (type_sema) sema;
264}
265
266void free_sema _P1(sema, type_sema sema)
267{
268 dprintf(("free_sema(%lx) called\n", (long) sema));
269}
270
271void down_sema _P1(sema, type_sema sema)
272{
273 dprintf(("down_sema(%lx) called\n", (long) sema));
274 dprintf(("down_sema(%lx) return\n", (long) sema));
275}
276
277void up_sema _P1(sema, type_sema sema)
278{
279 dprintf(("up_sema(%lx)\n", (long) sema));
280}