@@ -263,32 +263,93 @@ void release_lock _P1(lock, type_lock lock)
263263/*
264264 * Semaphore support.
265265 */
266- /* NOTE: 100% non-functional at this time - tim */
266+
267+ struct semaphore {
268+ pthread_mutex_t mutex ;
269+ pthread_cond_t cond ;
270+ int value ;
271+ };
267272
268273type_sema allocate_sema _P1 (value , int value )
269274{
270- char * sema = 0 ;
275+ struct semaphore * sema ;
276+ int status , error = 0 ;
277+
271278 dprintf (("allocate_sema called\n" ));
272279 if (!initialized )
273280 init_thread ();
274281
282+ sema = (struct semaphore * ) malloc (sizeof (struct semaphore ));
283+ if (sema != NULL ) {
284+ sema -> value = value ;
285+ status = pthread_mutex_init (& sema -> mutex ,
286+ pthread_mutexattr_default );
287+ CHECK_STATUS ("pthread_mutex_init" );
288+ status = pthread_cond_init (& sema -> cond ,
289+ pthread_condattr_default );
290+ CHECK_STATUS ("pthread_cond_init" );
291+ if (error ) {
292+ free ((void * ) sema );
293+ sema = NULL ;
294+ }
295+ }
275296 dprintf (("allocate_sema() -> %lx\n" , (long ) sema ));
276297 return (type_sema ) sema ;
277298}
278299
279300void free_sema _P1 (sema , type_sema sema )
280301{
302+ int status , error = 0 ;
303+ struct semaphore * thesema = (struct semaphore * ) sema ;
304+
281305 dprintf (("free_sema(%lx) called\n" , (long ) sema ));
306+ status = pthread_cond_destroy (& thesema -> cond );
307+ CHECK_STATUS ("pthread_cond_destroy" );
308+ status = pthread_mutex_destroy (& thesema -> mutex );
309+ CHECK_STATUS ("pthread_mutex_destroy" );
310+ free ((void * ) thesema );
282311}
283312
284313int down_sema _P2 (sema , type_sema sema , waitflag , int waitflag )
285314{
315+ int status , error = 0 , success ;
316+ struct semaphore * thesema = (struct semaphore * ) sema ;
317+
286318 dprintf (("down_sema(%lx, %d) called\n" , (long ) sema , waitflag ));
319+ status = pthread_mutex_lock (& thesema -> mutex );
320+ CHECK_STATUS ("pthread_mutex_lock" );
321+ if (waitflag ) {
322+ while (!error && thesema -> value <= 0 ) {
323+ status = pthread_cond_wait (& thesema -> cond ,
324+ & thesema -> mutex );
325+ CHECK_STATUS ("pthread_cond_wait" );
326+ }
327+ }
328+ if (error )
329+ success = 0 ;
330+ else if (thesema -> value > 0 ) {
331+ thesema -> value -- ;
332+ success = 1 ;
333+ }
334+ else
335+ success = 0 ;
336+ status = pthread_mutex_unlock (& thesema -> mutex );
337+ CHECK_STATUS ("pthread_mutex_unlock" );
287338 dprintf (("down_sema(%lx) return\n" , (long ) sema ));
288- return -1 ;
339+ return success ;
289340}
290341
291342void up_sema _P1 (sema , type_sema sema )
292343{
344+ int status , error = 0 ;
345+ struct semaphore * thesema = (struct semaphore * ) sema ;
346+
293347 dprintf (("up_sema(%lx)\n" , (long ) sema ));
348+ status = pthread_mutex_lock (& thesema -> mutex );
349+ CHECK_STATUS ("pthread_mutex_lock" );
350+ thesema -> value ++ ;
351+ status = pthread_cond_signal (& thesema -> cond );
352+ CHECK_STATUS ("pthread_cond_signal" );
353+ status = pthread_mutex_unlock (& thesema -> mutex );
354+ CHECK_STATUS ("pthread_mutex_unlock" );
294355}
0 commit comments