This commit was manufactured by cvs2svn to create tag 'cnrisync'.
[python/dscho.git] / Python / thread_pthread.h
bloba4222cf1e068d1ece3073b84f815482bb911b37d
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 #ifdef sun
26 #define FLORIDA_HACKS
27 #endif
29 #ifdef FLORIDA_HACKS
30 /* Hacks for Florida State Posix threads implementation */
31 #undef _POSIX_THREADS
32 #include "/ufs/guido/src/python/Contrib/pthreads/src/pthread.h"
33 #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>
43 /* 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
50 * Python's locks regardless.
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
58 typedef struct {
59 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;
63 } pthread_lock;
65 #define CHECK_STATUS(name) if (status < 0) { perror(name); error=1; }
68 * Initialization.
70 static void _init_thread _P0()
75 * Thread support.
79 int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
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;
86 int success;
87 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;
94 long get_thread_ident _P0()
96 pthread_t threadid;
97 if (!initialized)
98 init_thread();
99 /* Jump through some hoops for Alpha OSF/1 */
100 threadid = pthread_self();
101 return (long) *(long *) &threadid;
104 static void do_exit_thread _P1(no_cleanup, int no_cleanup)
106 dprintf(("exit_thread called\n"));
107 if (!initialized)
108 if (no_cleanup)
109 _exit(0);
110 else
111 exit(0);
114 void exit_thread _P0()
116 do_exit_thread(0);
119 void _exit_thread _P0()
121 do_exit_thread(1);
124 #ifndef NO_EXIT_PROG
125 static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
127 dprintf(("exit_prog(%d) called\n", status));
128 if (!initialized)
129 if (no_cleanup)
130 _exit(status);
131 else
132 exit(status);
135 void exit_prog _P1(status, int status)
137 do_exit_prog(status, 0);
140 void _exit_prog _P1(status, int status)
142 do_exit_prog(status, 1);
144 #endif /* NO_EXIT_PROG */
147 * Lock support.
149 type_lock allocate_lock _P0()
151 pthread_lock *lock;
152 int status, error = 0;
154 dprintf(("allocate_lock called\n"));
155 if (!initialized)
156 init_thread();
158 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
159 if (lock) {
160 lock->locked = 0;
162 status = pthread_mutex_init(&lock->mut,
163 pthread_mutexattr_default);
164 CHECK_STATUS("pthread_mutex_init");
166 status = pthread_cond_init(&lock->lock_released,
167 pthread_condattr_default);
168 CHECK_STATUS("pthread_cond_init");
170 if (error) {
171 free((void *)lock);
172 lock = 0;
176 dprintf(("allocate_lock() -> %lx\n", (long)lock));
177 return (type_lock) lock;
180 void free_lock _P1(lock, type_lock lock)
182 pthread_lock *thelock = (pthread_lock *)lock;
183 int status, error = 0;
185 dprintf(("free_lock(%lx) called\n", (long)lock));
187 status = pthread_mutex_destroy( &thelock->mut );
188 CHECK_STATUS("pthread_mutex_destroy");
190 status = pthread_cond_destroy( &thelock->lock_released );
191 CHECK_STATUS("pthread_cond_destroy");
193 free((void *)thelock);
196 int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
198 int success;
199 pthread_lock *thelock = (pthread_lock *)lock;
200 int status, error = 0;
202 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
204 status = pthread_mutex_lock( &thelock->mut );
205 CHECK_STATUS("pthread_mutex_lock[1]");
206 success = thelock->locked == 0;
207 if (success) thelock->locked = 1;
208 status = pthread_mutex_unlock( &thelock->mut );
209 CHECK_STATUS("pthread_mutex_unlock[1]");
211 if ( !success && waitflag ) {
212 /* continue trying until we get the lock */
214 /* mut must be locked by me -- part of the condition
215 * protocol */
216 status = pthread_mutex_lock( &thelock->mut );
217 CHECK_STATUS("pthread_mutex_lock[2]");
218 while ( thelock->locked ) {
219 status = pthread_cond_wait(&thelock->lock_released,
220 &thelock->mut);
221 CHECK_STATUS("pthread_cond_wait");
223 thelock->locked = 1;
224 status = pthread_mutex_unlock( &thelock->mut );
225 CHECK_STATUS("pthread_mutex_unlock[2]");
226 success = 1;
228 if (error) success = 0;
229 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
230 return success;
233 void release_lock _P1(lock, type_lock lock)
235 pthread_lock *thelock = (pthread_lock *)lock;
236 int status, error = 0;
238 dprintf(("release_lock(%lx) called\n", (long)lock));
240 status = pthread_mutex_lock( &thelock->mut );
241 CHECK_STATUS("pthread_mutex_lock[3]");
243 thelock->locked = 0;
245 status = pthread_mutex_unlock( &thelock->mut );
246 CHECK_STATUS("pthread_mutex_unlock[3]");
248 /* wake up someone (anyone, if any) waiting on the lock */
249 status = pthread_cond_signal( &thelock->lock_released );
250 CHECK_STATUS("pthread_cond_signal");
254 * Semaphore support.
256 /* NOTE: 100% non-functional at this time - tim */
258 type_sema allocate_sema _P1(value, int value)
260 char *sema = 0;
261 dprintf(("allocate_sema called\n"));
262 if (!initialized)
263 init_thread();
265 dprintf(("allocate_sema() -> %lx\n", (long) sema));
266 return (type_sema) sema;
269 void free_sema _P1(sema, type_sema sema)
271 dprintf(("free_sema(%lx) called\n", (long) sema));
274 void down_sema _P1(sema, type_sema sema)
276 dprintf(("down_sema(%lx) called\n", (long) sema));
277 dprintf(("down_sema(%lx) return\n", (long) sema));
280 void up_sema _P1(sema, type_sema sema)
282 dprintf(("up_sema(%lx)\n", (long) sema));