Skip to content
Browse files

- partly implement semaphores. the post- and wait- functions are stub…

…bed, the rest is implemented

- update Makefile.am/in for this
- improve pthread_set_num_processors_np a little, it has still the flaw that it can only reduce the nr of cpus
- improve debug test makefile
- skip hanging once4.exe (for now) and improve it a little
- adding test to debug test makefile not needed anymore
  • Loading branch information...
1 parent cf0124f commit a3debef826d7e48822b7f09af0ca1d697019ef15 thedutchsherpa committed Nov 6, 2010
Showing with 340 additions and 28 deletions.
  1. +1 −1 Makefile.am
  2. +57 −18 Makefile.in
  3. +41 −0 include/semaphore.h
  4. +68 −0 src/ref.c
  5. +6 −0 src/ref.h
  6. +140 −0 src/sem.c
  7. +16 −0 src/sem.h
  8. +1 −1 src/thread.c
  9. +4 −4 test/makefile
  10. +1 −2 tests/README.WINPTHREADS
  11. +1 −1 tests/SIZES.GC
  12. +3 −1 tests/once4.c
  13. +1 −0 tests/test.h
View
2 Makefile.am
@@ -5,7 +5,7 @@ lib_LIBRARIES = libpthread.a
libpthread_a_CPPFLAGS = -I$(srcdir)/include
libpthread_a_SOURCES = \
src/barrier.h src/cond.h src/misc.h src/mutex.h src/rwlock.h src/spinlock.h src/thread.h src/ref.h src/sem.h \
- src/barrier.c src/cond.c src/misc.c src/mutex.c src/rwlock.c src/spinlock.c src/thread.c src/ref.c src/semaphore.c src/sched.c
+ src/barrier.c src/cond.c src/misc.c src/mutex.c src/rwlock.c src/spinlock.c src/thread.c src/ref.c src/sem.c src/sched.c
include_HEADERS = include/pthread.h include/semaphore.h
View
75 Makefile.in
@@ -84,8 +84,9 @@ am_libpthread_a_OBJECTS = src/libpthread_a-barrier.$(OBJEXT) \
src/libpthread_a-mutex.$(OBJEXT) \
src/libpthread_a-rwlock.$(OBJEXT) \
src/libpthread_a-spinlock.$(OBJEXT) \
- src/libpthread_a-ref.$(OBJEXT) \
- src/libpthread_a-thread.$(OBJEXT)
+ src/libpthread_a-thread.$(OBJEXT) \
+ src/libpthread_a-ref.$(OBJEXT) src/libpthread_a-sem.$(OBJEXT) \
+ src/libpthread_a-sched.$(OBJEXT)
libpthread_a_OBJECTS = $(am_libpthread_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
@@ -209,16 +210,18 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
+AM_CFLAGS = -Wall
lib_LIBRARIES = libpthread.a
libpthread_a_CPPFLAGS = -I$(srcdir)/include
libpthread_a_SOURCES = \
- src/barrier.h src/cond.h src/misc.h src/mutex.h src/rwlock.h src/spinlock.h src/ref.h src/thread.h \
- src/barrier.c src/cond.c src/misc.c src/mutex.c src/rwlock.c src/spinlock.c src/ref.c src/thread.c
+ src/barrier.h src/cond.h src/misc.h src/mutex.h src/rwlock.h src/spinlock.h src/thread.h src/ref.h src/sem.h \
+ src/barrier.c src/cond.c src/misc.c src/mutex.c src/rwlock.c src/spinlock.c src/thread.c src/ref.c src/sem.c src/sched.c
-include_HEADERS = include/pthread.h
+include_HEADERS = include/pthread.h include/semaphore.h
DISTCHECK_CONFIGURE_FLAGS = --host=$(host_triplet)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
+ cp libpthread.a libpthreadGC2.a
.SUFFIXES:
.SUFFIXES: .c .o .obj
@@ -323,9 +326,13 @@ src/libpthread_a-rwlock.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/libpthread_a-spinlock.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
+src/libpthread_a-thread.$(OBJEXT): src/$(am__dirstamp) \
+ src/$(DEPDIR)/$(am__dirstamp)
src/libpthread_a-ref.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
-src/libpthread_a-thread.$(OBJEXT): src/$(am__dirstamp) \
+src/libpthread_a-sem.$(OBJEXT): src/$(am__dirstamp) \
+ src/$(DEPDIR)/$(am__dirstamp)
+src/libpthread_a-sched.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
libpthread.a: $(libpthread_a_OBJECTS) $(libpthread_a_DEPENDENCIES)
-rm -f libpthread.a
@@ -338,9 +345,11 @@ mostlyclean-compile:
-rm -f src/libpthread_a-cond.$(OBJEXT)
-rm -f src/libpthread_a-misc.$(OBJEXT)
-rm -f src/libpthread_a-mutex.$(OBJEXT)
+ -rm -f src/libpthread_a-ref.$(OBJEXT)
-rm -f src/libpthread_a-rwlock.$(OBJEXT)
+ -rm -f src/libpthread_a-sched.$(OBJEXT)
+ -rm -f src/libpthread_a-sem.$(OBJEXT)
-rm -f src/libpthread_a-spinlock.$(OBJEXT)
- -rm -f src/libpthread_a-ref.$(OBJEXT)
-rm -f src/libpthread_a-thread.$(OBJEXT)
distclean-compile:
@@ -350,9 +359,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-cond.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-mutex.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-ref.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-rwlock.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-sched.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-sem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-spinlock.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-ref.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpthread_a-thread.Po@am__quote@
.c.o:
@@ -455,6 +466,20 @@ src/libpthread_a-spinlock.obj: src/spinlock.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-spinlock.obj `if test -f 'src/spinlock.c'; then $(CYGPATH_W) 'src/spinlock.c'; else $(CYGPATH_W) '$(srcdir)/src/spinlock.c'; fi`
+src/libpthread_a-thread.o: src/thread.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-thread.o -MD -MP -MF src/$(DEPDIR)/libpthread_a-thread.Tpo -c -o src/libpthread_a-thread.o `test -f 'src/thread.c' || echo '$(srcdir)/'`src/thread.c
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-thread.Tpo src/$(DEPDIR)/libpthread_a-thread.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/thread.c' object='src/libpthread_a-thread.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-thread.o `test -f 'src/thread.c' || echo '$(srcdir)/'`src/thread.c
+
+src/libpthread_a-thread.obj: src/thread.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-thread.obj -MD -MP -MF src/$(DEPDIR)/libpthread_a-thread.Tpo -c -o src/libpthread_a-thread.obj `if test -f 'src/thread.c'; then $(CYGPATH_W) 'src/thread.c'; else $(CYGPATH_W) '$(srcdir)/src/thread.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-thread.Tpo src/$(DEPDIR)/libpthread_a-thread.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/thread.c' object='src/libpthread_a-thread.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-thread.obj `if test -f 'src/thread.c'; then $(CYGPATH_W) 'src/thread.c'; else $(CYGPATH_W) '$(srcdir)/src/thread.c'; fi`
+
src/libpthread_a-ref.o: src/ref.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-ref.o -MD -MP -MF src/$(DEPDIR)/libpthread_a-ref.Tpo -c -o src/libpthread_a-ref.o `test -f 'src/ref.c' || echo '$(srcdir)/'`src/ref.c
@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-ref.Tpo src/$(DEPDIR)/libpthread_a-ref.Po
@@ -469,19 +494,33 @@ src/libpthread_a-ref.obj: src/ref.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-ref.obj `if test -f 'src/ref.c'; then $(CYGPATH_W) 'src/ref.c'; else $(CYGPATH_W) '$(srcdir)/src/ref.c'; fi`
-src/libpthread_a-thread.o: src/thread.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-thread.o -MD -MP -MF src/$(DEPDIR)/libpthread_a-thread.Tpo -c -o src/libpthread_a-thread.o `test -f 'src/thread.c' || echo '$(srcdir)/'`src/thread.c
-@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-thread.Tpo src/$(DEPDIR)/libpthread_a-thread.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/thread.c' object='src/libpthread_a-thread.o' libtool=no @AMDEPBACKSLASH@
+src/libpthread_a-sem.o: src/sem.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-sem.o -MD -MP -MF src/$(DEPDIR)/libpthread_a-sem.Tpo -c -o src/libpthread_a-sem.o `test -f 'src/sem.c' || echo '$(srcdir)/'`src/sem.c
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-sem.Tpo src/$(DEPDIR)/libpthread_a-sem.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/sem.c' object='src/libpthread_a-sem.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-thread.o `test -f 'src/thread.c' || echo '$(srcdir)/'`src/thread.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-sem.o `test -f 'src/sem.c' || echo '$(srcdir)/'`src/sem.c
-src/libpthread_a-thread.obj: src/thread.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-thread.obj -MD -MP -MF src/$(DEPDIR)/libpthread_a-thread.Tpo -c -o src/libpthread_a-thread.obj `if test -f 'src/thread.c'; then $(CYGPATH_W) 'src/thread.c'; else $(CYGPATH_W) '$(srcdir)/src/thread.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-thread.Tpo src/$(DEPDIR)/libpthread_a-thread.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/thread.c' object='src/libpthread_a-thread.obj' libtool=no @AMDEPBACKSLASH@
+src/libpthread_a-sem.obj: src/sem.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-sem.obj -MD -MP -MF src/$(DEPDIR)/libpthread_a-sem.Tpo -c -o src/libpthread_a-sem.obj `if test -f 'src/sem.c'; then $(CYGPATH_W) 'src/sem.c'; else $(CYGPATH_W) '$(srcdir)/src/sem.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-sem.Tpo src/$(DEPDIR)/libpthread_a-sem.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/sem.c' object='src/libpthread_a-sem.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-thread.obj `if test -f 'src/thread.c'; then $(CYGPATH_W) 'src/thread.c'; else $(CYGPATH_W) '$(srcdir)/src/thread.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-sem.obj `if test -f 'src/sem.c'; then $(CYGPATH_W) 'src/sem.c'; else $(CYGPATH_W) '$(srcdir)/src/sem.c'; fi`
+
+src/libpthread_a-sched.o: src/sched.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-sched.o -MD -MP -MF src/$(DEPDIR)/libpthread_a-sched.Tpo -c -o src/libpthread_a-sched.o `test -f 'src/sched.c' || echo '$(srcdir)/'`src/sched.c
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-sched.Tpo src/$(DEPDIR)/libpthread_a-sched.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/sched.c' object='src/libpthread_a-sched.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-sched.o `test -f 'src/sched.c' || echo '$(srcdir)/'`src/sched.c
+
+src/libpthread_a-sched.obj: src/sched.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libpthread_a-sched.obj -MD -MP -MF src/$(DEPDIR)/libpthread_a-sched.Tpo -c -o src/libpthread_a-sched.obj `if test -f 'src/sched.c'; then $(CYGPATH_W) 'src/sched.c'; else $(CYGPATH_W) '$(srcdir)/src/sched.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) src/$(DEPDIR)/libpthread_a-sched.Tpo src/$(DEPDIR)/libpthread_a-sched.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/sched.c' object='src/libpthread_a-sched.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpthread_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libpthread_a-sched.obj `if test -f 'src/sched.c'; then $(CYGPATH_W) 'src/sched.c'; else $(CYGPATH_W) '$(srcdir)/src/sched.c'; fi`
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
View
41 include/semaphore.h
@@ -0,0 +1,41 @@
+#ifndef WIN_SEMAPHORE
+#define WIN_SEMAPHORE
+
+/* Set this to 0 to disable it */
+#define USE_SEM_CriticalSection_SpinCount 100
+
+#define SEM_VALUE_MAX INT_MAX
+
+#ifndef _MODE_T_
+#define _MODE_T_
+typedef unsigned short mode_t;
+#endif
+
+typedef void *sem_t;
+
+#define SEM_FAILED NULL
+
+int sem_init(sem_t * sem, int pshared, unsigned int value);
+
+int sem_destroy(sem_t * sem);
+
+int sem_trywait(sem_t * sem);
+
+int sem_wait(sem_t * sem);
+
+int sem_timedwait(sem_t * sem, const struct timespec * abstime);
+
+int sem_post(sem_t * sem);
+
+int sem_post_multiple(sem_t * sem, int count);
+
+/* yes, it returns a semaphore (or SEM_FAILED) */
+sem_t *sem_open(const char * name, int oflag, mode_t mode, unsigned int value);
+
+int sem_close(sem_t * sem);
+
+int sem_unlink(const char * name);
+
+int sem_getvalue(sem_t * sem, int * sval);
+
+#endif /* WIN_SEMAPHORE */
View
68 src/ref.c
@@ -2,18 +2,21 @@
#include <winternl.h>
#include <stdio.h>
#include "pthread.h"
+#include "semaphore.h"
#include "spinlock.h"
#include "mutex.h"
#include "rwlock.h"
#include "cond.h"
#include "barrier.h"
+#include "sem.h"
#include "ref.h"
#include "misc.h"
static spin_t mutex_global = {0,LIFE_SPINLOCK,0};
static spin_t rwl_global = {0,LIFE_SPINLOCK,0};
static spin_t cond_global = {0,LIFE_SPINLOCK,0};
static spin_t barrier_global = {0,LIFE_SPINLOCK,0};
+static spin_t sem_global = {0,LIFE_SPINLOCK,0};
inline int mutex_unref(volatile pthread_mutex_t *m, int r)
{
@@ -370,3 +373,68 @@ inline int barrier_ref_init(volatile pthread_barrier_t *barrier )
return r;
}
+inline int sem_unref(volatile sem_t *sem, int res)
+{
+ _spin_lite_lock(&sem_global);
+#ifdef WINPTHREAD_DBG
+ assert((((_sem_t *)*sem)->valid == LIFE_SEM) && (((_sem_t *)*sem)->busy > 0));
+#endif
+ ((_sem_t *)*sem)->busy--;
+ _spin_lite_unlock(&sem_global);
+ return res;
+}
+
+inline int sem_ref(volatile sem_t *sem)
+{
+ int r = 0;
+ _spin_lite_lock(&sem_global);
+
+ if (!sem || !*sem || ((_sem_t *)*sem)->valid != LIFE_SEM) r = EINVAL;
+ else {
+ ((_sem_t *)*sem)->busy ++;
+ }
+
+ _spin_lite_unlock(&sem_global);
+
+ return r;
+}
+
+inline int
+sem_ref_destroy(volatile sem_t *sem, sem_t *sDestroy)
+{
+ int r = 0;
+
+ *sDestroy = NULL;
+ if (_spin_lite_trylock(&sem_global)) return EBUSY;
+
+ if (!sem || !*sem || ((_sem_t *)*sem)->valid != LIFE_SEM) r = EINVAL;
+ else {
+ _sem_t *s = (_sem_t *)*sem;
+ if (s->valid != LIFE_SEM) r = EINVAL;
+ else if (s->busy) r = EBUSY;
+ else {
+ *sDestroy = *sem;
+ *sem = NULL;
+ }
+ }
+
+ _spin_lite_unlock(&sem_global);
+ return r;
+}
+
+inline int sem_ref_init(volatile sem_t *sem )
+{
+ int r = 0;
+
+ _spin_lite_lock(&sem_global);
+
+ if (!sem) r = EINVAL;
+ else if (*sem) {
+ _sem_t *s = (_sem_t *)*sem;
+ if (s->valid == LIFE_SEM) r = EBUSY;
+ }
+
+ _spin_lite_unlock(&sem_global);
+ return r;
+}
+
View
6 src/ref.h
@@ -1,5 +1,7 @@
#ifndef WIN_PTHREADS_REF_H
#define WIN_PTHREADS_REF_H
+#include "pthread.h"
+#include "semaphore.h"
inline int mutex_unref(volatile pthread_mutex_t *m, int r);
@@ -30,5 +32,9 @@ inline int barrier_ref(volatile pthread_barrier_t *barrier);
inline int barrier_ref_destroy(volatile pthread_barrier_t *barrier, pthread_barrier_t *bDestroy );
inline int barrier_ref_init(volatile pthread_barrier_t *barrier );
+inline int sem_unref(volatile sem_t *sem, int res);
+inline int sem_ref(volatile sem_t *sem);
+inline int sem_ref_destroy(volatile sem_t *sem, sem_t *sDestroy);
+inline int sem_ref_init(volatile sem_t *sem );
#endif
View
140 src/sem.c
@@ -0,0 +1,140 @@
+#include <windows.h>
+#include <stdio.h>
+#include "pthread.h"
+#include "misc.h"
+#include "semaphore.h"
+#include "sem.h"
+#include "mutex.h"
+#include "ref.h"
+
+int sem_init(sem_t *sem, int pshared, unsigned int value)
+{
+ _sem_t *s;
+ mode_t r;
+
+ if (value > (unsigned int)SEM_VALUE_MAX) {
+ return EINVAL;
+ }
+ if (pshared == PTHREAD_PROCESS_SHARED) {
+ return EPERM;
+ }
+
+ r = sem_ref_init(sem);
+ if (r != 0)
+ return r;
+
+ if (!(s = (sem_t)calloc(1,sizeof(*s))))
+ return ENOMEM;
+
+ if ((s->s = CreateSemaphore (NULL, 0, SEM_VALUE_MAX, NULL)) == NULL) {
+ s->valid = DEAD_SEM;
+ free(s);
+ return ENOSPC;
+ }
+
+ s->value = value;
+ s->valid = LIFE_SEM;
+ *sem = s;
+
+ return 0;
+}
+
+int sem_destroy(sem_t *sem)
+{
+ sem_t sDestroy;
+ int r = sem_ref_destroy(sem,&sDestroy);
+
+ if (r)
+ return r;
+
+ _sem_t *s = (_sem_t *)sDestroy;
+
+ CloseHandle(s->s); /* no way back if this fails */
+ s->valid = DEAD_SEM;
+ free(sDestroy);
+ return r;
+
+}
+
+int sem_trywait(sem_t *sem)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ (void)s;
+
+ return sem_unref(sem,r);
+}
+
+int sem_wait(sem_t *sem)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ (void)s;
+
+ return sem_unref(sem,r);
+}
+
+int sem_timedwait(sem_t *sem, const struct timespec *abstime)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ (void)s;
+
+ return sem_unref(sem,r);
+}
+
+int sem_post(sem_t * sem)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ (void)s;
+
+ return sem_unref(sem,r);
+}
+
+int sem_post_multiple(sem_t *sem, int count)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ (void)s;
+
+ return sem_unref(sem,r);
+}
+
+sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
+{
+ errno = ENOSYS;
+ return SEM_FAILED;
+}
+
+int sem_close(sem_t *sem)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int sem_unlink(const char *name)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int sem_getvalue(sem_t *sem, int *sval)
+{
+ int r = sem_ref(sem);
+ if(r) return r;
+
+ _sem_t *s = (_sem_t *)*sem;
+ *sval = s->value;
+ return sem_unref(sem,r);
+}
View
16 src/sem.h
@@ -0,0 +1,16 @@
+#ifndef WIN_SEM
+#define WIN_SEM
+
+#define LIFE_SEM 0xBAB1F00D
+#define DEAD_SEM 0xDEADBEEF
+
+typedef struct _sem_t _sem_t;
+struct _sem_t
+{
+ unsigned int valid;
+ volatile LONG busy;
+ HANDLE s;
+ unsigned int value;
+};
+
+#endif /* WIN_SEM */
View
2 src/thread.c
@@ -121,7 +121,7 @@ int pthread_set_num_processors_np(int n)
}
SetProcessAffinityMask(GetCurrentProcess(),ProcessNewAffinityMask);
}
- return r ? r : 1;
+ return r;
}
int pthread_once(pthread_once_t *o, void (*func)(void))
View
8 test/makefile
@@ -4,11 +4,11 @@ test.o: test.c
test.exe: test.o
gcc -static -m64 -o test.exe test.o -L.. -lpthread
-mutex4.o: mutex4.c
- gcc -c -m64 -I ../include -I ../src mutex4.c
+%.o: %.c
+ gcc -c -m64 -I ../include -I ../src $<
-mutex4.exe: mutex4.o
- gcc -static -m64 -o mutex4.exe mutex4.o -L.. -lpthread
+%.exe: %.o
+ gcc -static -m64 -o $@ $< -L.. -lpthread
test: test.exe
View
3 tests/README.WINPTHREADS
@@ -48,8 +48,7 @@ Sometimes you want to test, debug and modify a single test, say once2.c:
$ cp once2.c ../test
3. Enter the debug test dir:
$ cd ../test
-4. Add once2.c to the makefile
-5. Build and run it:
+4. Build and run it:
$ make once2.exe
$ ./once2.exe
View
2 tests/SIZES.GC
@@ -2,7 +2,7 @@ Sizes of winpthreads structs
-------------------------------
pthread_t 8
pthread_attr_t_ 32
- pthread_mutex_t_ 72
+ pthread_mutex_t_ 56
pthread_mutexattr_t_ 4
pthread_spinlock_t_ 12
pthread_barrier_t_ 32
View
4 tests/once4.c
@@ -140,6 +140,8 @@ main()
pthread_t t[NUM_THREADS][NUM_ONCE];
int i, j, cpus;
+ fprintf(stderr, "Skipped (hangs)\n");
+ return 1;
InitializeCriticalSection(&print_lock);
InitializeCriticalSection(&numThreads.cs);
InitializeCriticalSection(&numOnce.cs);
@@ -154,7 +156,7 @@ main()
* Windows random priority boosting will obscure any problems.
*/
cpus = pthread_num_processors_np();
- printf("CPU count: %d\n", cpus);
+ fprintf(stderr,"CPU count: %d\n", cpus);
if (cpus <= 1) {
fprintf(stderr, "This test uses realtime scheduling and requires a multi-core to prevent system hang.\n");
exit(1);
View
1 tests/test.h
@@ -43,6 +43,7 @@
#include <time.h>
#include "../include/pthread.h"
+#include "../include/semaphore.h"
#include "../src/misc.h"
#include "../src/mutex.h"
#include "../src/cond.h"

0 comments on commit a3debef

Please sign in to comment.
Something went wrong with that request. Please try again.