This time I made a simple test that tries post and wait.
I can synchronize two threads without a segfault.
--
Michal Suchanek
[EMAIL PROTECTED]
diff -Nurx CVS libpthread.org/Makefile libpthread/Makefile
--- libpthread.org/Makefile 2002-11-26 19:04:34.000000000 +0100
+++ libpthread/Makefile 2002-11-26 18:46:30.000000000 +0100
@@ -120,6 +120,9 @@
\
pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \
\
+ sem_init.c sem_destroy.c sem_wait.c sem_post.c sem_trywait.c \
+ sem_getvalue.c sem_stubs.c \
+ \
cthreads-compat.c \
$(SYSDEPS)
@@ -132,6 +135,7 @@
sysdeps_headers = \
pthread.h \
pthread/pthread.h \
+ semaphore.h \
\
bits/pthread.h \
bits/mutex.h \
@@ -146,7 +150,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 -Nurx 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-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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.h>
+ */
+
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H 1
+
+#include <bits/semaphore.h>
+
+#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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.h>
+ */
+
+#ifndef _BITS_SEMAPHORE_H
+#define _BITS_SEMAPHORE_H 1
+
+#include <pthread.h>
+#include <limits.h>
+
+#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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+
+/* 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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+/* 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 -Nurx CVS 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-26 18:58:42.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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+/* 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;
+ sem->id = __SEM_ID_LOCAL;
+ return 0;
+
+mutex_init_fail:
+ pthread_cond_destroy (&sem->__data.local.count_cond);
+cond_init_fail:
+ return -1;
+
+}
diff -Nurx CVS 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-26 19:38:28.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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+/* 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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+
+/* 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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+
+/* 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 -Nurx CVS 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 <[EMAIL PROTECTED]>
+
+ 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 <semaphore.c>
+ */
+
+#include <semaphore.h>
+#include <errno.h>
+
+
+/* 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 -Nurx CVS libpthread.org/tests/Makefile libpthread/tests/Makefile
--- libpthread.org/tests/Makefile 2002-11-26 19:37:32.000000000 +0100
+++ libpthread/tests/Makefile 2002-11-26 18:25:42.000000000 +0100
@@ -4,7 +4,7 @@
CHECK_SRC := test-0.c 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-14.c test-15.c test-16.c test-1s.c
CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC))))
CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \
Binary files libpthread.org/tests/core and libpthread/tests/core differ
diff -Nurx CVS 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-26 19:14:03.000000000 +0100
@@ -0,0 +1,75 @@
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <unistd.h>
+#include <error.h>
+#include <errno.h>
+
+#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 (parg->chk - 1)
+ error (0, ERANGE, "Thread %i: value %i should be 1",
+ parg->no, parg->chk);
+ err = sem_post (sem);
+ if (err)
+ error (0, errno, "sem_post");
+ return (void *)err;
+}
+
+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 (0, errno, "sem_init");
+ err = pthread_create (&tid[i], 0, foo, &arg[i]);
+ if (err)
+ error (0, errno, "pthread_create");
+ err = sem_wait (sem);
+ if (err)
+ error (0, errno, "sem_wait");
+ arg[i].chk--;
+ if (arg[i].chk)
+ error (0, EGREGIOUS, "Main: Thread %i: value %i should be 0.",
+ arg[i].no, arg[i].chk);
+
+ }
+
+ for (i = THREADS - 1; i >= 0; i --)
+ {
+ void * ret;
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (0, errno, "pthread_join");
+ if ((int)ret)
+ error (0, EGREGIOUS, "Main: Thread %i: return value %i should be 0",
+ arg[i].no, (int)ret);
+ }
+
+ return 0;
+}