diff -Nur -x CVS libpthread.org/Makefile libpthread/Makefile --- libpthread.org/Makefile 2002-10-11 01:05:06.000000000 +0200 +++ libpthread/Makefile 2002-11-07 13:04:22.000000000 +0100 @@ -120,6 +120,8 @@ \ pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \ \ + semaphore.c \ + \ cthreads-compat.c \ $(SYSDEPS) @@ -131,7 +133,9 @@ sysdeps_headers = \ pthread.h \ + semaphore.h \ pthread/pthread.h \ + bits/semaphore.h \ \ bits/pthread.h \ bits/mutex.h \ diff -Nur -x CVS libpthread.org/include/bits/semaphore.h libpthread/include/bits/semaphore.h --- libpthread.org/include/bits/semaphore.h 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/include/bits/semaphore.h 2002-11-07 14:02:01.000000000 +0100 @@ -0,0 +1,44 @@ +/* Copyright (C) 2000,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ga?l Le Mignot + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * POSIX Threads Extension: Semaphores + */ + +#ifndef _BITS_SEMAPHORE_H +#define _BITS_SEMAPHORE_H 1 + +#include +#include + +#define SEM_FAILED NULL + +#define SEM_VALUE_MAX (UINT_MAX - 1) +#define SEM_VALUE_INVALID UINT_MAX + +struct __sem_t +{ + unsigned int count; + pthread_mutex_t count_lock; + pthread_cond_t count_cond; + char * ID; /* may be used in future to store semaphore name */ +}; + +#endif /* bits/semaphore.h */ + diff -Nur -x CVS libpthread.org/include/semaphore.h libpthread/include/semaphore.h --- libpthread.org/include/semaphore.h 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/include/semaphore.h 2002-11-07 14:04:11.000000000 +0100 @@ -0,0 +1,59 @@ +/* Copyright (C) 2000,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ga?l Le Mignot + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * POSIX Threads Extension: Semaphores + */ + +#ifndef _SEMAPHORE_H +#define _SEMAPHORE_H 1 + +#include + + +typedef struct __sem_t sem_t; + +__BEGIN_DECLS + +/* Initialize the semaphore and set the initial value - as in LinuxThreads + pshared must be zero right now. */ +extern int sem_init (sem_t *sem, int pshared, unsigned int value); + +/* Destroys the semaphore */ +extern int sem_destroy (sem_t *sem); + +/* Wait until the count is > 0, and then decrease it */ +extern int sem_wait (sem_t *sem); + +/* Non-blocking variant of sem_wait. Returns -1 if count == 0. */ +extern int sem_trywait (sem_t *sem); + +/* Increments the count */ +extern int sem_post (sem_t *sem); + +/* Return the value of the semaphore */ +extern int sem_getvalue (sem_t *sem, int *sval); + +/* Operate named semaphores - not implemented yet */ +extern int sem_close(sem_t *); +extern sem_t *sem_open(const char *, int, ...); + +__END_DECLS + +#endif /* semaphore.h */ diff -Nur -x CVS libpthread.org/semaphore.c libpthread/semaphore.c --- libpthread.org/semaphore.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/semaphore.c 2002-11-07 14:05:38.000000000 +0100 @@ -0,0 +1,202 @@ +/* Copyright (C) 2000,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ga?l Le Mignot + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * POSIX Threads Extension: Semaphores + */ + +#include +#include +#include +#include + +static void pmut_unlock(void * pmutex) { + pthread_mutex_unlock((pthread_mutex_t *)pmutex); +} + +#define pmutex_safe_lock(pmut) \ +{ \ + int __pmutex_safe_lock_old_state; \ + pthread_mutex_t *__pmutext_safe_lock_pmut_test = pmut; \ + pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, \ + &__pmutex_safe_lock_old_state); \ + pthread_cleanup_push (&pmut_unlock, (pmut)); \ + pthread_mutex_lock (pmut) + +#define pmutex_safe_unlock(pmut) \ + pthread_cleanup_pop (1); \ + assert (__pmutext_safe_lock_pmut_test == pmut); \ + pthread_setcanceltype (__pmutex_safe_lock_old_state, NULL); \ +} + +/* Initialize the semaphore and set the initial value - as in LinuxThreads + pshared must be zero right now. */ +int +sem_init (sem_t *sem, int pshared, unsigned int value) +{ + int res = 0; + if (pshared) { + errno = ENOTSUP; + return -1; + } + if (value > SEM_VALUE_MAX) { + errno = ERANGE; + return -1; + } + + sem->count = SEM_VALUE_INVALID; + sem->ID = NULL; + if (pthread_cond_init (&sem->count_cond, NULL)) + res = -1; + else + { + if(pthread_mutex_init (&sem->count_lock, NULL)) + { + res = -1; + pthread_cond_destroy(&sem->count_cond); + } + else + sem->count = value; + } + return res; +} + + +/* Destroys the semaphore */ +int +sem_destroy (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->count_lock); + sem->count = SEM_VALUE_INVALID; + pthread_cond_broadcast (&sem->count_cond); + if (pthread_cond_destroy (&sem->count_cond)) + res = -1; + pthread_mutex_unlock(&sem->count_lock); + if (pthread_mutex_destroy (&sem->count_lock)) + res = -1; + return res; +} + +/* Wait until the count is > 0, and then decrease it */ +int +sem_wait (sem_t *sem) +{ + int res = 0; + pmutex_safe_lock (&sem->count_lock); + if (sem->count == SEM_VALUE_INVALID) + { + errno = EINVAL; + res = -1; + } + else + { + while (!sem->count) + pthread_cond_wait (&sem->count_cond, &sem->count_lock); + if (sem->count == SEM_VALUE_INVALID) + { + res = -1; + errno = EINVAL; + } + else + sem->count--; + } + pmutex_safe_unlock (&sem->count_lock); + return res; +} + +/* Non-blocking variant of sem_wait. Returns -1 if count == 0. */ +int +sem_trywait (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->count_lock); + if (sem->count == SEM_VALUE_INVALID) + { + res = -1; + errno = EINVAL; + } + else + if (sem->count) + { + sem->count--; + } + else + { + res = -1; + errno = EAGAIN; + } + pthread_mutex_unlock (&sem->count_lock); + return res; +} + +/* Increments the count */ +int +sem_post (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->count_lock); + if (sem->count == SEM_VALUE_INVALID) + { + res = -1; + errno = EINVAL; + } + else + if (sem->count < SEM_VALUE_MAX) + { + sem->count++; + pthread_cond_signal (&sem->count_cond); + } + else + { + errno = ERANGE; + res = -1; + } + pthread_mutex_unlock (&sem->count_lock); + return res; +} + +/* Return the value of the semaphore */ +int +sem_getvalue (sem_t *sem, int *sval) +{ + int res = 0; + pthread_mutex_lock (&sem->count_lock); + if (sem->count == SEM_VALUE_INVALID) + { + res = -1; + errno = EINVAL; + } + else + *sval = sem->count; + pthread_mutex_unlock (&sem->count_lock); + return res; +} + +sem_t *sem_open(const char * foo, int bar, ...) +{ + errno = ENOSYS; + return SEM_FAILED; +} + +int sem_close(sem_t * foo) +{ + errno = ENOSYS; + return -1; +}