diff options
| -rw-r--r-- | ChangeLog | 9 | ||||
| -rw-r--r-- | GNUmakefile | 2 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | global.c | 5 | ||||
| -rw-r--r-- | implement.h | 2 | ||||
| -rw-r--r-- | nonportable.c | 1 | ||||
| -rw-r--r-- | pthread.h | 1 | ||||
| -rwxr-xr-x | pthread_getsequence_np.c | 47 | ||||
| -rwxr-xr-x | pthread_mutex_consistent.c | 17 | ||||
| -rw-r--r-- | ptw32_new.c | 1 | ||||
| -rw-r--r-- | tests/Bmakefile | 13 | ||||
| -rw-r--r-- | tests/ChangeLog | 4 | ||||
| -rw-r--r-- | tests/GNUmakefile | 15 | ||||
| -rw-r--r-- | tests/Makefile | 15 | ||||
| -rw-r--r-- | tests/Wmakefile | 13 | ||||
| -rwxr-xr-x | tests/sequence1.c | 142 | 
16 files changed, 260 insertions, 29 deletions
@@ -1,3 +1,12 @@ +2011-03-26  Ross Johnson <ross.johnson at homemail.com.au>
 +
 +	* pthread_getsequence_np.c: New non-POSIX interface for compatibility
 +	with some other implementations; returns a 64 bit sequence number
 +	that is unique to each thread in the process.
 +	* pthread.h (pthread_getsequence_np): Added.
 +	* global.c: Add global sequence counter for above.
 +	* implement.h: Likewise.
 +
  2011-03-25  Ross Johnson <ross.johnson at homemail.com.au>
  	* (cancelLock): Convert to an MCS lock and rename to stateLock.
 diff --git a/GNUmakefile b/GNUmakefile index 40fd538..3491efd 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -194,6 +194,7 @@ SMALL_STATIC_OBJS	= \  		pthread_mutexattr_setkind_np.o \  		pthread_mutexattr_getkind_np.o \  		pthread_getw32threadhandle_np.o \ +		pthread_getsequence_np.o \  		pthread_delay_np.o \  		pthread_num_processors_np.o \  		pthread_win32_attach_detach_np.o \ @@ -353,6 +354,7 @@ NONPORTABLE_SRCS = \  		pthread_mutexattr_setkind_np.c \  		pthread_mutexattr_getkind_np.c \  		pthread_getw32threadhandle_np.c \ +                pthread_getsequence_np.c \  		pthread_delay_np.c \  		pthread_num_processors_np.c \  		pthread_win32_attach_detach_np.c \ @@ -140,6 +140,7 @@ SMALL_STATIC_OBJS	= \  		pthread_mutexattr_setkind_np.obj \  		pthread_mutexattr_getkind_np.obj \  		pthread_getw32threadhandle_np.obj \ +		pthread_getsequence_np.obj \  		pthread_delay_np.obj \  		pthread_num_processors_np.obj \  		pthread_win32_attach_detach_np.obj \ @@ -295,6 +296,7 @@ NONPORTABLE_SRCS = \  		pthread_mutexattr_setkind_np.c \  		pthread_mutexattr_getkind_np.c \  		pthread_getw32threadhandle_np.c \ +		pthread_getsequence_np.c \  		pthread_delay_np.c \  		pthread_num_processors_np.c \  		pthread_win32_attach_detach_np.c \ @@ -52,6 +52,11 @@ int ptw32_concurrency = 0;  /* What features have been auto-detected */  int ptw32_features = 0; +/* + * Global [process wide] thread sequence Number + */ +unsigned long long ptw32_threadSeqNumber = 0; +  /*    * Function pointer to QueueUserAPCEx if it exists, otherwise   * it will be set at runtime to a substitute routine which cannot unblock diff --git a/implement.h b/implement.h index b4c80b3..8a27fae 100644 --- a/implement.h +++ b/implement.h @@ -561,6 +561,8 @@ extern pthread_cond_t ptw32_cond_list_tail;  extern int ptw32_mutex_default_kind; +extern unsigned long long ptw32_threadSeqNumber; +  extern int ptw32_concurrency;  extern int ptw32_features; diff --git a/nonportable.c b/nonportable.c index 6c2a990..82c558b 100644 --- a/nonportable.c +++ b/nonportable.c @@ -40,6 +40,7 @@  #include "pthread_mutexattr_setkind_np.c"  #include "pthread_mutexattr_getkind_np.c"  #include "pthread_getw32threadhandle_np.c" +#include "pthread_getsequence_np.c"  #include "pthread_delay_np.c"  #include "pthread_num_processors_np.c"  #include "pthread_win32_attach_detach_np.c" @@ -1176,6 +1176,7 @@ PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t *   */  PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);  PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); +PTW32_DLLPORT unsigned long long PTW32_CDECL pthread_getsequence_np(pthread_t thread);  /*   * Useful if an application wants to statically link diff --git a/pthread_getsequence_np.c b/pthread_getsequence_np.c new file mode 100755 index 0000000..0e643e9 --- /dev/null +++ b/pthread_getsequence_np.c @@ -0,0 +1,47 @@ +/* + * pthread_getsequence_np.c + * + * Description: + * This translation unit implements non-portable thread functions. + * + * -------------------------------------------------------------------------- + * + *      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 + */ + +#include "pthread.h" +#include "implement.h" + +/* + * + */ +unsigned long long +pthread_getsequence_np (pthread_t thread) +{ +  return ((ptw32_thread_t*)thread.p)->seqNumber; +} diff --git a/pthread_mutex_consistent.c b/pthread_mutex_consistent.c index 5ceab0c..08572a5 100755 --- a/pthread_mutex_consistent.c +++ b/pthread_mutex_consistent.c @@ -83,7 +83,7 @@ ptw32_robust_mutex_inherit(pthread_mutex_t * mutex)    switch (PTW32_INTERLOCKED_COMPARE_EXCHANGE(              (LPLONG)&robust->stateInconsistent,              (LONG)PTW32_ROBUST_INCONSISTENT, -            -1L /* Terminating thread sets this */)) +            -1L /* The terminating thread sets this */))      {        case -1L:            result = EOWNERDEAD; @@ -99,6 +99,18 @@ ptw32_robust_mutex_inherit(pthread_mutex_t * mutex)    return result;  } +/* + * The next two internal support functions depend on only being + * called by the thread that owns the robust mutex. This enables + * us to avoid additional locks. + * Any mutex currently in the thread's robust mutex list is held + * by the thread, again eliminating the need for locks. + * The forward/backward links allow the thread to unlock mutexes + * in any order, not necessarily the reverse locking order. + * This is all possible because it is an error if a thread that + * does not own the [robust] mutex attempts to unlock it. + */ +  INLINE  void  ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self) @@ -131,10 +143,9 @@ ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp)  {    ptw32_robust_node_t** list;    pthread_mutex_t mx = *mutex; -  ptw32_thread_t* tp = mx->ownerThread.p;    ptw32_robust_node_t* robust = mx->robustNode; -  list = &tp->robustMxList; +  list = &(((ptw32_thread_t*)mx->ownerThread.p)->robustMxList);    mx->ownerThread.p = otp;    if (robust->next != NULL)      { diff --git a/ptw32_new.c b/ptw32_new.c index 881c6ac..ac836ea 100644 --- a/ptw32_new.c +++ b/ptw32_new.c @@ -70,6 +70,7 @@ ptw32_new (void)      }    /* Set default state. */ +  tp->seqNumber = ++ptw32_threadSeqNumber;    tp->sched_priority = THREAD_PRIORITY_NORMAL;    tp->detachState = PTHREAD_CREATE_JOINABLE;    tp->cancelState = PTHREAD_CANCEL_ENABLE; diff --git a/tests/Bmakefile b/tests/Bmakefile index 263d127..bd8d7b7 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -85,7 +85,7 @@ PASSES=   loadfree.pass \  	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \  	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \  	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \ -	  kill1.pass  valid1.pass  valid2.pass  \ +	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \  	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \  	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \  	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \ @@ -311,11 +311,6 @@ mutex8.pass: mutex7.pass  mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass  mutex8r.pass: mutex7r.pass -robust1.pass: mutex8r.pass -robust2.pass: mutex8r.pass -robust3.pass: robust2.pass -robust4.pass: robust3.pass -robust5.pass: robust4.pass  once1.pass: create1.pass  once2.pass: once1.pass  once3.pass: once2.pass @@ -324,6 +319,11 @@ priority1.pass: join1.pass  priority2.pass: priority1.pass barrier3.pass  reuse1.pass: create2.pass  reuse2.pass: reuse1.pass +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass  rwlock1.pass: condvar6.pass  rwlock2.pass: rwlock1.pass  rwlock3.pass: rwlock2.pass @@ -346,6 +346,7 @@ semaphore3.pass: semaphore2.pass  semaphore4.pass: semaphore3.pass cancel1.pass  semaphore4t.pass: semaphore4.pass  semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass  sizes.pass:  spin1.pass:  spin2.pass: spin1.pass diff --git a/tests/ChangeLog b/tests/ChangeLog index 8d7604f..47b8253 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2011-03-26  Ross Johnson <ross.johnson at homemail.com.au> + +	* sequence1.c: New test for new pthread_getsequence_np(). +  2011-03-24  Ross Johnson <ross.johnson at homemail.com.au>  	* mutex*.c: Include tests for robust mutexes wherever diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 98342cc..9a46b2c 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -92,7 +92,7 @@ TESTS	= \  	  semaphore1 semaphore2 semaphore3 \  	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \  	  create1 create2 reuse1 reuse2 equal1 \ -	  kill1 valid1 valid2 \ +	  sequence1 kill1 valid1 valid2 \  	  exit2 exit3 exit4 exit5 \  	  join0 join1 detach1 join2 join3 \  	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ @@ -131,7 +131,7 @@ STATICTESTS = \  	  semaphore1 semaphore2 semaphore3 \  	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \  	  create1 create2 reuse1 reuse2 equal1 \ -	  kill1 valid1 valid2 \ +	  sequence1 kill1 valid1 valid2 \  	  exit2 exit3 exit4 exit5 \  	  join0 join1 detach1 join2 join3 \  	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ @@ -329,11 +329,6 @@ mutex8.pass: mutex7.pass  mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass  mutex8r.pass: mutex7r.pass -robust1.pass: mutex8r.pass -robust2.pass: mutex8r.pass -robust3.pass: robust2.pass -robust4.pass: robust3.pass -robust5.pass: robust4.pass  once1.pass: create1.pass  once2.pass: once1.pass  once3.pass: once2.pass @@ -343,6 +338,11 @@ priority1.pass: join1.pass  priority2.pass: priority1.pass barrier3.pass  reuse1.pass: create2.pass  reuse2.pass: reuse1.pass +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass  rwlock1.pass: condvar6.pass  rwlock2.pass: rwlock1.pass  rwlock3.pass: rwlock2.pass @@ -365,6 +365,7 @@ semaphore3.pass: semaphore2.pass  semaphore4.pass: semaphore3.pass cancel1.pass  semaphore4t.pass: semaphore4.pass  semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass  sizes.pass:  spin1.pass:  spin2.pass: spin1.pass diff --git a/tests/Makefile b/tests/Makefile index 5439ee1..4164e1e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -89,7 +89,7 @@ PASSES= sizes.pass  loadfree.pass \  	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \  	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \  	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \ -	  kill1.pass  valid1.pass  valid2.pass  \ +	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \  	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \  	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \  	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \ @@ -135,7 +135,7 @@ STATICRESULTS = \  	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \  	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \  	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \ -	  kill1.pass  valid1.pass  valid2.pass  \ +	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  \  	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \  	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  \  	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \ @@ -400,11 +400,6 @@ mutex8.pass: mutex7.pass  mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass  mutex8r.pass: mutex7r.pass -robust1.pass: mutex8r.pass -robust2.pass: mutex8r.pass -robust3.pass: robust2.pass -robust4.pass: robust3.pass -robust5.pass: robust4.pass  once1.pass: create1.pass  once2.pass: once1.pass  once3.pass: once2.pass @@ -413,6 +408,11 @@ priority1.pass: join1.pass  priority2.pass: priority1.pass barrier3.pass  reuse1.pass: create2.pass  reuse2.pass: reuse1.pass +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass  rwlock1.pass: condvar6.pass  rwlock2.pass: rwlock1.pass  rwlock3.pass: rwlock2.pass @@ -435,6 +435,7 @@ semaphore3.pass: semaphore2.pass  semaphore4.pass: semaphore3.pass cancel1.pass  semaphore4t.pass: semaphore4.pass  semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass  sizes.pass:  spin1.pass:  spin2.pass: spin1.pass diff --git a/tests/Wmakefile b/tests/Wmakefile index c7e97fb..0fcbd43 100644 --- a/tests/Wmakefile +++ b/tests/Wmakefile @@ -87,7 +87,7 @@ PASSES	= sizes.pass  loadfree.pass &  	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  &  	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  &  	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  & -	  kill1.pass  valid1.pass  valid2.pass  & +	  sequence1.pass  kill1.pass  valid1.pass  valid2.pass  &  	  exit2.pass  exit3.pass  exit4  exit5  &  	  join0.pass  join1.pass  detach1.pass  join2.pass join3.pass  &  	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  & @@ -309,11 +309,6 @@ mutex8.pass: mutex7.pass  mutex8n.pass: mutex7n.pass  mutex8e.pass: mutex7e.pass  mutex8r.pass: mutex7r.pass -robust1.pass: mutex8r.pass -robust2.pass: mutex8r.pass -robust3.pass: robust2.pass -robust4.pass: robust3.pass -robust5.pass: robust4.pass  once1.pass: create1.pass  once2.pass: once1.pass  once3.pass: once2.pass @@ -322,6 +317,11 @@ priority1.pass: join1.pass  priority2.pass: priority1.pass barrier3.pass  reuse1.pass: create2.pass  reuse2.pass: reuse1.pass +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass  rwlock1.pass: condvar6.pass  rwlock2.pass: rwlock1.pass  rwlock3.pass: rwlock2.pass @@ -343,6 +343,7 @@ semaphore3.pass: semaphore2.pass  semaphore4.pass: semaphore3.pass cancel1.pass  semaphore4t.pass: semaphore4.pass  semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass  sizes.pass:  spin1.pass:  spin2.pass: spin1.pass diff --git a/tests/sequence1.c b/tests/sequence1.c new file mode 100755 index 0000000..d7c6e0b --- /dev/null +++ b/tests/sequence1.c @@ -0,0 +1,142 @@ +/* + * File: sequence1.c + * + * + * -------------------------------------------------------------------------- + * + *      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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - that unique thread sequence numbers are generated. + * - Analyse thread struct reuse. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - This test is implementation specific + * because it uses knowledge of internals that should be + * opaque to an application. + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - analysis output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - unique sequence numbers are generated for every new thread. + * + * Fail Criteria: + * -  + */ + +#include "test.h" + +/* + */ + +enum { +	NUMTHREADS = 10000 +}; + + +static long done = 0; +/* + * seqmap should have 1 in every element except [0] + * Thread sequence numbers start at 1 and we will also + * include this main thread so we need NUMTHREADS+2 + * elements.  + */ +static UINT64 seqmap[NUMTHREADS+2]; + +void * func(void * arg) +{ +  sched_yield(); +  seqmap[(int)pthread_getsequence_np(pthread_self())] = 1; +  InterlockedIncrement(&done); + +  return (void *) 0;  +} +  +int +main() +{ +  pthread_t t[NUMTHREADS]; +  pthread_attr_t attr; +  int i; + +  assert(pthread_attr_init(&attr) == 0); +  assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + +  for (i = 0; i <= NUMTHREADS+2; i++) +    { +      seqmap[i] = 0; +    } + +  for (i = 0; i < NUMTHREADS; i++) +    { +      if (NUMTHREADS/2 == i) +        { +          /* Include this main thread, which will be an implicit pthread_t */ +          seqmap[(int)pthread_getsequence_np(pthread_self())] = 1; +        } +      assert(pthread_create(&t[i], &attr, func, NULL) == 0); +    } + +  while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L)) +    Sleep(100); + +  Sleep(100); + +  assert(seqmap[0] == 0); +  for (i = 1; i < NUMTHREADS+2; i++) +    { +      assert(seqmap[i] == 1); +    } + +  return 0; +}  | 
