* 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:
parent
dcd350f0ec
commit
2ff03dc2e0
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue