@@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2929#ifdef FLORIDA_HACKS
3030/* Hacks for Florida State Posix threads implementation */
3131#undef _POSIX_THREADS
32- #include "/ufs/guido/src/python/Contrib/pthreads/pthreads /pthread.h"
32+ #include "/ufs/guido/src/python/Contrib/pthreads/src /pthread.h"
3333#define pthread_attr_default ((pthread_attr_t *)0)
3434#define pthread_mutexattr_default ((pthread_mutexattr_t *)0)
3535#define pthread_condattr_default ((pthread_condattr_t *)0)
@@ -40,26 +40,30 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4040#endif /* FLORIDA_HACKS */
4141#include <stdlib.h>
4242
43- /* A pthread mutex isn't sufficient to model the Python lock type (at
44- * least not the way KSR did 'em -- haven't dug thru the docs to verify),
45- * because a thread that locks a mutex can't then do a pthread_mutex_lock
46- * on it (to wait for another thread to unlock it).
47- * In any case, pthread mutexes are designed for serializing threads over
48- * short pieces of code, so wouldn't be an appropriate implementation of
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
4950 * Python's locks regardless.
50- * The pthread_lock struct below implements a Python lock as a pthread
51- * mutex and a <condition, mutex> pair. In general, if the mutex can be
52- * be acquired instantly, it is, else the pair is used to block the
53- * thread until the mutex is released. 7 May 1994 [email protected] 51+ *
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 [email protected] 5456 */
57+
5558typedef struct {
56- /* the lock */
57- pthread_mutex_t mutex ;
58- /* a <cond, mutex> pair to handle an acquire of a locked mutex */
59- pthread_cond_t cond ;
60- pthread_mutex_t cmutex ;
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 ;
6163} pthread_lock ;
6264
65+ #define CHECK_STATUS (name ) if (status < 0) { perror(name); error=1; }
66+
6367/*
6468 * Initialization.
6569 */
@@ -70,6 +74,8 @@ static void _init_thread _P0()
7074/*
7175 * Thread support.
7276 */
77+
78+
7379int start_new_thread _P2 (func , void (* func ) _P ((void * ) ), arg , void * arg )
7480{
7581#if defined(SGI_THREADS ) && defined(USE_DL )
@@ -135,30 +141,25 @@ void _exit_prog _P1(status, int status)
135141type_lock allocate_lock _P0 ()
136142{
137143 pthread_lock * lock ;
144+ int status , error = 0 ;
138145
139146 dprintf (("allocate_lock called\n" ));
140147 if (!initialized )
141148 init_thread ();
142149
143150 lock = (pthread_lock * ) malloc (sizeof (pthread_lock ));
144- {
145- int err = 0 ;
146- if ( pthread_mutex_init (& lock -> mutex ,
147- pthread_mutexattr_default ) ) {
148- perror ("pthread_mutex_init" );
149- err = 1 ;
150- }
151- if ( pthread_cond_init (& lock -> cond ,
152- pthread_condattr_default ) ) {
153- perror ("pthread_cond_init" );
154- err = 1 ;
155- }
156- if ( pthread_mutex_init (& lock -> cmutex ,
157- pthread_mutexattr_default )) {
158- perror ("pthread_mutex_init" );
159- err = 1 ;
160- }
161- if (err ) {
151+ if (lock ) {
152+ lock -> locked = 0 ;
153+
154+ status = pthread_mutex_init (& lock -> mut ,
155+ pthread_mutexattr_default );
156+ CHECK_STATUS ("pthread_mutex_init" );
157+
158+ status = pthread_cond_init (& lock -> lock_released ,
159+ pthread_condattr_default );
160+ CHECK_STATUS ("pthread_cond_init" );
161+
162+ if (error ) {
162163 free ((void * )lock );
163164 lock = 0 ;
164165 }
@@ -170,80 +171,82 @@ type_lock allocate_lock _P0()
170171
171172void free_lock _P1 (lock , type_lock lock )
172173{
174+ pthread_lock * thelock = (pthread_lock * )lock ;
175+ int status , error = 0 ;
176+
173177 dprintf (("free_lock(%lx) called\n" , (long )lock ));
174- if ( pthread_mutex_destroy (& ((pthread_lock * )lock )-> mutex ) )
175- perror ("pthread_mutex_destroy" );
176- if ( pthread_cond_destroy (& ((pthread_lock * )lock )-> cond ) )
177- perror ("pthread_cond_destroy" );
178- if ( pthread_mutex_destroy (& ((pthread_lock * )lock )-> cmutex ) )
179- perror ("pthread_mutex_destroy" );
180- free ((void * )lock );
178+
179+ status = pthread_mutex_destroy ( & thelock -> mut );
180+ CHECK_STATUS ("pthread_mutex_destroy" );
181+
182+ status = pthread_cond_destroy ( & thelock -> lock_released );
183+ CHECK_STATUS ("pthread_cond_destroy" );
184+
185+ free ((void * )thelock );
181186}
182187
183188int acquire_lock _P2 (lock , type_lock lock , waitflag , int waitflag )
184189{
185190 int success ;
191+ pthread_lock * thelock = (pthread_lock * )lock ;
192+ int status , error = 0 ;
186193
187194 dprintf (("acquire_lock(%lx, %d) called\n" , (long )lock , waitflag ));
188- {
189- pthread_lock * thelock = (pthread_lock * )lock ;
190- success = TRYLOCK_OFFSET +
191- pthread_mutex_trylock ( & thelock -> mutex );
192- if (success < 0 ) {
193- perror ("pthread_mutex_trylock [1]" );
194- success = 0 ;
195- } else if ( success == 0 && waitflag ) {
196- /* continue trying until we get the lock */
197-
198- /* cmutex must be locked by me -- part of the condition
199- * protocol */
200- if ( pthread_mutex_lock ( & thelock -> cmutex ) )
201- perror ("pthread_mutex_lock" );
202- while ( 0 == (success = TRYLOCK_OFFSET +
203- pthread_mutex_trylock (& thelock -> mutex )) ) {
204- if ( pthread_cond_wait (& thelock -> cond ,
205- & thelock -> cmutex ) )
206- perror ("pthread_cond_wait" );
207- }
208- if (success < 0 )
209- perror ("pthread_mutex_trylock [2]" );
210- /* now ->mutex & ->cmutex are both locked by me */
211- if ( pthread_mutex_unlock ( & thelock -> cmutex ) )
212- perror ("pthread_mutex_unlock" );
195+
196+ status = pthread_mutex_lock ( & thelock -> mut );
197+ CHECK_STATUS ("pthread_mutex_lock[1]" );
198+ success = thelock -> locked == 0 ;
199+ if (success ) thelock -> locked = 1 ;
200+ status = pthread_mutex_unlock ( & thelock -> mut );
201+ CHECK_STATUS ("pthread_mutex_unlock[1]" );
202+
203+ if ( !success && waitflag ) {
204+ /* continue trying until we get the lock */
205+
206+ /* mut must be locked by me -- part of the condition
207+ * protocol */
208+ status = pthread_mutex_lock ( & thelock -> mut );
209+ CHECK_STATUS ("pthread_mutex_lock[2]" );
210+ while ( thelock -> locked ) {
211+ status = pthread_cond_wait (& thelock -> lock_released ,
212+ & thelock -> mut );
213+ CHECK_STATUS ("pthread_cond_wait" );
213214 }
215+ thelock -> locked = 1 ;
216+ status = pthread_mutex_unlock ( & thelock -> mut );
217+ CHECK_STATUS ("pthread_mutex_unlock[2]" );
218+ success = 1 ;
214219 }
220+ if (error ) success = 0 ;
215221 dprintf (("acquire_lock(%lx, %d) -> %d\n" , (long )lock , waitflag , success ));
216222 return success ;
217223}
218224
219225void release_lock _P1 (lock , type_lock lock )
220226{
227+ pthread_lock * thelock = (pthread_lock * )lock ;
228+ int status , error = 0 ;
229+
221230 dprintf (("release_lock(%lx) called\n" , (long )lock ));
222- {
223- pthread_lock * thelock = (pthread_lock * )lock ;
224-
225- /* tricky: if the release & signal occur between the
226- * pthread_mutex_trylock(&thelock->mutex))
227- * and pthread_cond_wait during the acquire, the acquire
228- * will miss the signal it's waiting for; locking cmutex
229- * around the release prevents that
230- */
231- if (pthread_mutex_lock ( & thelock -> cmutex ))
232- perror ("pthread_mutex_lock" );
233- if (pthread_mutex_unlock ( & thelock -> mutex ))
234- perror ("pthread_mutex_unlock" );
235- if (pthread_mutex_unlock ( & thelock -> cmutex ))
236- perror ("pthread_mutex_unlock" );
237-
238- /* wake up someone (anyone, if any) waiting on the lock */
239- if (pthread_cond_signal ( & thelock -> cond ))
240- perror ("pthread_cond_signal" );
241- }
231+
232+ status = pthread_mutex_lock ( & thelock -> mut );
233+ CHECK_STATUS ("pthread_mutex_lock[3]" );
234+
235+ thelock -> locked = 0 ;
236+
237+ status = pthread_mutex_unlock ( & thelock -> mut );
238+ CHECK_STATUS ("pthread_mutex_unlock[3]" );
239+
240+ /* wake up someone (anyone, if any) waiting on the lock */
241+ status = pthread_cond_signal ( & thelock -> lock_released );
242+ CHECK_STATUS ("pthread_cond_signal" );
242243}
243244
244245/*
245246 * Semaphore support.
246247 */
248+ /* NOTE: 100% non-functional at this time - tim */
249+
247250type_sema allocate_sema _P1 (value , int value )
248251{
249252 char * sema = 0 ;
0 commit comments