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;
+}

Reply via email to