diff options
| author | rpj <rpj> | 2005-03-08 07:36:56 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2005-03-08 07:36:56 +0000 | 
| commit | d5c78e3656cbc7410f333bfa80e2929947e6d0e5 (patch) | |
| tree | 9d47c7f9dc5022564a7c34ec1db8cca4e4d6d802 | |
| parent | 6df0e45cf47b5eaee00f21a5862e8f0c5107a4e2 (diff) | |
compiler compatibility and bug fixes
| -rw-r--r-- | ANNOUNCE | 9 | ||||
| -rw-r--r-- | ChangeLog | 12 | ||||
| -rw-r--r-- | NEWS | 20 | ||||
| -rw-r--r-- | global.c | 11 | ||||
| -rw-r--r-- | implement.h | 7 | ||||
| -rw-r--r-- | pthread.h | 9 | ||||
| -rw-r--r-- | pthread_once.c | 65 | ||||
| -rw-r--r-- | ptw32_processTerminate.c | 4 | ||||
| -rw-r--r-- | tests/Bmakefile | 3 | ||||
| -rw-r--r-- | tests/ChangeLog | 4 | ||||
| -rw-r--r-- | tests/GNUmakefile | 665 | ||||
| -rw-r--r-- | tests/Makefile | 3 | ||||
| -rw-r--r-- | tests/Wmakefile | 3 | ||||
| -rw-r--r-- | tests/exit2.c | 2 | ||||
| -rw-r--r-- | tests/exit3.c | 2 | ||||
| -rw-r--r-- | tests/eyal1.c | 4 | ||||
| -rw-r--r-- | tests/mutex5.c | 24 | 
17 files changed, 462 insertions, 385 deletions
| @@ -1,13 +1,14 @@ -		 PTHREADS-WIN32 SNAPSHOT 2005-01-25
 +		 PTHREADS-WIN32 SNAPSHOT 2005-03-08
  		 ----------------------------------
  	 Web Site: http://sources.redhat.com/pthreads-win32/
  	FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
  	 Maintainer: Ross Johnson <rpj@callisto.canberra.edu.au>
 -[Please note: snapshots from 2004-11-03 are using a new mutex implementation -and should be regarded as beta code. You may not want to use it in production -yet but please try it if you can.] +[Please note: snapshots from 2004-11-03 are using a new mutex implementation
 +and should be regarded as beta code. You may not want to use it in production
 +yet but please try it if you can. No mutex related problems have been reported +since snapshot 2005-01-25.]
  We are pleased to announce the availability of a new snapshot of
  Pthreads-win32, an Open Source Software implementation of the
 @@ -1,9 +1,19 @@ +2005-03-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
 + +	* pthread_once.c (pthread_once): Redesigned to elliminate potential +	starvation problem. +	- reported by Gottlob Frege  <gottlobfrege at gmail.com> + +	* ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were +	not closing their Win32 thread duplicate handle. +	- reported by Dmitrii Semii <bogolt at gmail.com> +  2005-01-25  Ralf Kubis  <RKubis at mc.com>
  	* Attempted acquisition of recursive mutex was causing waiting
  	threads to not be woken when the mutex is released.
 -	* GNUmakefile (GCE): Generate correct version resource comments. +	* GNUmakefile (GCE): Generate correct version resource comments.
  2005-01-01  Konstantin Voronkov  <beowinkle at yahoo.com>
 @@ -1,3 +1,21 @@ +SNAPSHOT 2005-03-08
 +-------------------
 +
 +Bug reports (fixed)
 +-------------------
 + +* Implicitly created threads leave Win32 handles behind after exiting. +- Dmitrii Semii + +* pthread_once() starvation problem. +- Gottlob Frege + +New tests +--------- + +* More intense testing of pthread_once(). + +
  SNAPSHOT 2005-01-25
  -------------------
 @@ -8,7 +26,7 @@ Bug fixes  to not be woken when the mutex was released.
  - Ralf Kubis  <RKubis at mc.com>
 -* Various package omissions have been fixed. +* Various package omissions have been fixed.
  SNAPSHOT 2005-01-03
 @@ -107,6 +107,17 @@ CRITICAL_SECTION ptw32_spinlock_test_init_lock;   */  CRITICAL_SECTION ptw32_cond_list_lock; +/* + * Global condition variable and mutex for once_control management. + * The mutex must be an ERRORCHECK type because we need to + * guarantee ownership when unlocking. + */ +ptw32_once_control_t ptw32_once_control = +  { +    PTHREAD_COND_INITIALIZER, +    PTHREAD_ERRORCHECK_MUTEX_INITIALIZER +  }; +  #ifdef _UWIN  /*   * Keep a count of the number of threads. diff --git a/implement.h b/implement.h index b456ebf..5ba9260 100644 --- a/implement.h +++ b/implement.h @@ -319,6 +319,12 @@ struct pthread_rwlockattr_t_  }; +typedef struct { +  pthread_cond_t cond; +  pthread_mutex_t mtx; +} ptw32_once_control_t; + +  struct ThreadKeyAssoc  {    /* @@ -472,6 +478,7 @@ extern CRITICAL_SECTION ptw32_cond_list_lock;  extern CRITICAL_SECTION ptw32_cond_test_init_lock;  extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;  extern CRITICAL_SECTION ptw32_spinlock_test_init_lock; +extern ptw32_once_control_t ptw32_once_control;  #ifdef _UWIN  extern int pthread_count; @@ -37,8 +37,8 @@   * See the README file for an explanation of the pthreads-win32 version   * numbering scheme and how the DLL is named etc.   */ -#define PTW32_VERSION 1,2,0,0 -#define PTW32_VERSION_STRING "1, 2, 0, 0\0" +#define PTW32_VERSION 1,3,0,0 +#define PTW32_VERSION_STRING "1, 3, 0, 0\0"  /* There are three implementations of cancel cleanup.   * Note that pthread.h is included in both application @@ -677,9 +677,8 @@ enum {  struct pthread_once_t_  { -  volatile int done;        /* indicates if user function executed  */ -  long started;             /* First thread to increment this value */ -                            /* to zero executes the user function   */ +  volatile int done;        /* indicates if user function has been executed  */ +  int          started;  }; diff --git a/pthread_once.c b/pthread_once.c index 9a94f74..d20a04d 100644 --- a/pthread_once.c +++ b/pthread_once.c @@ -87,41 +87,62 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void))      }    /* -   * The race condition involving once_control->done is harmless. -   * The problem experienced in MPU environments with multibyte variables -   * is also not a problem because the value (initially zero i.e. PTW32_FALSE) -   * is only ever tested for non-zero. In the event of a race occuring, the -   * worst result is that up to N-1 threads (N = number of CPUs) may enter the -   * while loop and yield their run state unnecessarily, and this can only -   * ever occur at most once. +   * Use a single global cond+mutex to manage access to all once_control objects. +   * Unlike a global mutex on it's own, the global cond+mutex allows faster +   * once_controls to overtake slower ones. Spurious wakeups may occur, but +   * can be tolerated.     * -   * The alternatives are to use a condition variable (overkill?), or -   * InterlockedCompareExchange() to test/set once_control->done. +   * To maintain a separate mutex for each once_control object requires either +   * cleaning up the mutex (difficult to synchronise reliably), or leaving it +   * around forever. Since we can't make assumptions about how an application might +   * employ pthread_once objects, the later is considered to be unacceptable. +   * +   * Since this is being introduced as a bug fix, the global cond+mtx also avoids +   * a change in the ABI, maintaining backwards compatibility. +   * +   * The mutex should be an ERRORCHECK type to be sure we will never, in the event +   * we're cancelled before we get the lock, unlock the mutex when it's held by +   * another thread (possible with NORMAL/DEFAULT mutexes because they don't check +   * ownership).     */ +    if (!once_control->done)      { -      if (InterlockedIncrement (&(once_control->started)) == 0) +      if (InterlockedExchange((LPLONG) &once_control->started, (LONG) 0) == -1)  	{ +	  (*init_routine) (); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif  	  /* -	   * First thread to increment the started variable +	   * Holding the mutex during the broadcast prevents threads being left +	   * behind waiting.  	   */ -	  (*init_routine) (); +	  pthread_cleanup_push(pthread_mutex_unlock, (void *) &ptw32_once_control.mtx); +	  (void) pthread_mutex_lock(&ptw32_once_control.mtx);  	  once_control->done = PTW32_TRUE; - +	  (void) pthread_cond_broadcast(&ptw32_once_control.cond); +	  pthread_cleanup_pop(1); +#ifdef _MSC_VER +#pragma inline_depth() +#endif  	}        else  	{ -	  /* -	   * Block until other thread finishes executing the onceRoutine -	   */ -	  while (!(once_control->done)) +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +	  pthread_cleanup_push(pthread_mutex_unlock, (void *) &ptw32_once_control.mtx); +	  (void) pthread_mutex_lock(&ptw32_once_control.mtx); +	  while (!once_control->done)  	    { -	      /* -	       * The following gives up CPU cycles without pausing -	       * unnecessarily -	       */ -	      Sleep (0); +	      (void) pthread_cond_wait(&ptw32_once_control.cond, &ptw32_once_control.mtx);  	    } +	  pthread_cleanup_pop(1); +#ifdef _MSC_VER +#pragma inline_depth() +#endif  	}      } diff --git a/ptw32_processTerminate.c b/ptw32_processTerminate.c index 51293a9..bd1ee7a 100644 --- a/ptw32_processTerminate.c +++ b/ptw32_processTerminate.c @@ -99,8 +99,10 @@ ptw32_processTerminate (void)        LeaveCriticalSection (&ptw32_thread_reuse_lock);        /*  -       * Destroy the global locks. +       * Destroy the global locks and other objects.         */ +      (void) pthread_cond_destroy(&ptw32_once_control.cond); +      (void) pthread_mutex_destroy(&ptw32_once_control.mtx);        DeleteCriticalSection (&ptw32_spinlock_test_init_lock);        DeleteCriticalSection (&ptw32_rwlock_test_init_lock);        DeleteCriticalSection (&ptw32_cond_test_init_lock); diff --git a/tests/Bmakefile b/tests/Bmakefile index 94b5395..294eec1 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -91,7 +91,7 @@ PASSES=   loadfree.pass \  	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
  	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
  	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
 -	  count1.pass  once1.pass  tsd1.pass  \
 +	  count1.pass  once1.pass  once2.pass  tsd1.pass  \
  	  self2.pass  \
  	  cancel1.pass  cancel2.pass  \
  	  semaphore4.pass  semaphore4t.pass  \
 @@ -306,6 +306,7 @@ mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass
  mutex8r.pass: mutex7r.pass
  once1.pass: create1.pass
 +once2.pass: once1.pass
  priority1.pass: join1.pass
  priority2.pass: priority1.pass barrier3.pass
  reuse1.pass: create2.pass
 diff --git a/tests/ChangeLog b/tests/ChangeLog index 566a1a9..cea9444 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2005-03-08  Ross Johnson  <rpj@callisto.canberra.edu.au> + +        * once2.c: New test. +
  2004-11-19  Ross Johnson  <rpj@callisto.canberra.edu.au>
  	* Bmakefile: New makefile for Borland.
 diff --git a/tests/GNUmakefile b/tests/GNUmakefile index dda1283..6bf0546 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -1,332 +1,333 @@ -# Makefile for the pthreads test suite.
 -# If all of the .pass files can be created, the test suite has passed.
 -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#      following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This 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
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 - -DLL_VER	= 1
 - -CP	= cp -f
 -MV	= mv -f
 -RM	= rm -f
 -CAT	= cat
 -#CP	= copy
 -#MV	= rename
 -#RM	= erase
 -#CAT	= type
 -MKDIR	= mkdir
 -TOUCH	= echo Passed >
 -ECHO	= @echo
 -MAKE	= make
 - -#
 -# Mingw32
 -#
 -XXCFLAGS	= 
 -XXLIBS	= -lws2_32
 -#CFLAGS	= -O3 -UNDEBUG -Wall $(XXCFLAGS)
 -CFLAGS	= -g -UNDEBUG -Wall $(XXCFLAGS)
 -BUILD_DIR	= ..
 -INCLUDES	= -I.
 - - -TEST	= GC
 - -# Default lib version
 -GCX	= $(TEST)$(DLL_VER)
 - -# Files we need to run the tests
 -# - paths are relative to pthreads build dir.
 -HDR	= pthread.h semaphore.h sched.h
 -LIB	= libpthread$(GCX).a
 -DLL	= pthread$(GCX).dll
 -QAPC	= ../QueueUserAPCEx/User/quserex.dll
 - -COPYFILES	= $(HDR) $(LIB) $(DLL) $(QAPC)
 - -# If a test case returns a non-zero exit code to the shell, make will
 -# stop.
 - -TESTS	= sizes loadfree \
 -	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \
 -	  semaphore1 semaphore2 semaphore3 \
 -	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \
 -	  create1 create2 reuse1 reuse2 equal1 \
 -	  kill1 valid1 valid2 \
 -	  exit2 exit3 exit4 exit5 \
 -	  join0 join1 join2 join3 \
 -	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \
 -	  mutex4 mutex6 mutex6n mutex6e mutex6r \
 -	  mutex6s mutex6es mutex6rs \
 -	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \
 -	  count1 once1 tsd1 self2 \
 -	  cancel1 cancel2 \
 -	  semaphore4 semaphore4t \
 -	  delay1 delay2 eyal1 \
 -	  condvar3 condvar3_1 condvar3_2 condvar3_3 \
 -	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \
 -	  errno1 \
 -	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \
 -	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \
 -	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \
 -	  cancel7 cancel8 \
 -	  cleanup0 cleanup1 cleanup2 cleanup3 \
 -	  priority1 priority2 inherit1 \
 -	  spin1 spin2 spin3 spin4 \
 -	  barrier1 barrier2 barrier3 barrier4 barrier5 \
 -	  exception1 exception2 exception3 \
 -	  cancel9 create3
 - -BENCHTESTS = \
 -	benchtest1 benchtest2 benchtest3 benchtest4 benchtest5
 - -PASSES		= $(TESTS:%=%.pass)
 -BENCHRESULTS	= $(BENCHTESTS:%=%.bench)
 - -help:
 -	@ $(ECHO) "Run one of the following command lines:"
 -	@ $(ECHO) "make clean GC    (to test using GC dll with C (no EH) applications)"
 -	@ $(ECHO) "make clean GCX   (to test using GC dll with C++ (EH) applications)"
 -	@ $(ECHO) "make clean GCE   (to test using GCE dll with C++ (EH) applications)"
 -	@ $(ECHO) "make clean GC-bench	  (to benchtest using GNU C dll with C cleanup code)"
 -	@ $(ECHO) "make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)"
 - -all:
 -	@ $(MAKE) clean GC
 -	@ $(MAKE) clean GCX
 -	@ $(MAKE) clean GCE
 - -GC:
 -	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-pass
 - -GCE:
 -	$(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass
 - -GCX:
 -	$(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass
 - -GC-bench:
 -	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench
 - -GCE-bench:
 -	$(MAKE) TEST=GCE  CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench
 - -all-pass: $(PASSES)
 -	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 - -all-bench: $(BENCHRESULTS)
 -	@ $(ECHO) BENCH TESTS COMPLETED.
 - -benchtest1.bench:
 -benchtest2.bench:
 -benchtest3.bench:
 -benchtest4.bench:
 -benchtest5.bench:
 - -barrier1.pass:
 -barrier2.pass: barrier1.pass
 -barrier3.pass: barrier2.pass
 -barrier4.pass: barrier3.pass
 -barrier5.pass: barrier4.pass
 -cancel1.pass: create1.pass
 -cancel2.pass: cancel1.pass
 -cancel2_1.pass: cancel2.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cancel6a.pass: cancel3.pass
 -cancel6d.pass: cancel3.pass
 -cancel7.pass: kill1.pass
 -cancel8.pass: cancel7.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -condvar1.pass:
 -condvar1_1.pass: condvar1.pass
 -condvar1_2.pass: join2.pass
 -condvar2.pass: condvar1.pass
 -condvar2_1.pass: condvar2.pass join2.pass
 -condvar3.pass: create1.pass condvar2.pass
 -condvar3_1.pass: condvar3.pass join2.pass
 -condvar3_2.pass: condvar3_1.pass
 -condvar3_3.pass: condvar3_2.pass
 -condvar4.pass: create1.pass
 -condvar5.pass: condvar4.pass
 -condvar6.pass: condvar5.pass
 -condvar7.pass: condvar6.pass cleanup1.pass
 -condvar8.pass: condvar7.pass
 -condvar9.pass: condvar8.pass
 -context1.pass: cancel2.pass
 -count1.pass: join1.pass
 -create1.pass: mutex2.pass
 -create2.pass: create1.pass
 -create3.pass:
 -delay1.pass: cancel2.pass
 -delay2.pass: delay1.pass
 -equal1.pass: create1.pass
 -errno1.pass: mutex3.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 -exit1.pass:
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -exit4.pass:
 -exit5.pass: exit4.pass kill1.pass
 -eyal1.pass: tsd1.pass
 -inherit1.pass: join1.pass priority1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -join3.pass: join2.pass
 -kill1.pass:
 -loadfree.pass: pthread.dll
 -mutex1.pass: self1.pass
 -mutex1n.pass: mutex1.pass
 -mutex1e.pass: mutex1.pass
 -mutex1r.pass: mutex1.pass
 -mutex2.pass: mutex1.pass
 -mutex2r.pass: mutex2.pass
 -mutex2e.pass: mutex2.pass
 -mutex3.pass: create1.pass
 -mutex3r.pass: mutex3.pass
 -mutex3e.pass: mutex3.pass
 -mutex4.pass: mutex3.pass
 -mutex5.pass:
 -mutex6.pass: mutex4.pass
 -mutex6n.pass: mutex4.pass
 -mutex6e.pass: mutex4.pass
 -mutex6r.pass: mutex4.pass
 -mutex6s.pass: mutex6.pass
 -mutex6rs.pass: mutex6r.pass
 -mutex6es.pass: mutex6e.pass
 -mutex7.pass: mutex6.pass
 -mutex7n.pass: mutex6n.pass
 -mutex7e.pass: mutex6e.pass
 -mutex7r.pass: mutex6r.pass
 -mutex8.pass: mutex7.pass
 -mutex8n.pass: mutex7n.pass
 -mutex8e.pass: mutex7e.pass
 -mutex8r.pass: mutex7r.pass
 -once1.pass: create1.pass
 -priority1.pass: join1.pass
 -priority2.pass: priority1.pass barrier3.pass
 -reuse1.pass: create2.pass
 -reuse2.pass: reuse1.pass
 -rwlock1.pass: condvar6.pass
 -rwlock2.pass: rwlock1.pass
 -rwlock3.pass: rwlock2.pass
 -rwlock4.pass: rwlock3.pass
 -rwlock5.pass: rwlock4.pass
 -rwlock6.pass: rwlock5.pass
 -rwlock7.pass: rwlock6.pass
 -rwlock8.pass: rwlock7.pass
 -rwlock2_t.pass: rwlock2.pass
 -rwlock3_t.pass: rwlock2_t.pass
 -rwlock4_t.pass: rwlock3_t.pass
 -rwlock5_t.pass: rwlock4_t.pass
 -rwlock6_t.pass: rwlock5_t.pass
 -rwlock6_t2.pass: rwlock6_t.pass
 -self1.pass:
 -self2.pass: create1.pass
 -semaphore1.pass:
 -semaphore2.pass:
 -semaphore3.pass: semaphore2.pass
 -semaphore4.pass: semaphore3.pass cancel1.pass
 -semaphore4t.pass: semaphore4.pass
 -sizes.pass:
 -spin1.pass:
 -spin2.pass: spin1.pass
 -spin3.pass: spin2.pass
 -spin4.pass: spin3.pass
 -tsd1.pass: join1.pass
 -valid1.pass: join1.pass
 -valid2.pass: valid1.pass
 -cancel9.pass: cancel8.pass
 - -sizes.pass: sizes.exe
 -	@ $(ECHO) Running $*
 -	$< > SIZES.$(TEST)
 -	@ $(CAT) SIZES.$(TEST)
 -	@ $(ECHO) Passed
 -	@ $(TOUCH) $@
 - -%.pass: %.exe
 -	@ $(ECHO) Running $*
 -	$*
 -	@ $(ECHO) Passed
 -	@ $(TOUCH) $@
 - -%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe
 -	@ $(ECHO) Running $*
 -	$*
 -	@ $(ECHO) Done
 -	@ $(TOUCH) $@
 - -%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC)
 -	@ $(ECHO) Compiling $@
 -	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
 -	@ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
 - -%.pre: %.c $(HDR)
 -	@ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES)
 - -%.s: %.c $(HDR)
 -	@ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES)
 - -$(COPYFILES):
 -	@ $(ECHO) Copying $@
 -	@ $(CP) $(BUILD_DIR)/$@ .
 - -benchlib.o: benchlib.c
 -	@ $(ECHO) Compiling $@
 -	@ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES)
 -	@ $(CC) -c $(CFLAGS) $< $(INCLUDES)
 - -pthread.dll: $(DLL)
 -	@ $(CP) $(DLL) $@
 - -clean:
 -	- $(RM) *.dll
 -	- $(RM) *.lib
 -	- $(RM) pthread.h
 -	- $(RM) semaphore.h
 -	- $(RM) sched.h
 -	- $(RM) *.a
 -	- $(RM) *.e
 -	- $(RM) *.i
 -	- $(RM) *.o
 -	- $(RM) *.obj
 -	- $(RM) *.pdb
 -	- $(RM) *.exe
 -	- $(RM) *.pass
 -	- $(RM) *.bench
 -	- $(RM) *.log
 +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#      following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This 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 +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + +DLL_VER	= 1 + +CP	= cp -f +MV	= mv -f +RM	= rm -f +CAT	= cat +#CP	= copy +#MV	= rename +#RM	= erase +#CAT	= type +MKDIR	= mkdir +TOUCH	= echo Passed > +ECHO	= @echo +MAKE	= make + +# +# Mingw32 +# +XXCFLAGS	=  +XXLIBS	= -lws2_32 +#CFLAGS	= -O3 -UNDEBUG -Wall $(XXCFLAGS) +CFLAGS	= -g -UNDEBUG -Wall $(XXCFLAGS) +BUILD_DIR	= .. +INCLUDES	= -I. + + +TEST	= GC + +# Default lib version +GCX	= $(TEST)$(DLL_VER) + +# Files we need to run the tests +# - paths are relative to pthreads build dir. +HDR	= pthread.h semaphore.h sched.h +LIB	= libpthread$(GCX).a +DLL	= pthread$(GCX).dll +QAPC	= ../QueueUserAPCEx/User/quserex.dll + +COPYFILES	= $(HDR) $(LIB) $(DLL) $(QAPC) + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +TESTS	= sizes loadfree \ +	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ +	  semaphore1 semaphore2 semaphore3 \ +	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ +	  create1 create2 reuse1 reuse2 equal1 \ +	  kill1 valid1 valid2 \ +	  exit2 exit3 exit4 exit5 \ +	  join0 join1 join2 join3 \ +	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ +	  mutex4 mutex6 mutex6n mutex6e mutex6r \ +	  mutex6s mutex6es mutex6rs \ +	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ +	  count1 once1 once2 tsd1 self2 \ +	  cancel1 cancel2 \ +	  semaphore4 semaphore4t \ +	  delay1 delay2 eyal1 \ +	  condvar3 condvar3_1 condvar3_2 condvar3_3 \ +	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ +	  errno1 \ +	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \ +	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \ +	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \ +	  cancel7 cancel8 \ +	  cleanup0 cleanup1 cleanup2 cleanup3 \ +	  priority1 priority2 inherit1 \ +	  spin1 spin2 spin3 spin4 \ +	  barrier1 barrier2 barrier3 barrier4 barrier5 \ +	  exception1 exception2 exception3 \ +	  cancel9 create3 + +BENCHTESTS = \ +	benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 + +PASSES		= $(TESTS:%=%.pass) +BENCHRESULTS	= $(BENCHTESTS:%=%.bench) + +help: +	@ $(ECHO) "Run one of the following command lines:" +	@ $(ECHO) "make clean GC    (to test using GC dll with C (no EH) applications)" +	@ $(ECHO) "make clean GCX   (to test using GC dll with C++ (EH) applications)" +	@ $(ECHO) "make clean GCE   (to test using GCE dll with C++ (EH) applications)" +	@ $(ECHO) "make clean GC-bench	  (to benchtest using GNU C dll with C cleanup code)" +	@ $(ECHO) "make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)" + +all: +	@ $(MAKE) clean GC +	@ $(MAKE) clean GCX +	@ $(MAKE) clean GCE + +GC: +	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-pass + +GCE: +	$(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass + +GCX: +	$(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass + +GC-bench: +	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench + +GCE-bench: +	$(MAKE) TEST=GCE  CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench + +all-pass: $(PASSES) +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-bench: $(BENCHRESULTS) +	@ $(ECHO) BENCH TESTS COMPLETED. + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: + +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel2_1.pass: cancel2.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: cancel2.pass +delay2.pass: delay1.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: exit4.pass kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass + +sizes.pass: sizes.exe +	@ $(ECHO) Running $* +	$< > SIZES.$(TEST) +	@ $(CAT) SIZES.$(TEST) +	@ $(ECHO) Passed +	@ $(TOUCH) $@ + +%.pass: %.exe +	@ $(ECHO) Running $* +	$* +	@ $(ECHO) Passed +	@ $(TOUCH) $@ + +%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe +	@ $(ECHO) Running $* +	$* +	@ $(ECHO) Done +	@ $(TOUCH) $@ + +%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC) +	@ $(ECHO) Compiling $@ +	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) +	@ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) + +%.pre: %.c $(HDR) +	@ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES) + +%.s: %.c $(HDR) +	@ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES) + +$(COPYFILES): +	@ $(ECHO) Copying $@ +	@ $(CP) $(BUILD_DIR)/$@ . + +benchlib.o: benchlib.c +	@ $(ECHO) Compiling $@ +	@ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES) +	@ $(CC) -c $(CFLAGS) $< $(INCLUDES) + +pthread.dll: $(DLL) +	@ $(CP) $(DLL) $@ + +clean: +	- $(RM) *.dll +	- $(RM) *.lib +	- $(RM) pthread.h +	- $(RM) semaphore.h +	- $(RM) sched.h +	- $(RM) *.a +	- $(RM) *.e +	- $(RM) *.i +	- $(RM) *.o +	- $(RM) *.obj +	- $(RM) *.pdb +	- $(RM) *.exe +	- $(RM) *.pass +	- $(RM) *.bench +	- $(RM) *.log diff --git a/tests/Makefile b/tests/Makefile index e747ee5..cad2a94 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -95,7 +95,7 @@ PASSES= sizes.pass  loadfree.pass \  	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
  	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
  	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
 -	  count1.pass  once1.pass  tsd1.pass  \
 +	  count1.pass  once1.pass  once2.pass  tsd1.pass  \
  	  self2.pass  \
  	  cancel1.pass  cancel2.pass  \
  	  semaphore4.pass  semaphore4t.pass  \
 @@ -318,6 +318,7 @@ mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass
  mutex8r.pass: mutex7r.pass
  once1.pass: create1.pass
 +once2.pass: once1.pass
  priority1.pass: join1.pass
  priority2.pass: priority1.pass barrier3.pass
  reuse1.pass: create2.pass
 diff --git a/tests/Wmakefile b/tests/Wmakefile index a7005b9..91a4854 100644 --- a/tests/Wmakefile +++ b/tests/Wmakefile @@ -91,7 +91,7 @@ PASSES	= sizes.pass  loadfree.pass &  	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  &
  	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  &
  	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  &
 -	  count1.pass  once1.pass  tsd1.pass  &
 +	  count1.pass  once1.pass  once2.pass  tsd1.pass  &
  	  self2.pass  &
  	  cancel1.pass  cancel2.pass  &
  	  semaphore4.pass semaphore4t.pass  &
 @@ -303,6 +303,7 @@ mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass
  mutex8r.pass: mutex7r.pass
  once1.pass: create1.pass
 +once2.pass: once1.pass
  priority1.pass: join1.pass
  priority2.pass: priority1.pass barrier3.pass
  reuse1.pass: create2.pass
 diff --git a/tests/exit2.c b/tests/exit2.c index eaa557e..196139a 100644 --- a/tests/exit2.c +++ b/tests/exit2.c @@ -47,6 +47,8 @@ func(void * arg)  	/* Never reached. */  	assert(0); + +	return NULL;  }  int diff --git a/tests/exit3.c b/tests/exit3.c index fadd035..574a92d 100644 --- a/tests/exit3.c +++ b/tests/exit3.c @@ -45,6 +45,8 @@ func(void * arg)  	/* Never reached. */  	assert(0); + +	return NULL;  }  int diff --git a/tests/eyal1.c b/tests/eyal1.c index 2f846e8..31226b0 100644 --- a/tests/eyal1.c +++ b/tests/eyal1.c @@ -124,7 +124,7 @@ waste_time (int n)    int		i;    double	f, g, h, s; -  s = 0; +  s = 0.0;    /*     * Useless work. @@ -134,7 +134,7 @@ waste_time (int n)        f = rand ();        g = rand ();        h = rand (); -      s += 2 * f * g / (h != 0 ? (h * h) : 1); +      s += 2.0 * f * g / (h != 0.0 ? (h * h) : 1.0);      }    return s;  } diff --git a/tests/mutex5.c b/tests/mutex5.c index 10e224b..a597892 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -45,23 +45,19 @@ int  main()  {    int mxType = -1; -  int success = 0;   /* Use to quell GNU compiler warnings. */ -  assert(success = PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL); -  assert(success = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_ERRORCHECK); -  assert(success = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_RECURSIVE); -  assert(success = PTHREAD_MUTEX_RECURSIVE != PTHREAD_MUTEX_ERRORCHECK); +  assert(PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL); +  assert(PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_ERRORCHECK); +  assert(PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_RECURSIVE); +  assert(PTHREAD_MUTEX_RECURSIVE != PTHREAD_MUTEX_ERRORCHECK); -  assert(success = PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_FAST_NP); -  assert(success = PTHREAD_MUTEX_RECURSIVE == PTHREAD_MUTEX_RECURSIVE_NP); -  assert(success = PTHREAD_MUTEX_ERRORCHECK == PTHREAD_MUTEX_ERRORCHECK_NP); +  assert(PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_FAST_NP); +  assert(PTHREAD_MUTEX_RECURSIVE == PTHREAD_MUTEX_RECURSIVE_NP); +  assert(PTHREAD_MUTEX_ERRORCHECK == PTHREAD_MUTEX_ERRORCHECK_NP); -  if (success == success) -    { -      assert(pthread_mutexattr_init(&mxAttr) == 0); -      assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); -      assert(mxType == PTHREAD_MUTEX_NORMAL); -    } +  assert(pthread_mutexattr_init(&mxAttr) == 0); +  assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); +  assert(mxType == PTHREAD_MUTEX_NORMAL);    return 0;  } | 
