* include/pthread.h (PTHREAD_MUTEX_NORMAL): New define.

* thread.cc: Remove errno.h include.
(pthread::precreate): Change internal mutex type to normal.
(pthread_mutex::canBeUnlocked): Implement.
(pthread_mutex::pthread_mutex): Initialize lock_counter with 0.
(pthread_mutex::Lock): Rename to _Lock. Add self parameter.
Change lock_counter logic. Update SetOwner call.
(pthread_mutex::TryLock): Rename to _TryLock. Add self parameter.
Change lock_counter logic. Update SetOwner call.
(pthread_mutex::UnLock): Rename to _UnLock. Add self parameter.
Change lock_counter logic.
(pthread_mutex::Destroy): Rename to _Destroy. Update TryLock call.
(pthread_mutex::SetOwner): Move to thread.h as inline.
(pthread_mutex::LockRecursive): Ditto.
(pthread_mutex::fixup_after_fork): Change lock_counter logic.
(__pthread_mutexattr_settype): Add PTHREAD_MUTEX_NORMAL to valid
types check.
* thread.h: Include errno.h and limits.h.
(MUTEX_LOCK_COUNTER_INITIAL): Remove.
(MUTEX_OWNER_ANONYMOUS): New define.
(pthread_mutex::canBeUnlocked): New static method.
(pthread_mutex::lock_counter): Change type to unsigned long.
(pthread_mutex::GetPthreadSelf): New method.
(pthread_mutex::Lock): Call _Lock with pthread_self pointer.
(pthread_mutex::TryLock): Call _TryLock with pthread_self pointer.
(pthread_mutex::UnLock): Call _UnLock with pthread_self pointer.
(pthread_mutex::Destroy): Call _Destroy with pthread_self pointer.
(pthread_mutex::SetOwner): Moved from thread.cc as inline.
(pthread_mutex::LockRecursive): Ditto.
(pthread_mutex::_Lock): New method.
(pthread_mutex::_TryLock): New method.
(pthread_mutex::_UnLock): New method.
(pthread_mutex::_Destroy): New method.
This commit is contained in:
Thomas Pfaff 2003-03-18 19:39:21 +00:00
parent dcd350f0ec
commit 2ff03dc2e0
4 changed files with 119 additions and 50 deletions

View File

@ -1,3 +1,39 @@
2003-03-18 Thomas Pfaff <tpfaff@gmx.net>
* include/pthread.h (PTHREAD_MUTEX_NORMAL): New define.
* thread.cc: Remove errno.h include.
(pthread::precreate): Change internal mutex type to normal.
(pthread_mutex::canBeUnlocked): Implement.
(pthread_mutex::pthread_mutex): Initialize lock_counter with 0.
(pthread_mutex::Lock): Rename to _Lock. Add self parameter.
Change lock_counter logic. Update SetOwner call.
(pthread_mutex::TryLock): Rename to _TryLock. Add self parameter.
Change lock_counter logic. Update SetOwner call.
(pthread_mutex::UnLock): Rename to _UnLock. Add self parameter.
Change lock_counter logic.
(pthread_mutex::Destroy): Rename to _Destroy. Update TryLock call.
(pthread_mutex::SetOwner): Move to thread.h as inline.
(pthread_mutex::LockRecursive): Ditto.
(pthread_mutex::fixup_after_fork): Change lock_counter logic.
(__pthread_mutexattr_settype): Add PTHREAD_MUTEX_NORMAL to valid
types check.
* thread.h: Include errno.h and limits.h.
(MUTEX_LOCK_COUNTER_INITIAL): Remove.
(MUTEX_OWNER_ANONYMOUS): New define.
(pthread_mutex::canBeUnlocked): New static method.
(pthread_mutex::lock_counter): Change type to unsigned long.
(pthread_mutex::GetPthreadSelf): New method.
(pthread_mutex::Lock): Call _Lock with pthread_self pointer.
(pthread_mutex::TryLock): Call _TryLock with pthread_self pointer.
(pthread_mutex::UnLock): Call _UnLock with pthread_self pointer.
(pthread_mutex::Destroy): Call _Destroy with pthread_self pointer.
(pthread_mutex::SetOwner): Moved from thread.cc as inline.
(pthread_mutex::LockRecursive): Ditto.
(pthread_mutex::_Lock): New method.
(pthread_mutex::_TryLock): New method.
(pthread_mutex::_UnLock): New method.
(pthread_mutex::_Destroy): New method.
2003-03-18 Christopher January <chris@atomice.net> 2003-03-18 Christopher January <chris@atomice.net>
* fhandler_proc.cc (format_proc_cpuinfo): Use IsProcessorFeaturePresent * fhandler_proc.cc (format_proc_cpuinfo): Use IsProcessorFeaturePresent

