diff -urp src.old/winsup/cygwin/include/pthread.h src/winsup/cygwin/include/pthread.h --- src.old/winsup/cygwin/include/pthread.h 2003-02-27 09:14:21.000000000 +0100 +++ src/winsup/cygwin/include/pthread.h 2003-02-27 09:20:24.000000000 +0100 @@ -52,6 +52,7 @@ extern "C" #define PTHREAD_INHERIT_SCHED 0 #define PTHREAD_MUTEX_RECURSIVE 0 #define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_NORMAL 2 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK /* this should be too low to ever be a valid address */ #define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)20 diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc --- src.old/winsup/cygwin/thread.cc 2003-02-27 09:14:21.000000000 +0100 +++ src/winsup/cygwin/thread.cc 2003-02-27 09:23:10.000000000 +0100 @@ -32,7 +32,6 @@ details. */ #ifdef _MT_SAFE #include "winsup.h" #include -#include #include "cygerrno.h" #include #include @@ -328,6 +327,8 @@ pthread::precreate (pthread_attr *newatt magic = 0; return; } + /* Change the mutex type to NORMAL to speed up mutex operations */ + mutex.type = PTHREAD_MUTEX_NORMAL; cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); if (!cancel_event) @@ -1157,6 +1158,19 @@ pthread_mutex::isGoodInitializerOrBadObj return true; } +bool +pthread_mutex::canBeUnlocked (pthread_mutex_t const *mutex) +{ + pthread_t self = pthread::self (); + + if (!isGoodObject (mutex)) + return false; + /* + * Check if the mutex is owned by the current thread and can be unlocked + */ + return (__pthread_equal (&(*mutex)->owner, &self)) && 1 == (*mutex)->recursion_counter; +} + /* This is used for mutex creation protection within a single process only */ nativeMutex NO_COPY pthread_mutex::mutexInitializationLock; @@ -1172,7 +1186,7 @@ pthread_mutex::initMutex () pthread_mutex::pthread_mutex (pthread_mutexattr *attr) : verifyable_object (PTHREAD_MUTEX_MAGIC), - lock_counter (MUTEX_LOCK_COUNTER_INITIAL), + lock_counter (0), win32_obj_id (NULL), recursion_counter (0), condwaits (0), owner (NULL), type (PTHREAD_MUTEX_DEFAULT), pshared (PTHREAD_PROCESS_PRIVATE) @@ -1221,16 +1235,15 @@ pthread_mutex::~pthread_mutex () } int -pthread_mutex::Lock () +pthread_mutex::_Lock (pthread_t self) { int result = 0; - pthread_t self = pthread::self (); - if (0 == InterlockedIncrement (&lock_counter)) - SetOwner (); - else if (__pthread_equal (&owner, &self)) + if (1 == InterlockedIncrement ((long *)&lock_counter)) + SetOwner (self); + else if (PTHREAD_MUTEX_NORMAL != type && __pthread_equal (&owner, &self)) { - InterlockedDecrement (&lock_counter); + InterlockedDecrement ((long *) &lock_counter); if (PTHREAD_MUTEX_RECURSIVE == type) result = LockRecursive (); else @@ -1239,23 +1252,20 @@ pthread_mutex::Lock () else { WaitForSingleObject (win32_obj_id, INFINITE); - SetOwner (); + SetOwner (self); } return result; } -/* returns non-zero on failure */ int -pthread_mutex::TryLock () +pthread_mutex::_TryLock (pthread_t self) { int result = 0; - pthread_t self = pthread::self (); - if (MUTEX_LOCK_COUNTER_INITIAL == - InterlockedCompareExchange (&lock_counter, 0, MUTEX_LOCK_COUNTER_INITIAL )) - SetOwner (); - else if (__pthread_equal (&owner, &self) && PTHREAD_MUTEX_RECURSIVE == type) + if (0 == InterlockedCompareExchange ((long *)&lock_counter, 1, 0 )) + SetOwner (self); + else if (PTHREAD_MUTEX_RECURSIVE == type && __pthread_equal (&owner, &self)) result = LockRecursive (); else result = EBUSY; @@ -1264,17 +1274,15 @@ pthread_mutex::TryLock () } int -pthread_mutex::UnLock () +pthread_mutex::_UnLock (pthread_t self) { - pthread_t self = pthread::self (); - if (!__pthread_equal (&owner, &self)) return EPERM; if (0 == --recursion_counter) { owner = NULL; - if (MUTEX_LOCK_COUNTER_INITIAL != InterlockedDecrement (&lock_counter)) + if (InterlockedDecrement ((long *)&lock_counter)) // Another thread is waiting ::ReleaseSemaphore (win32_obj_id, 1, NULL); } @@ -1283,9 +1291,9 @@ pthread_mutex::UnLock () } int -pthread_mutex::Destroy () +pthread_mutex::_Destroy (pthread_t self) { - if (condwaits || TryLock ()) + if (condwaits || _TryLock (self)) // Do not destroy a condwaited or locked mutex return EBUSY; else if (recursion_counter != 1) @@ -1300,22 +1308,6 @@ pthread_mutex::Destroy () } void -pthread_mutex::SetOwner () -{ - recursion_counter = 1; - owner = pthread::self (); -} - -int -pthread_mutex::LockRecursive () -{ - if (UINT_MAX == recursion_counter) - return EAGAIN; - ++recursion_counter; - return 0; -} - -void pthread_mutex::fixup_after_fork () { debug_printf ("mutex %x in fixup_after_fork", this); @@ -1324,10 +1316,10 @@ pthread_mutex::fixup_after_fork () if (NULL == owner) /* mutex has no owner, reset to initial */ - lock_counter = MUTEX_LOCK_COUNTER_INITIAL; - else if (lock_counter != MUTEX_LOCK_COUNTER_INITIAL) - /* All waiting threads are gone after a fork */ lock_counter = 0; + else if (lock_counter != 0) + /* All waiting threads are gone after a fork */ + lock_counter = 1; win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); if (!win32_obj_id) @@ -2615,6 +2607,7 @@ __pthread_mutexattr_settype (pthread_mut { case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_RECURSIVE: + case PTHREAD_MUTEX_NORMAL: (*attr)->mutextype = type; break; default: diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h --- src.old/winsup/cygwin/thread.h 2003-02-27 09:14:21.000000000 +0100 +++ src/winsup/cygwin/thread.h 2003-02-27 09:20:24.000000000 +0100 @@ -39,6 +39,8 @@ extern "C" #else #include +#include +#include #include #include #include @@ -160,9 +162,9 @@ private: #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6 #define SEM_MAGIC PTHREAD_MAGIC+7 -#define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8; +#define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8 -#define MUTEX_LOCK_COUNTER_INITIAL (-1) +#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1) /* verifyable_object should not be defined here - it's a general purpose class */ @@ -304,10 +306,11 @@ public: static bool isGoodInitializer (pthread_mutex_t const *); static bool isGoodInitializerOrObject (pthread_mutex_t const *); static bool isGoodInitializerOrBadObject (pthread_mutex_t const *mutex); + static bool canBeUnlocked (pthread_mutex_t const *mutex); static void initMutex (); static int init (pthread_mutex_t *, const pthread_mutexattr_t *); - LONG lock_counter; + unsigned long lock_counter; HANDLE win32_obj_id; unsigned int recursion_counter; LONG condwaits; @@ -316,12 +319,48 @@ public: int pshared; class pthread_mutex * next; - int Lock (); - int TryLock (); - int UnLock (); - int Destroy (); - void SetOwner (); - int LockRecursive (); + int _Lock (pthread_t self); + int _TryLock (pthread_t self); + int _UnLock (pthread_t self); + int _Destroy (pthread_t self); + + pthread_t GetPthreadSelf () + { + return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS : + ::pthread_self (); + } + + int Lock () + { + return _Lock (GetPthreadSelf ()); + } + int TryLock () + { + return _TryLock (GetPthreadSelf ()); + } + int UnLock () + { + return _UnLock (GetPthreadSelf ()); + } + int Destroy () + { + return _Destroy (GetPthreadSelf ()); + } + + void SetOwner (pthread_t self) + { + recursion_counter = 1; + owner = self; + } + + int LockRecursive () + { + if (UINT_MAX == recursion_counter) + return EAGAIN; + ++recursion_counter; + return 0; + } + void fixup_after_fork (); pthread_mutex (pthread_mutexattr * = NULL);