summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--implement.h14
-rw-r--r--mutex.c60
-rw-r--r--private.c7
4 files changed, 61 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 72593f2..a3e1403 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2002-01-08 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_trylock): use
+ ptw32_interlocked_compare_exchange function pointer
+ rather than ptw32_InterlockedCompareExchange() directly
+ to retain portability to non-iX86 processors,
+ e.g. WinCE etc. The pointer will point to the native
+ OS version of InterlockedCompareExchange() if the
+ OS supports it (see ChangeLog entry of 2001-10-17).
+
2002-01-07 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
Contributed by - Thomas Pfaff <tpfaff@gmx.net>
@@ -7,12 +17,13 @@
section calls.
(pthread_mutex_destroy): Likewise.
(pthread_mutex_unlock): Likewise.
- (pthread_mutex_trylock): Likewise; recursive mutexes
- now increment the lock count rather than return EBUSY;
- errorcheck mutexes return EDEADLCK rather than
- EBUSY. This behaviour is consistent with the Solaris
- pthreads implementation.
-
+ (pthread_mutex_trylock): Likewise; uses
+ ptw32_InterlockedCompareExchange() to avoid need for
+ critical section; library is no longer i386 compatible;
+ recursive mutexes now increment the lock count rather
+ than return EBUSY; errorcheck mutexes return EDEADLCK
+ rather than EBUSY. This behaviour is consistent with the
+ Solaris pthreads implementation.
* implement.h (pthread_mutex_t_): Remove critical
section element - no longer needed.
diff --git a/implement.h b/implement.h
index e07306b..e075ee9 100644
--- a/implement.h
+++ b/implement.h
@@ -156,11 +156,17 @@ struct sem_t_ {
#define PTW32_OBJECT_INVALID NULL
struct pthread_mutex_t_ {
- LONG lock_idx;
- int recursive_count;
- int kind;
+ LONG lock_idx; /* Provides exclusive access to mutex state
+ via the Interlocked* mechanism, as well
+ as a count of the number of threads
+ waiting on the mutex. */
+ int recursive_count; /* Number of unlocks a thread needs to perform
+ before the lock is released (recursive
+ mutexes only). */
+ int kind; /* Mutex type. */
pthread_t ownerThread;
- HANDLE wait_sema;
+ HANDLE wait_sema; /* Mutex release notification to waiting
+ threads. */
};
struct pthread_mutexattr_t_ {
diff --git a/mutex.c b/mutex.c
index 7a232c5..d1d7aad 100644
--- a/mutex.c
+++ b/mutex.c
@@ -699,12 +699,12 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
{
mx->ownerThread = NULL;
- if( InterlockedDecrement( &mx->lock_idx ) >= 0 )
- {
- /* Someone is waiting on that mutex */
- ReleaseSemaphore( mx->wait_sema, 1, NULL );
- }
- }
+ if( InterlockedDecrement( &mx->lock_idx ) >= 0 )
+ {
+ /* Someone is waiting on that mutex */
+ ReleaseSemaphore( mx->wait_sema, 1, NULL );
+ }
+ }
}
else
{
@@ -745,35 +745,35 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
if (result == 0)
{
-
- if( PTW32_MUTEX_LOCK_IDX_INIT == ptw32_InterlockedCompareExchange(
- &mx->lock_idx, 0, PTW32_MUTEX_LOCK_IDX_INIT ) )
- {
- mx->recursive_count = 1;
- mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP
- ? pthread_self()
- : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS);
- }
-
+ 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))
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP
+ ? pthread_self()
+ : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS);
+ }
else
- {
- if( mx->kind != PTHREAD_MUTEX_FAST_NP &&
- pthread_equal( mx->ownerThread, pthread_self() ) )
- {
- if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP )
+ {
+ if( mx->kind != PTHREAD_MUTEX_FAST_NP &&
+ pthread_equal( mx->ownerThread, pthread_self() ) )
{
- mx->recursive_count++;
+ if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP )
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EDEADLK;
+ }
}
- else
+ else
{
- result = EDEADLK;
+ result = EBUSY;
}
- }
- else
- {
- result = EBUSY;
- }
- }
+ }
}
return(result);
diff --git a/private.c b/private.c
index 8aa7d84..0d6b5f3 100644
--- a/private.c
+++ b/private.c
@@ -1080,9 +1080,10 @@ ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG location,
#else
/*
- * If we get to here then we should be running on a Win95 system but either
- * running on something other than an X86 processor, or a compiler other
- * than MSVC or GCC. Pthreads-win32 doesn't support that platform (yet).
+ * If execution gets to here then we should be running on a Win95 system
+ * but either running on something other than an X86 processor, or a
+ * compiler other than MSVC or GCC. Pthreads-win32 doesn't support that
+ * platform (yet).
*/
result = 0;