diff -Nur libpthread.org/Makefile libpthread/Makefile --- libpthread.org/Makefile 2002-11-19 17:14:53.000000000 +0100 +++ libpthread/Makefile 2002-11-19 17:39:32.000000000 +0100 @@ -120,6 +120,8 @@ \ pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \ \ + semaphore.c \ + \ cthreads-compat.c \ $(SYSDEPS) @@ -132,6 +134,7 @@ sysdeps_headers = \ pthread.h \ pthread/pthread.h \ + semaphore.h \ \ bits/pthread.h \ bits/mutex.h \ @@ -146,7 +149,8 @@ bits/once.h \ bits/mutex-attr.h \ bits/rwlock.h \ - bits/rwlock-attr.h + bits/rwlock-attr.h \ + bits/semaphore.h SYSDEP_PATH = $(srcdir)/sysdeps/$(MICROKERNEL)/hurd/i386 \ $(srcdir)/sysdeps/$(MICROKERNEL)/i386 \ diff -Nur 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-19 17:33:37.000000000 +0100 @@ -0,0 +1,62 @@ +/* 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 + +#define SEM_FAILED __SEM_FAILED + +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); + +/* Close a named semaphore. */ +extern int sem_close(sem_t *sem); + +/* Open a named semaphore. */ +extern sem_t *sem_open(const char *name, int oflag, ...); + +__END_DECLS + +#endif /* semaphore.h */ diff -Nur libpthread.org/sysdeps/generic/bits/semaphore.h libpthread/sysdeps/generic/bits/semaphore.h --- libpthread.org/sysdeps/generic/bits/semaphore.h 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/bits/semaphore.h 2002-11-19 17:37:07.000000000 +0100 @@ -0,0 +1,65 @@ +/* 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 + +#define __SEM_ID_NONE 0 +#define __SEM_ID_LOCAL 0xFAAF /* Anything non-zero is good enough. */ + +struct __local_sem_t +{ + unsigned int count; + pthread_mutex_t count_lock; + pthread_cond_t count_cond; +}; + +struct __shared_sem_t +{ + /* Not used yet. */ +}; + +struct __named_sem_t +{ + /* Not used yet. */ +}; + +struct __sem_t +{ + int id; + union { + struct __local_sem_t local; + struct __shared_sem_t shared; + struct __named_sem_t named; + } __data; +}; + +#endif /* bits/semaphore.h */ + diff -Nur libpthread.org/sysdeps/generic/sem_destroy.c libpthread/sysdeps/generic/sem_destroy.c --- libpthread.org/sysdeps/generic/sem_destroy.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_destroy.c 2002-11-19 17:36:45.000000000 +0100 @@ -0,0 +1,42 @@ +/* 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 + + +/* Destroys the semaphore. */ +int +sem_destroy (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->__data.local.count_lock); + sem->id = __SEM_ID_NONE; + pthread_cond_broadcast (&sem->__data.local.count_cond); + if (pthread_cond_destroy (&sem->__data.local.count_cond)) + res = -1; + pthread_mutex_unlock(&sem->__data.local.count_lock); + if (pthread_mutex_destroy (&sem->__data.local.count_lock)) + res = -1; + return res; +} diff -Nur libpthread.org/sysdeps/generic/sem_getvalue.c libpthread/sysdeps/generic/sem_getvalue.c --- libpthread.org/sysdeps/generic/sem_getvalue.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_getvalue.c 2002-11-19 17:36:45.000000000 +0100 @@ -0,0 +1,42 @@ +/* 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 + +/* Return the value of the semaphore */ +int +sem_getvalue (sem_t *sem, int *sval) +{ + int res = 0; + pthread_mutex_lock (&sem->__data.local.count_lock); + if (sem->id != __SEM_ID_LOCAL) + { + res = -1; + errno = EINVAL; + } + else + *sval = sem->__data.local.count; + pthread_mutex_unlock (&sem->__data.local.count_lock); + return res; +} diff -Nur libpthread.org/sysdeps/generic/sem_init.c libpthread/sysdeps/generic/sem_init.c --- libpthread.org/sysdeps/generic/sem_init.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_init.c 2002-11-19 17:36:46.000000000 +0100 @@ -0,0 +1,53 @@ +/* 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 + +/* 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) +{ + if (pshared) { + errno = ENOTSUP; + return -1; + } + + sem->id = __SEM_ID_NONE; + + if (pthread_cond_init (&sem->__data.local.count_cond, NULL)) + goto cond_init_fail; + + if (pthread_mutex_init (&sem->__data.local.count_lock, NULL)) + goto mutex_init_fail; + + sem->__data.local.count = value; + return 0; + +mutex_init_fail: + pthread_cond_destroy (&sem->__data.local.count_cond); +cond_init_fail: + return -1; + +} diff -Nur libpthread.org/sysdeps/generic/sem_post.c libpthread/sysdeps/generic/sem_post.c --- libpthread.org/sysdeps/generic/sem_post.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_post.c 2002-11-19 17:36:46.000000000 +0100 @@ -0,0 +1,52 @@ +/* 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 + +/* Increments the count */ +int +sem_post (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->__data.local.count_lock); + if (sem->id != __SEM_ID_LOCAL) + { + res = -1; + errno = EINVAL; + } + else + if (sem->__data.local.count < __SEM_VALUE_MAX) + { + sem->__data.local.count++; + if (sem->__data.local.count == 1) + pthread_cond_signal (&sem->__data.local.count_cond); + } + else + { + errno = ERANGE; + res = -1; + } + pthread_mutex_unlock (&sem->__data.local.count_lock); + return res; +} diff -Nur libpthread.org/sysdeps/generic/sem_stubs.c libpthread/sysdeps/generic/sem_stubs.c --- libpthread.org/sysdeps/generic/sem_stubs.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_stubs.c 2002-11-19 17:36:46.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 + */ + +#include +#include + + +/* Stub functions - unimplemented functionality. */ + +/* Open a named semaphore. */ +sem_t * +sem_open (const char * foo, int bar, ...) +{ + errno = ENOSYS; + return __SEM_FAILED; +} + +/* Close a named semaphore. */ +int +sem_close (sem_t * foo) +{ + errno = ENOSYS; + return -1; +} diff -Nur libpthread.org/sysdeps/generic/sem_trywait.c libpthread/sysdeps/generic/sem_trywait.c --- libpthread.org/sysdeps/generic/sem_trywait.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_trywait.c 2002-11-19 17:36:46.000000000 +0100 @@ -0,0 +1,51 @@ +/* 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 + + +/* Non-blocking variant of sem_wait. Returns -1 if count == 0. */ +int +sem_trywait (sem_t *sem) +{ + int res = 0; + pthread_mutex_lock (&sem->__data.local.count_lock); + if (sem->id != __SEM_ID_LOCAL) + { + res = -1; + errno = EINVAL; + } + else + if (sem->__data.local.count) + { + sem->__data.local.count--; + } + else + { + res = -1; + errno = EAGAIN; + } + pthread_mutex_unlock (&sem->__data.local.count_lock); + return res; +} diff -Nur libpthread.org/sysdeps/generic/sem_wait.c libpthread/sysdeps/generic/sem_wait.c --- libpthread.org/sysdeps/generic/sem_wait.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/sysdeps/generic/sem_wait.c 2002-11-19 17:36:46.000000000 +0100 @@ -0,0 +1,54 @@ +/* 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 + + +/* Wait until the count is > 0, and then decrease it. */ +int +sem_wait (sem_t *sem) +{ + int res = 0; + pthread_cleanup_push (&pthread_mutex_unlock, &sem->__data.local.count_lock); + pthread_mutex_lock (&sem->__data.local.count_lock); + if (sem->id != __SEM_ID_LOCAL) + { + errno = EINVAL; + res = -1; + } + else + { + while (!sem->__data.local.count) + pthread_cond_wait (&sem->__data.local.count_cond, &sem->__data.local.count_lock); + if (sem->id != __SEM_ID_LOCAL) + { + res = -1; + errno = EINVAL; + } + else + sem->__data.local.count--; + } + pthread_cleanup_pop (1); + return res; +} diff -Nur libpthread.org/tests/Makefile libpthread/tests/Makefile --- libpthread.org/tests/Makefile 2002-11-19 17:15:35.000000000 +0100 +++ libpthread/tests/Makefile 2002-11-19 17:40:43.000000000 +0100 @@ -4,7 +4,7 @@ CHECK_SRC := test-1.c test-2.c test-3.c test-6.c test-7.c test-8.c \ test-9.c test-10.c test-11.c test-12.c test-13.c test-14.c \ - test-15.c test-16.c + test-15.c test-16.c test-1s.c CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC)))) CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \ @@ -26,4 +26,4 @@ clean: rm -f $(CHECK_OBJS) $(CHECK_PROGS) \ - $(addsuffix .out,$(basename $(notdir $(CHECK_PROGS)))) \ No newline at end of file + $(addsuffix .out,$(basename $(notdir $(CHECK_PROGS)))) diff -Nur libpthread.org/tests/test-1s.c libpthread/tests/test-1s.c --- libpthread.org/tests/test-1s.c 1970-01-01 01:00:00.000000000 +0100 +++ libpthread/tests/test-1s.c 2002-11-19 17:40:22.000000000 +0100 @@ -0,0 +1,75 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#define THREADS 500 + +typedef struct +{ + volatile int chk, no; + sem_t sem; +} thr_arg; + +void * +foo (void *arg) +{ + thr_arg *parg = arg; + sem_t *sem = &parg->sem; + volatile int *chk = &parg->chk; + int err; + *chk++; + if (*chk - 1) { + fprintf (stderr, "Thread %i value %i should be 1.\n", parg->no, parg->chk); + error (1, EGREGIOUS, "Value check (sub)"); + } + err = sem_post (sem); + if (err) + error (1, err, "sem_post"); + return arg; +} + +int +main (int argc, char **argv) +{ + int i; + error_t err; + pthread_t tid[THREADS]; + thr_arg arg[THREADS]; + + for (i = 0; i < THREADS; i ++) + { + sem_t *sem = &arg[i].sem; + arg[i].chk = 0; + arg[i].no = i + 1; + err = sem_init (sem, 0, 0); + if (err) + error (1, err, "sem_init"); + err = pthread_create (&tid[i], 0, foo, &arg[i]); + if (err) + error (1, err, "pthread_create"); + sem_wait (sem); + arg[i].chk--; + if (arg[i].chk) + { + fprintf (stderr, + "Thread %i value %i should be 0.\n" , arg[i].no, arg[i].chk); + error (1, EGREGIOUS, "Value check (main)"); + } + + } + + for (i = THREADS - 1; i >= 0; i --) + { + void * ret; + err = pthread_join (tid[i], &ret); + if (err) + error (1, err, "pthread_join"); + } + + return 0; +}