@@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
29
#ifdef FLORIDA_HACKS
30
30
/* Hacks for Florida State Posix threads implementation */
31
31
#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"
33
33
#define pthread_attr_default ((pthread_attr_t *)0)
34
34
#define pthread_mutexattr_default ((pthread_mutexattr_t *)0)
35
35
#define pthread_condattr_default ((pthread_condattr_t *)0)
@@ -40,26 +40,30 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40
40
#endif /* FLORIDA_HACKS */
41
41
#include <stdlib.h>
42
42
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
49
50
* 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 tim@ksr.com
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 tim@ksr.com
54
56
*/
57
+
55
58
typedef 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 ;
61
63
} pthread_lock ;
62
64
65
+ #define CHECK_STATUS (name ) if (status < 0) { perror(name); error=1; }
66
+
63
67
/*
64
68
* Initialization.
65
69
*/
@@ -70,6 +74,8 @@ static void _init_thread _P0()
70
74
/*
71
75
* Thread support.
72
76
*/
77
+
78
+
73
79
int start_new_thread _P2 (func , void (* func ) _P ((void * ) ), arg , void * arg )
74
80
{
75
81
#if defined(SGI_THREADS ) && defined(USE_DL )
@@ -135,30 +141,25 @@ void _exit_prog _P1(status, int status)
135
141
type_lock allocate_lock _P0 ()
136
142
{
137
143
pthread_lock * lock ;
144
+ int status , error = 0 ;
138
145
139
146
dprintf (("allocate_lock called\n" ));
140
147
if (!initialized )
141
148
init_thread ();
142
149
143
150
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 ) {
162
163
free ((void * )lock );
163
164
lock = 0 ;
164
165
}
@@ -170,80 +171,82 @@ type_lock allocate_lock _P0()
170
171
171
172
void free_lock _P1 (lock , type_lock lock )
172
173
{
174
+ pthread_lock * thelock = (pthread_lock * )lock ;
175
+ int status , error = 0 ;
176
+
173
177
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 );
181
186
}
182
187
183
188
int acquire_lock _P2 (lock , type_lock lock , waitflag , int waitflag )
184
189
{
185
190
int success ;
191
+ pthread_lock * thelock = (pthread_lock * )lock ;
192
+ int status , error = 0 ;
186
193
187
194
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" );
213
214
}
215
+ thelock -> locked = 1 ;
216
+ status = pthread_mutex_unlock ( & thelock -> mut );
217
+ CHECK_STATUS ("pthread_mutex_unlock[2]" );
218
+ success = 1 ;
214
219
}
220
+ if (error ) success = 0 ;
215
221
dprintf (("acquire_lock(%lx, %d) -> %d\n" , (long )lock , waitflag , success ));
216
222
return success ;
217
223
}
218
224
219
225
void release_lock _P1 (lock , type_lock lock )
220
226
{
227
+ pthread_lock * thelock = (pthread_lock * )lock ;
228
+ int status , error = 0 ;
229
+
221
230
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" );
242
243
}
243
244
244
245
/*
245
246
* Semaphore support.
246
247
*/
248
+ /* NOTE: 100% non-functional at this time - tim */
249
+
247
250
type_sema allocate_sema _P1 (value , int value )
248
251
{
249
252
char * sema = 0 ;
0 commit comments