View File

@ -52,6 +52,7 @@ extern "C"
#define PTHREAD_INHERIT_SCHED 0 #define PTHREAD_INHERIT_SCHED 0
#define PTHREAD_MUTEX_RECURSIVE 0 #define PTHREAD_MUTEX_RECURSIVE 0
#define PTHREAD_MUTEX_ERRORCHECK 1 #define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_NORMAL 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
/* this should be too low to ever be a valid address */ /* this should be too low to ever be a valid address */
#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)20 #define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)20

View File

@ -32,7 +32,6 @@ details. */
#ifdef _MT_SAFE #ifdef _MT_SAFE
#include "winsup.h" #include "winsup.h"
#include <limits.h> #include <limits.h>
#include <errno.h>
#include "cygerrno.h" #include "cygerrno.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -328,6 +327,8 @@ pthread::precreate (pthread_attr *newattr)
magic = 0; magic = 0;
return; 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); cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
if (!cancel_event) if (!cancel_event)
@ -1157,6 +1158,19 @@ pthread_mutex::isGoodInitializerOrBadObject (pthread_mutex_t const *mutex)
return true; 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 */ /* This is used for mutex creation protection within a single process only */
nativeMutex NO_COPY pthread_mutex::mutexInitializationLock; nativeMutex NO_COPY pthread_mutex::mutexInitializationLock;
@ -1172,7 +1186,7 @@ pthread_mutex::initMutex ()
pthread_mutex::pthread_mutex (pthread_mutexattr *attr) : pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
verifyable_object (PTHREAD_MUTEX_MAGIC), verifyable_object (PTHREAD_MUTEX_MAGIC),
lock_counter (MUTEX_LOCK_COUNTER_INITIAL), lock_counter (0),
win32_obj_id (NULL), recursion_counter (0), win32_obj_id (NULL), recursion_counter (0),
condwaits (0), owner (NULL), type (PTHREAD_MUTEX_DEFAULT), condwaits (0), owner (NULL), type (PTHREAD_MUTEX_DEFAULT),
pshared (PTHREAD_PROCESS_PRIVATE) pshared (PTHREAD_PROCESS_PRIVATE)
@ -1221,16 +1235,15 @@ pthread_mutex::~pthread_mutex ()
} }
int int
pthread_mutex::Lock () pthread_mutex::_Lock (pthread_t self)
{ {
int result = 0; int result = 0;
pthread_t self = pthread::self ();
if (0 == InterlockedIncrement (&lock_counter)) if (1 == InterlockedIncrement ((long *)&lock_counter))
SetOwner (); SetOwner (self);
else if (__pthread_equal (&owner, &self)) else if (PTHREAD_MUTEX_NORMAL != type && __pthread_equal (&owner, &self))
{ {
InterlockedDecrement (&lock_counter); InterlockedDecrement ((long *) &lock_counter);
if (PTHREAD_MUTEX_RECURSIVE == type) if (PTHREAD_MUTEX_RECURSIVE == type)
result = LockRecursive (); result = LockRecursive ();
else else
@ -1239,23 +1252,20 @@ pthread_mutex::Lock ()
else else
{ {
WaitForSingleObject (win32_obj_id, INFINITE); WaitForSingleObject (win32_obj_id, INFINITE);
SetOwner (); SetOwner (self);
} }
return result; return result;
} }
/* returns non-zero on failure */
int int
pthread_mutex::TryLock () pthread_mutex::_TryLock (pthread_t self)
{ {
int result = 0; int result = 0;
pthread_t self = pthread::self ();
if (MUTEX_LOCK_COUNTER_INITIAL == if (0 == InterlockedCompareExchange ((long *)&lock_counter, 1, 0 ))
InterlockedCompareExchange (&lock_counter, 0, MUTEX_LOCK_COUNTER_INITIAL )) SetOwner (self);
SetOwner (); else if (PTHREAD_MUTEX_RECURSIVE == type && __pthread_equal (&owner, &self))
else if (__pthread_equal (&owner, &self) && PTHREAD_MUTEX_RECURSIVE == type)
result = LockRecursive (); result = LockRecursive ();
else else
result = EBUSY; result = EBUSY;
@ -1264,17 +1274,15 @@ pthread_mutex::TryLock ()
} }
int int
pthread_mutex::UnLock () pthread_mutex::_UnLock (pthread_t self)
{ {
pthread_t self = pthread::self ();
if (!__pthread_equal (&owner, &self)) if (!__pthread_equal (&owner, &self))
return EPERM; return EPERM;
if (0 == --recursion_counter) if (0 == --recursion_counter)
{ {
owner = NULL; owner = NULL;
if (MUTEX_LOCK_COUNTER_INITIAL != InterlockedDecrement (&lock_counter)) if (InterlockedDecrement ((long *)&lock_counter))
// Another thread is waiting // Another thread is waiting
::ReleaseSemaphore (win32_obj_id, 1, NULL); ::ReleaseSemaphore (win32_obj_id, 1, NULL);
} }
@ -1283,9 +1291,9 @@ pthread_mutex::UnLock ()
} }
int 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 // Do not destroy a condwaited or locked mutex
return EBUSY; return EBUSY;
else if (recursion_counter != 1) else if (recursion_counter != 1)
@ -1299,22 +1307,6 @@ pthread_mutex::Destroy ()
return 0; return 0;
} }
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 void
pthread_mutex::fixup_after_fork () pthread_mutex::fixup_after_fork ()
{ {
@ -1324,10 +1316,10 @@ pthread_mutex::fixup_after_fork ()
if (NULL == owner) if (NULL == owner)
/* mutex has no owner, reset to initial */ /* 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; 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); win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
if (!win32_obj_id) if (!win32_obj_id)
@ -2615,6 +2607,7 @@ __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
{ {
case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_ERRORCHECK:
case PTHREAD_MUTEX_RECURSIVE: case PTHREAD_MUTEX_RECURSIVE:
case PTHREAD_MUTEX_NORMAL:
(*attr)->mutextype = type; (*attr)->mutextype = type;
break; break;
default: default:

View File

@ -39,6 +39,8 @@ extern "C"
#else #else
#include <pthread.h> #include <pthread.h>
#include <limits.h>
#include <errno.h>
#include <signal.h> #include <signal.h>
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
@ -160,9 +162,9 @@ private:
#define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
#define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
#define SEM_MAGIC PTHREAD_MAGIC+7 #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 */ /* 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 isGoodInitializer (pthread_mutex_t const *);
static bool isGoodInitializerOrObject (pthread_mutex_t const *); static bool isGoodInitializerOrObject (pthread_mutex_t const *);
static bool isGoodInitializerOrBadObject (pthread_mutex_t const *mutex); static bool isGoodInitializerOrBadObject (pthread_mutex_t const *mutex);
static bool canBeUnlocked (pthread_mutex_t const *mutex);
static void initMutex (); static void initMutex ();
static int init (pthread_mutex_t *, const pthread_mutexattr_t *); static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
LONG lock_counter; unsigned long lock_counter;
HANDLE win32_obj_id; HANDLE win32_obj_id;
unsigned int recursion_counter; unsigned int recursion_counter;
LONG condwaits; LONG condwaits;
@ -316,12 +319,43 @@ public:
int pshared; int pshared;
class pthread_mutex * next; class pthread_mutex * next;
int Lock (); pthread_t GetPthreadSelf () const
int TryLock (); {
int UnLock (); return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
int Destroy (); ::pthread_self ();
void SetOwner (); }
int LockRecursive ();
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 (); void fixup_after_fork ();
pthread_mutex (pthread_mutexattr * = NULL); pthread_mutex (pthread_mutexattr * = NULL);
@ -329,6 +363,11 @@ public:
~pthread_mutex (); ~pthread_mutex ();
private: private:
int _Lock (pthread_t self);
int _TryLock (pthread_t self);
int _UnLock (pthread_t self);
int _Destroy (pthread_t self);
static nativeMutex mutexInitializationLock; static nativeMutex mutexInitializationLock;
}; };