From 5f7ea668d6d4c96d9e0efea21ac5e300fda552ad Mon Sep 17 00:00:00 2001 From: rpj Date: Tue, 8 Jan 2002 02:21:06 +0000 Subject: * 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). --- ChangeLog | 23 +++++++++++++++++------ implement.h | 14 ++++++++++---- mutex.c | 60 ++++++++++++++++++++++++++++++------------------------------ private.c | 7 ++++--- 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 + + * 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 Contributed by - Thomas Pfaff @@ -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; -- cgit v1.2.3