diff options
| author | rpj <rpj> | 2004-10-01 07:17:09 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2004-10-01 07:17:09 +0000 | 
| commit | b0cf9efa6afeb8a7dbddf124dae173a2d633c801 (patch) | |
| tree | 8f208f15bd63cf69ae9e2ceb2d523296db8bca76 | |
| parent | 531ca4db4794aab863a898b4d079ccd59b424b25 (diff) | |
Mutex speedups
| -rw-r--r-- | ChangeLog | 42 | ||||
| -rw-r--r-- | implement.h | 7 | ||||
| -rw-r--r-- | pthread_mutex_destroy.c | 9 | ||||
| -rw-r--r-- | pthread_mutex_init.c | 2 | ||||
| -rw-r--r-- | pthread_mutex_lock.c | 64 | ||||
| -rw-r--r-- | pthread_mutex_timedlock.c | 244 | ||||
| -rw-r--r-- | pthread_mutex_trylock.c | 47 | ||||
| -rw-r--r-- | pthread_mutex_unlock.c | 72 | ||||
| -rw-r--r-- | tests/GNUmakefile | 2 | ||||
| -rw-r--r-- | tests/benchlib.c | 25 | ||||
| -rw-r--r-- | tests/benchtest.h | 3 | ||||
| -rw-r--r-- | tests/benchtest1.c | 42 | ||||
| -rw-r--r-- | tests/mutex4.c | 6 | 
13 files changed, 341 insertions, 224 deletions
| @@ -1,23 +1,39 @@ +2004-09-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
 + +	* pthread_mutex_lock.c (pthread_mutex_lock): Separate PTHREAD_MUTEX_NORMAL
 +	logic since we do not need to keep or check some state required by other
 +	mutex types; do not check mutex pointer arg for validity - leave this to
 +	the system since we are only checking for NULL pointers. This should improve
 +	speed of NORMAL mutexes and marginally improve speed of other type.
 +	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
 +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid
 +	entering the critical section for the no-waiters case, with approx. 30%
 +	reduction in lock/unlock overhead for this case..
 +	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also
 +	no longer keeps mutex if post-timeout second attempt succeeds - this will
 +	assist applications that wish to impose strict lock deadlines, rather than
 +	simply to escape from frozen locks.
 +  2004-09-09  Tristan Savatier  <tristan at mpegtv.com>
 -	* pthread.h (struct pthread_once_t_): Qualify the 'done' element -	as 'volatile'. -	* pthread_once.c: Concerned about possible race condition, -	specifically on MPU systems re concurrent access to multibyte types. -	[Maintainer's note: the race condition is harmless on SPU systems -	and only a problem on MPU systems if concurrent access results in an -	exception (presumably generated by a hardware interrupt). There are -	other instances of similar harmless race conditions that have not been -	identified as issues.] +	* pthread.h (struct pthread_once_t_): Qualify the 'done' element
 +	as 'volatile'.
 +	* pthread_once.c: Concerned about possible race condition,
 +	specifically on MPU systems re concurrent access to multibyte types.
 +	[Maintainer's note: the race condition is harmless on SPU systems
 +	and only a problem on MPU systems if concurrent access results in an
 +	exception (presumably generated by a hardware interrupt). There are
 +	other instances of similar harmless race conditions that have not been
 +	identified as issues.]
  2004-09-09  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -	* pthread.h: Declare additional types as volatile. +	* pthread.h: Declare additional types as volatile.
  2004-08-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -	* pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code -	by substituting the internal non-cancelable version of sem_wait -	(ptw32_semwait). +	* pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code
 +	by substituting the internal non-cancelable version of sem_wait
 +	(ptw32_semwait).
  2004-08-25  Ross Johnson  <rpj at callisto.canberra.edu.au>
 diff --git a/implement.h b/implement.h index 95308f5..400598c 100644 --- a/implement.h +++ b/implement.h @@ -423,13 +423,6 @@ struct ThreadKeyAssoc  #define PTW32_EPS_EXIT                  (1)  #define PTW32_EPS_CANCEL                (2) -/* Mutex constants */ -enum -{ -  PTW32_MUTEX_LOCK_IDX_INIT = -1, -  PTW32_MUTEX_OWNER_ANONYMOUS = 1 -}; -  /* Useful macros */  #define PTW32_MAX(a,b)  ((a)<(b)?(b):(a)) diff --git a/pthread_mutex_destroy.c b/pthread_mutex_destroy.c index a777598..c2289d0 100644 --- a/pthread_mutex_destroy.c +++ b/pthread_mutex_destroy.c @@ -44,10 +44,9 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)    int result = 0;    pthread_mutex_t mx; -  if (mutex == NULL || *mutex == NULL) -    { -      return EINVAL; -    } +  /* +   * Let the system deal with invalid pointers. +   */    /*     * Check to see if we have something to delete. @@ -64,7 +63,7 @@ pthread_mutex_destroy (pthread_mutex_t * mutex)         */        if (result == 0)  	{ -	  if (1 == mx->recursive_count) +	  if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count)  	    {  	      /*  	       * FIXME!!! diff --git a/pthread_mutex_init.c b/pthread_mutex_init.c index ebf26d5..93504ad 100644 --- a/pthread_mutex_init.c +++ b/pthread_mutex_init.c @@ -80,7 +80,7 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)      }    else      { -      mx->lock_idx = PTW32_MUTEX_LOCK_IDX_INIT; +      mx->lock_idx = -1;        mx->recursive_count = 0;        mx->kind = (attr == NULL || *attr == NULL  		  ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); diff --git a/pthread_mutex_lock.c b/pthread_mutex_lock.c index f92b39b..b733801 100644 --- a/pthread_mutex_lock.c +++ b/pthread_mutex_lock.c @@ -46,11 +46,9 @@ pthread_mutex_lock (pthread_mutex_t * mutex)    int result = 0;    pthread_mutex_t mx; - -  if (mutex == NULL || *mutex == NULL) -    { -      return EINVAL; -    } +  /* +   * Let the system deal with invalid pointers. +   */    /*     * We do a quick check to see if we need to do more work @@ -68,41 +66,51 @@ pthread_mutex_lock (pthread_mutex_t * mutex)    mx = *mutex; -  if (0 == InterlockedIncrement (&mx->lock_idx)) +  if (mx->kind == PTHREAD_MUTEX_NORMAL)      { -      mx->recursive_count = 1; -      mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -			 ? pthread_self () -			 : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); +      if (0 != InterlockedIncrement (&mx->lock_idx)) +	{ +	  if (ptw32_semwait (&mx->wait_sema) != 0) +	    { +	      result = errno; +	    } +	}      }    else      { -      if (mx->kind != PTHREAD_MUTEX_FAST_NP && -	  pthread_equal (mx->ownerThread, pthread_self ())) +      if (0 == InterlockedIncrement (&mx->lock_idx))  	{ -	  (void) InterlockedDecrement (&mx->lock_idx); - -	  if (mx->kind == PTHREAD_MUTEX_RECURSIVE_NP) -	    { -	      mx->recursive_count++; -	    } -	  else -	    { -	      result = EDEADLK; -	    } +	  mx->recursive_count = 1; +	  mx->ownerThread = pthread_self ();  	}        else  	{ -	  if (ptw32_semwait (&mx->wait_sema) == 0) +	  pthread_t self = pthread_self(); + +	  if (pthread_equal (mx->ownerThread, self))  	    { -	      mx->recursive_count = 1; -	      mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -				 ? pthread_self () -				 : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); +	      (void) InterlockedDecrement (&mx->lock_idx); +	       +	      if (mx->kind == PTHREAD_MUTEX_RECURSIVE) +		{ +		  mx->recursive_count++; +		} +	      else +		{ +		  result = EDEADLK; +		}  	    }  	  else  	    { -	      result = errno; +	      if (ptw32_semwait (&mx->wait_sema) == 0) +		{ +		  mx->recursive_count = 1; +		  mx->ownerThread = self; +		} +	      else +		{ +		  result = errno; +		}  	    }  	}      } diff --git a/pthread_mutex_timedlock.c b/pthread_mutex_timedlock.c index a5d6b59..58f5613 100644 --- a/pthread_mutex_timedlock.c +++ b/pthread_mutex_timedlock.c @@ -214,10 +214,9 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,    return -1;  #endif -  if (mutex == NULL || *mutex == NULL) -    { -      return EINVAL; -    } +  /* +   * Let the system deal with invalid pointers. +   */    /*     * We do a quick check to see if we need to do more work @@ -235,142 +234,135 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex,    mx = *mutex; -  if (0 == InterlockedIncrement (&mx->lock_idx)) +  if (mx->kind == PTHREAD_MUTEX_NORMAL)      { -      mx->recursive_count = 1; -      mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -			 ? pthread_self () -			 : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); +      if (0 != InterlockedIncrement (&mx->lock_idx)) +	{ +	  switch (ptw32_timed_semwait (&mx->wait_sema, abstime)) +	    { +	      case 0:	/* We got the mutex. */ +		{ +		  break; +		} +	      case 1:	/* Timed out. */ +	      case 2:	/* abstime passed before we started to wait. */ +		{ +		  /* +		   * If we timeout, it is up to us to adjust lock_idx to say +		   * we're no longer waiting. +		   * +		   * The owner thread may still have posted wait_sema thinking +		   * we were waiting. We must check but then NOT do any +		   * programmed work if we have acquired the mutex because +		   * we don't know how long ago abstime was. We MUST just release it +		   * immediately. +		   */ +		  EnterCriticalSection (&mx->wait_cs); + +		  result = ETIMEDOUT; + +		  if (-1 == sem_trywait (&mx->wait_sema)) +		    { +		      (void) InterlockedDecrement (&mx->lock_idx); +		    } +		  else +		    { +		      if (InterlockedDecrement (&mx->lock_idx) >= 0) +			{ +			  /* Someone else is waiting on that mutex */ +			  if (sem_post (&mx->wait_sema) != 0) +			    { +			      result = errno; +			    } +			} +		    } + +		  LeaveCriticalSection (&mx->wait_cs); +		  break; +		} +	      default: +		{ +		  result = errno; +		  break; +		} +	    } +	}      }    else      { -      if (mx->kind != PTHREAD_MUTEX_FAST_NP && -	  pthread_equal (mx->ownerThread, pthread_self ())) -	{ -	  (void) InterlockedDecrement (&mx->lock_idx); +      pthread_t self = pthread_self(); -	  if (mx->kind == PTHREAD_MUTEX_RECURSIVE_NP) -	    { -	      mx->recursive_count++; -	    } -	  else -	    { -	      result = EDEADLK; -	    } +      if (0 == InterlockedIncrement (&mx->lock_idx)) +	{ +	  mx->recursive_count = 1; +	  mx->ownerThread = self;  	}        else  	{ -	  if (abstime == NULL) +	  if (pthread_equal (mx->ownerThread, self))  	    { -	      result = EINVAL; +	      (void) InterlockedDecrement (&mx->lock_idx); + +	      if (mx->kind == PTHREAD_MUTEX_RECURSIVE) +		{ +		  mx->recursive_count++; +		} +	      else +		{ +		  result = EDEADLK; +		}  	    }  	  else  	    {  	      switch (ptw32_timed_semwait (&mx->wait_sema, abstime))  		{ -		case 0:	/* We got the mutex. */ -		  { -		    mx->recursive_count = 1; -		    mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -				       ? pthread_self () -				       : (pthread_t) -				       PTW32_MUTEX_OWNER_ANONYMOUS); -		    break; -		  } -		case 1:	/* Timedout, try a second grab. */ -		  { -		    int busy; - -		    EnterCriticalSection (&mx->wait_cs); - -		    /* -		     * If we timeout, it is up to us to adjust lock_idx to say -		     * we're no longer waiting. If the mutex was also unlocked -		     * while we were timing out, and we simply return ETIMEDOUT, -		     * then wait_sema would be left in a state that is not consistent -		     * with the state of lock_idx. -		     * -		     * We must check to see if wait_sema has just been posted -		     * but we can't just call sem_getvalue - we must compete for -		     * the semaphore using sem_trywait(), otherwise we would need -		     * additional critical sections elsewhere, which would make the -		     * logic too inefficient. -		     * -		     * If sem_trywait returns EAGAIN then either wait_sema -		     * was given directly to another waiting thread or -		     * another thread has called sem_*wait() before us and -		     * taken the lock. Then we MUST decrement lock_idx and return -		     * ETIMEDOUT. -		     * -		     * Otherwise we MUST return success (because we have effectively -		     * acquired the lock that would have been ours had we not -		     * timed out), and NOT decrement lock_idx. -		     * -		     * We can almost guarrantee that EAGAIN is the only -		     * possible error, so no need to test errno. -		     */ - -		    if (-1 == (busy = sem_trywait (&mx->wait_sema))) -		      { -			(void) InterlockedDecrement (&mx->lock_idx); -			result = ETIMEDOUT; -		      } - -		    LeaveCriticalSection (&mx->wait_cs); - -		    if (!busy) -		      { -			/* -			 * We have acquired the lock on second grab - keep it. -			 */ -			mx->recursive_count = 1; -			mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -					   ? pthread_self () -					   : (pthread_t) -					   PTW32_MUTEX_OWNER_ANONYMOUS); -		      } -		    break; -		  } -		case 2:	/* abstime passed before we started to wait. */ -		  { -		    /* -		     * If we timeout, it is up to us to adjust lock_idx to say -		     * we're no longer waiting. -		     * -		     * The owner thread may still have posted wait_sema thinking -		     * we were waiting. I believe we must check but then NOT do any -		     * programmed work if we have acquired the mutex because -		     * we don't how long ago abstime was. We MUST just release it -		     * immediately. -		     */ -		    EnterCriticalSection (&mx->wait_cs); - -		    result = ETIMEDOUT; - -		    if (-1 == sem_trywait (&mx->wait_sema)) -		      { -			(void) InterlockedDecrement (&mx->lock_idx); -		      } -		    else -		      { -			if (InterlockedDecrement (&mx->lock_idx) >= 0) -			  { -			    /* Someone else is waiting on that mutex */ -			    if (sem_post (&mx->wait_sema) != 0) -			      { -				result = errno; -			      } -			  } -		      } - -		    LeaveCriticalSection (&mx->wait_cs); -		    break; -		  } -		default: -		  { -		    result = errno; -		    break; -		  } +		  case 0:	/* We got the mutex. */ +		    { +		      mx->recursive_count = 1; +		      mx->ownerThread = self; +		      break; +		    } +		  case 1:	/* Timedout. */ +		  case 2:	/* abstime passed before we started to wait. */ +		    { +		      /* +		       * If we timeout, it is up to us to adjust lock_idx to say +		       * we're no longer waiting. +		       * +		       * The owner thread may still have posted wait_sema thinking +		       * we were waiting. We must check but then NOT do any +		       * programmed work if we have acquired the mutex because +		       * we don't know how long ago abstime was. We MUST just release it +		       * immediately. +		       */ +		      EnterCriticalSection (&mx->wait_cs); + +		      result = ETIMEDOUT; + +		      if (-1 == sem_trywait (&mx->wait_sema)) +			{ +			  (void) InterlockedDecrement (&mx->lock_idx); +			} +		     else +			{ +			  if (InterlockedDecrement (&mx->lock_idx) >= 0) +			    { +			      /* Someone else is waiting on that mutex */ +			      if (sem_post (&mx->wait_sema) != 0) +				{ +				  result = errno; +				} +			    } +			} + +		      LeaveCriticalSection (&mx->wait_cs); +		      break; +		    } +		  default: +		    { +		      result = errno; +		      break; +		    }  		}  	    }  	} diff --git a/pthread_mutex_trylock.c b/pthread_mutex_trylock.c index 6f137f0..bba8ed2 100644 --- a/pthread_mutex_trylock.c +++ b/pthread_mutex_trylock.c @@ -44,10 +44,9 @@ pthread_mutex_trylock (pthread_mutex_t * mutex)    int result = 0;    pthread_mutex_t mx; -  if (mutex == NULL || *mutex == NULL) -    { -      return EINVAL; -    } +  /* +   * Let the system deal with invalid pointers. +   */    /*     * We do a quick check to see if we need to do more work @@ -57,36 +56,36 @@ pthread_mutex_trylock (pthread_mutex_t * mutex)     */    if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)      { -      result = ptw32_mutex_check_need_init (mutex); +      if ((result = ptw32_mutex_check_need_init (mutex)) != 0) +	{ +	  return (result); +	}      }    mx = *mutex; -  if (result == 0) +  if ((PTW32_INTERLOCKED_LONG) -1 == +      ptw32_interlocked_compare_exchange ((PTW32_INTERLOCKED_LPLONG) & +					  mx->lock_idx, +					  (PTW32_INTERLOCKED_LONG) 0, +					  (PTW32_INTERLOCKED_LONG) -1))      { -      if ((PTW32_INTERLOCKED_LONG) PTW32_MUTEX_LOCK_IDX_INIT == -	  ptw32_interlocked_compare_exchange ((PTW32_INTERLOCKED_LPLONG) & -					      mx->lock_idx, -					      (PTW32_INTERLOCKED_LONG) 0, -					      (PTW32_INTERLOCKED_LONG) -					      PTW32_MUTEX_LOCK_IDX_INIT)) +      if (mx->kind != PTHREAD_MUTEX_NORMAL)  	{  	  mx->recursive_count = 1; -	  mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP -			     ? pthread_self () -			     : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); +	  mx->ownerThread = pthread_self (); +	} +    } +  else +    { +      if (mx->kind == PTHREAD_MUTEX_RECURSIVE && +	  pthread_equal (mx->ownerThread, pthread_self ())) +	{ +	  mx->recursive_count++;  	}        else  	{ -	  if (mx->kind == PTHREAD_MUTEX_RECURSIVE_NP && -	      pthread_equal (mx->ownerThread, pthread_self ())) -	    { -	      mx->recursive_count++; -	    } -	  else -	    { -	      result = EBUSY; -	    } +	  result = EBUSY;  	}      } diff --git a/pthread_mutex_unlock.c b/pthread_mutex_unlock.c index 05677c8..7b20d79 100644 --- a/pthread_mutex_unlock.c +++ b/pthread_mutex_unlock.c @@ -44,10 +44,9 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)    int result = 0;    pthread_mutex_t mx; -  if (mutex == NULL || *mutex == NULL) -    { -      return EINVAL; -    } +  /* +   * Let the system deal with invalid pointers. +   */    mx = *mutex; @@ -58,30 +57,67 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)     */    if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)      { -      if (mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS -	  || pthread_equal (mx->ownerThread, pthread_self ())) +      if (mx->kind == PTHREAD_MUTEX_NORMAL)  	{ -	  if (mx->kind != PTHREAD_MUTEX_RECURSIVE_NP -	      || 0 == --mx->recursive_count) -	    { -	      mx->ownerThread = NULL; -	      EnterCriticalSection (&mx->wait_cs); +	  LONG idx; + +	  idx = (LONG) ptw32_interlocked_compare_exchange ((PTW32_INTERLOCKED_LPLONG) +	  					           &mx->lock_idx, +						           (PTW32_INTERLOCKED_LONG) -1, +						           (PTW32_INTERLOCKED_LONG) 0); -	      if (InterlockedDecrement (&mx->lock_idx) >= 0) +	  if (idx != 0) +	    { +	      if (idx > 0)  		{ -		  /* Someone is waiting on that mutex */ -		  if (sem_post (&mx->wait_sema) != 0) +		  EnterCriticalSection (&mx->wait_cs); + +		  if (InterlockedDecrement (&mx->lock_idx) >= 0)  		    { -		      result = errno; +		      /* Someone is waiting on that mutex */ +		        if (sem_post (&mx->wait_sema) != 0) +			{ +			  result = errno; +	 		}  		    } -		} -	      LeaveCriticalSection (&mx->wait_cs); +		  LeaveCriticalSection (&mx->wait_cs); +	        } +	      else +		{ +		  /* +		   * Was not locked (so can't be owned by us). +		   */ +		  result = EPERM; +		}  	    }  	}        else  	{ -	  result = EPERM; +	  if (pthread_equal (mx->ownerThread, pthread_self ())) +	    { +	      if (mx->kind != PTHREAD_MUTEX_RECURSIVE +		  || 0 == --mx->recursive_count) +		{ +		  mx->ownerThread = NULL; +		  EnterCriticalSection (&mx->wait_cs); + +		  if (InterlockedDecrement (&mx->lock_idx) >= 0) +		    { +		      /* Someone is waiting on that mutex */ +		      if (sem_post (&mx->wait_sema) != 0) +			{ +			  result = errno; +			} +		    } + +		  LeaveCriticalSection (&mx->wait_cs); +		} +	    } +	  else +	    { +	      result = EPERM; +	    }  	}      }    else diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 04f9943..cc36b53 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -273,7 +273,7 @@ sizes.pass: sizes.exe  	@ $(ECHO) Passed  	@ $(TOUCH) $@ -%.bench: $(XXLIBS) %.exe +%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe  	@ $(ECHO) Running $*  	$*  	@ $(ECHO) Done diff --git a/tests/benchlib.c b/tests/benchlib.c index 78ec3c8..3fa7171 100644 --- a/tests/benchlib.c +++ b/tests/benchlib.c @@ -51,6 +51,31 @@ int old_mutex_use = OLD_WIN32CS;  BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;  HINSTANCE ptw32_h_kernel32; +void +dummy_call(int * a) +{ +} + +void +interlocked_inc_with_conditionals(int * a) +{ +  if (a != NULL) +    if (InterlockedIncrement((long *) a) == -1) +      { +        *a = 0; +      } +} + +void +interlocked_dec_with_conditionals(int * a) +{ +  if (a != NULL) +    if (InterlockedDecrement((long *) a) == -1) +      { +        *a = 0; +      } +} +  int  old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr)  { diff --git a/tests/benchtest.h b/tests/benchtest.h index 2401622..64af6c8 100644 --- a/tests/benchtest.h +++ b/tests/benchtest.h @@ -59,6 +59,9 @@ extern HINSTANCE ptw32_h_kernel32;  #define PTW32_OBJECT_AUTO_INIT ((void *) -1) +void dummy_call(int * a); +void interlocked_inc_with_conditionals(int *a); +void interlocked_dec_with_conditionals(int *a);  int old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr);  int old_mutex_lock(old_mutex_t *mutex);  int old_mutex_unlock(old_mutex_t *mutex); diff --git a/tests/benchtest1.c b/tests/benchtest1.c index 1a553dc..ce45cf2 100644 --- a/tests/benchtest1.c +++ b/tests/benchtest1.c @@ -101,6 +101,7 @@ runTest (char * testNameString, int mType)  int  main (int argc, char *argv[])  { +  int i = 0;    CRITICAL_SECTION cs;    old_mutex_t ox;    pthread_mutexattr_init(&ma); @@ -127,6 +128,45 @@ main (int argc, char *argv[])    overHeadMilliSecs = durationMilliSecs; +  TESTSTART +  assert((dummy_call(&i), 1) == one); +  assert((dummy_call(&i), 1) == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Dummy call x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  TESTSTART +  assert((interlocked_inc_with_conditionals(&i), 1) == one); +  assert((interlocked_dec_with_conditionals(&i), 1) == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Dummy call -> Interlocked with cond x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  TESTSTART +  assert((InterlockedIncrement(&i), 1) == one); +  assert((InterlockedDecrement(&i), 1) == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "InterlockedOp x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + +    InitializeCriticalSection(&cs);    TESTSTART @@ -139,7 +179,7 @@ main (int argc, char *argv[])    durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;    printf( "%-45s %15ld %15.3f\n", -	    "Simple Critical Section", +	    "Simple Critical Section x 2",            durationMilliSecs,            (float) durationMilliSecs * 1E3 / ITERATIONS); diff --git a/tests/mutex4.c b/tests/mutex4.c index 74ec159..75880fd 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -69,6 +69,9 @@ main()    assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0);    assert(pthread_mutex_init(&mutex1, &ma) == 0);    assert(pthread_mutex_lock(&mutex1) == 0); +  /* +   * NORMAL (fast) mutexes don't check ownership. +   */    assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0);    assert(pthread_join(t, NULL) == 0);    assert(pthread_mutex_unlock(&mutex1) == EPERM); @@ -78,6 +81,9 @@ main()    assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);    assert(pthread_mutex_init(&mutex1, &ma) == 0);    assert(pthread_mutex_lock(&mutex1) == 0); +  /* +   * NORMAL (fast) mutexes don't check ownership. +   */    assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0);    assert(pthread_join(t, NULL) == 0);    assert(pthread_mutex_unlock(&mutex1) == EPERM); | 
