* cygwin.din (pthread_spin_destroy): Export.
(pthread_spin_init): Export. (pthread_spin_lock): Export. (pthread_spin_trylock): Export. (pthread_spin_unlock): Export. * posix.sgml (std-susv4): Add pthread_spin_destroy, pthread_spin_init, pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock. (std-notimpl): Remove pthread_spin_[...]. * pthread.cc (pthread_spin_init): New function. * thread.cc (pthread_spinlock::is_good_object): New function. (pthread_mutex::pthread_mutex): Rearrange initializers to accommodate protected data in pthread_mutex. (pthread_spinlock::pthread_spinlock): New constructor. (pthread_spinlock::lock): New method. (pthread_spinlock::unlock): New method. (pthread_spinlock::init): New method. (pthread_spin_lock): New function. (pthread_spin_trylock): New function. (pthread_spin_unlock): New function. (pthread_spin_destroy): New function. * thread.h (PTHREAD_SPINLOCK_MAGIC): Define. (class pthread_mutex): Change access level of members shared with derived classes to protected. (pthread_mutex::set_shared): New protected method. (class pthread_spinlock): New class, derived class of pthread_mutex. * include/pthread.h (pthread_spin_destroy): Declare. (pthread_spin_init): Declare. (pthread_spin_lock): Declare. (pthread_spin_trylock): Declare. (pthread_spin_unlock): Declare. * include/cygwin/types.h (pthread_spinlock_t): New typedef. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
This commit is contained in:
parent
a011f95216
commit
f00fe1b8e7
winsup/cygwin
|
@ -1,3 +1,38 @@
|
|||
2011-03-29 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygwin.din (pthread_spin_destroy): Export.
|
||||
(pthread_spin_init): Export.
|
||||
(pthread_spin_lock): Export.
|
||||
(pthread_spin_trylock): Export.
|
||||
(pthread_spin_unlock): Export.
|
||||
* posix.sgml (std-susv4): Add pthread_spin_destroy, pthread_spin_init,
|
||||
pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock.
|
||||
(std-notimpl): Remove pthread_spin_[...].
|
||||
* pthread.cc (pthread_spin_init): New function.
|
||||
* thread.cc (pthread_spinlock::is_good_object): New function.
|
||||
(pthread_mutex::pthread_mutex): Rearrange initializers to accommodate
|
||||
protected data in pthread_mutex.
|
||||
(pthread_spinlock::pthread_spinlock): New constructor.
|
||||
(pthread_spinlock::lock): New method.
|
||||
(pthread_spinlock::unlock): New method.
|
||||
(pthread_spinlock::init): New method.
|
||||
(pthread_spin_lock): New function.
|
||||
(pthread_spin_trylock): New function.
|
||||
(pthread_spin_unlock): New function.
|
||||
(pthread_spin_destroy): New function.
|
||||
* thread.h (PTHREAD_SPINLOCK_MAGIC): Define.
|
||||
(class pthread_mutex): Change access level of members shared with
|
||||
derived classes to protected.
|
||||
(pthread_mutex::set_shared): New protected method.
|
||||
(class pthread_spinlock): New class, derived class of pthread_mutex.
|
||||
* include/pthread.h (pthread_spin_destroy): Declare.
|
||||
(pthread_spin_init): Declare.
|
||||
(pthread_spin_lock): Declare.
|
||||
(pthread_spin_trylock): Declare.
|
||||
(pthread_spin_unlock): Declare.
|
||||
* include/cygwin/types.h (pthread_spinlock_t): New typedef.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
||||
2011-03-29 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* net.cc (SIO_BASE_HANDLE): Define.
|
||||
|
|
|
@ -1244,6 +1244,11 @@ pthread_setschedparam SIGFE
|
|||
pthread_setspecific SIGFE
|
||||
pthread_sigmask SIGFE
|
||||
pthread_suspend SIGFE
|
||||
pthread_spin_destroy SIGFE
|
||||
pthread_spin_init SIGFE
|
||||
pthread_spin_lock SIGFE
|
||||
pthread_spin_trylock SIGFE
|
||||
pthread_spin_unlock SIGFE
|
||||
pthread_testcancel SIGFE
|
||||
pthread_yield = sched_yield SIGFE
|
||||
ptsname SIGFE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* types.h
|
||||
|
||||
Copyright 2001, 2002, 2003, 2005, 2006, 2010 Red Hat Inc.
|
||||
Copyright 2001, 2002, 2003, 2005, 2006, 2010, 2011 Red Hat Inc.
|
||||
Written by Robert Collins <rbtcollins@hotmail.com>
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
@ -195,6 +195,7 @@ typedef struct
|
|||
int state;
|
||||
}
|
||||
pthread_once_t;
|
||||
typedef struct __pthread_spinlock_t {char __dummy;} *pthread_spinlock_t;
|
||||
typedef struct __pthread_rwlock_t {char __dummy;} *pthread_rwlock_t;
|
||||
typedef struct __pthread_rwlockattr_t {char __dummy;} *pthread_rwlockattr_t;
|
||||
|
||||
|
@ -210,6 +211,7 @@ typedef class pthread_mutexattr *pthread_mutexattr_t;
|
|||
typedef class pthread_condattr *pthread_condattr_t;
|
||||
typedef class pthread_cond *pthread_cond_t;
|
||||
typedef class pthread_once pthread_once_t;
|
||||
typedef class pthread_spinlock *pthread_spinlock_t;
|
||||
typedef class pthread_rwlock *pthread_rwlock_t;
|
||||
typedef class pthread_rwlockattr *pthread_rwlockattr_t;
|
||||
|
||||
|
|
|
@ -401,12 +401,14 @@ details. */
|
|||
235: Export madvise.
|
||||
236: Export pthread_yield, __xpg_strerror_r.
|
||||
237: Export strchrnul.
|
||||
238: Export pthread_spin_destroy, pthread_spin_init, pthread_spin_lock,
|
||||
pthread_spin_trylock, pthread_spin_unlock.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 237
|
||||
#define CYGWIN_VERSION_API_MINOR 238
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -162,6 +162,13 @@ int pthread_mutexattr_setprotocol (pthread_mutexattr_t *, int);
|
|||
int pthread_mutexattr_setpshared (pthread_mutexattr_t *, int);
|
||||
int pthread_mutexattr_settype (pthread_mutexattr_t *, int);
|
||||
|
||||
/* Spinlocks */
|
||||
int pthread_spin_destroy (pthread_spinlock_t *);
|
||||
int pthread_spin_init (pthread_spinlock_t *, int);
|
||||
int pthread_spin_lock (pthread_spinlock_t *);
|
||||
int pthread_spin_trylock (pthread_spinlock_t *);
|
||||
int pthread_spin_unlock (pthread_spinlock_t *);
|
||||
|
||||
/* RW Locks */
|
||||
int pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
|
||||
int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
|
||||
|
|
|
@ -600,6 +600,11 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
pthread_setschedparam
|
||||
pthread_setspecific
|
||||
pthread_sigmask
|
||||
pthread_spin_destroy
|
||||
pthread_spin_init
|
||||
pthread_spin_lock
|
||||
pthread_spin_trylock
|
||||
pthread_spin_unlock
|
||||
pthread_testcancel
|
||||
ptsname
|
||||
putc
|
||||
|
@ -1384,7 +1389,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
pthread_rwlock_timedrdlock
|
||||
pthread_rwlock_timedwrlock
|
||||
pthread_setschedprio
|
||||
pthread_spin_[...]
|
||||
putmsg
|
||||
reminderl
|
||||
remquol
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pthread.cc: posix pthread interface for Cygwin
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007 Red Hat, Inc.
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2011 Red Hat, Inc.
|
||||
|
||||
Originally written by Marco Fuykschot <marco@ddi.nl>
|
||||
|
||||
|
@ -91,6 +91,14 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)
|
|||
return pthread_mutex::init (mutex, attr, NULL);
|
||||
}
|
||||
|
||||
/* Spinlocks */
|
||||
int
|
||||
pthread_spin_init (pthread_spinlock_t *spinlock, int pshared)
|
||||
{
|
||||
return pthread_spinlock::init (spinlock, pshared);
|
||||
}
|
||||
|
||||
|
||||
/* Synchronisation */
|
||||
int
|
||||
pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* thread.cc: Locking and threading module functions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -173,6 +173,14 @@ pthread_key::is_good_object (pthread_key_t const *key)
|
|||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
pthread_spinlock::is_good_object (pthread_spinlock_t const *mutex)
|
||||
{
|
||||
if (verifyable_object_isvalid (mutex, PTHREAD_SPINLOCK_MAGIC) != VALID_OBJECT)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
pthread_mutex::is_good_object (pthread_mutex_t const *mutex)
|
||||
{
|
||||
|
@ -1547,11 +1555,11 @@ pthread_mutex::init_mutex ()
|
|||
pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
|
||||
verifyable_object (0), /* set magic to zero initially */
|
||||
lock_counter (0),
|
||||
win32_obj_id (NULL), recursion_counter (0),
|
||||
condwaits (0), owner (_new_mutex),
|
||||
win32_obj_id (NULL), owner (_new_mutex),
|
||||
#ifdef DEBUGGING
|
||||
tid (0),
|
||||
#endif
|
||||
recursion_counter (0), condwaits (0),
|
||||
type (PTHREAD_MUTEX_ERRORCHECK),
|
||||
pshared (PTHREAD_PROCESS_PRIVATE)
|
||||
{
|
||||
|
@ -1701,6 +1709,65 @@ pthread_mutexattr::~pthread_mutexattr ()
|
|||
{
|
||||
}
|
||||
|
||||
/* pshared spinlocks
|
||||
|
||||
The infrastructure is provided by the underlying pthread_mutex class.
|
||||
The rest is a simplification implementing spin locking. */
|
||||
|
||||
pthread_spinlock::pthread_spinlock (int pshared) :
|
||||
pthread_mutex (NULL)
|
||||
{
|
||||
magic = PTHREAD_SPINLOCK_MAGIC;
|
||||
set_type (PTHREAD_MUTEX_NORMAL);
|
||||
set_shared (pshared);
|
||||
}
|
||||
|
||||
int
|
||||
pthread_spinlock::lock ()
|
||||
{
|
||||
pthread_t self = ::pthread_self ();
|
||||
int result = -1;
|
||||
|
||||
do
|
||||
{
|
||||
if (InterlockedExchange ((long *) &lock_counter, 1) == 0)
|
||||
{
|
||||
set_owner (self);
|
||||
result = 0;
|
||||
}
|
||||
else if (pthread::equal (owner, self))
|
||||
result = EDEADLK;
|
||||
else /* Minimal timeout to minimize CPU usage while still spinning. */
|
||||
cancelable_wait (win32_obj_id, 1L, cw_no_cancel, cw_sig_resume);
|
||||
}
|
||||
while (result == -1);
|
||||
pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_spinlock::unlock ()
|
||||
{
|
||||
pthread_t self = ::pthread_self ();
|
||||
int result = 0;
|
||||
|
||||
if (!pthread::equal (owner, self))
|
||||
result = EPERM;
|
||||
else
|
||||
{
|
||||
owner = (pthread_t) _unlocked_mutex;
|
||||
#ifdef DEBUGGING
|
||||
tid = 0;
|
||||
#endif
|
||||
InterlockedExchange ((long *) &lock_counter, 0);
|
||||
::SetEvent (win32_obj_id);
|
||||
result = 0;
|
||||
}
|
||||
pthread_printf ("spinlock %p, owner %p, self %p, res %d",
|
||||
this, owner, self, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD WINAPI
|
||||
pthread::thread_init_wrapper (void *arg)
|
||||
{
|
||||
|
@ -2768,6 +2835,63 @@ pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
|
|||
return ENOSYS;
|
||||
}
|
||||
|
||||
/* Spinlocks */
|
||||
|
||||
int
|
||||
pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
|
||||
{
|
||||
pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
|
||||
if (!is_good_object (&new_spinlock))
|
||||
{
|
||||
delete new_spinlock;
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
{
|
||||
delete new_spinlock;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*spinlock = new_spinlock;
|
||||
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_spin_lock (pthread_spinlock_t *spinlock)
|
||||
{
|
||||
if (!pthread_spinlock::is_good_object (spinlock))
|
||||
return EINVAL;
|
||||
return (*spinlock)->lock ();
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_spin_trylock (pthread_spinlock_t *spinlock)
|
||||
{
|
||||
if (!pthread_spinlock::is_good_object (spinlock))
|
||||
return EINVAL;
|
||||
return (*spinlock)->trylock ();
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_spin_unlock (pthread_spinlock_t *spinlock)
|
||||
{
|
||||
if (!pthread_spinlock::is_good_object (spinlock))
|
||||
return EINVAL;
|
||||
return (*spinlock)->unlock ();
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_spin_destroy (pthread_spinlock_t *spinlock)
|
||||
{
|
||||
if (!pthread_spinlock::is_good_object (spinlock))
|
||||
return EINVAL;
|
||||
return (*spinlock)->destroy ();
|
||||
}
|
||||
|
||||
/* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
|
||||
for more detail */
|
||||
extern "C" int
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* thread.h: Locking and threading module definitions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
2008, 2009, 2010 Red Hat, Inc.
|
||||
2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -98,6 +98,7 @@ class pinfo;
|
|||
#define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
|
||||
#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
|
||||
#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
|
||||
#define PTHREAD_SPINLOCK_MAGIC PTHREAD_MAGIC+11
|
||||
|
||||
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
|
||||
|
||||
|
@ -303,18 +304,15 @@ public:
|
|||
mutexes.for_each (&pthread_mutex::_fixup_after_fork);
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
unsigned long lock_counter;
|
||||
HANDLE win32_obj_id;
|
||||
unsigned int recursion_counter;
|
||||
LONG condwaits;
|
||||
pthread_t owner;
|
||||
#ifdef DEBUGGING
|
||||
DWORD tid; /* the thread id of the owner */
|
||||
#endif
|
||||
int type;
|
||||
int pshared;
|
||||
|
||||
void set_shared (int in_shared) { pshared = in_shared; }
|
||||
void set_owner (pthread_t self)
|
||||
{
|
||||
recursion_counter = 1;
|
||||
|
@ -323,10 +321,17 @@ private:
|
|||
tid = GetCurrentThreadId ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static const pthread_t _new_mutex;
|
||||
static const pthread_t _unlocked_mutex;
|
||||
static const pthread_t _destroyed_mutex;
|
||||
|
||||
private:
|
||||
unsigned int recursion_counter;
|
||||
LONG condwaits;
|
||||
int type;
|
||||
int pshared;
|
||||
|
||||
bool no_owner ();
|
||||
void _fixup_after_fork ();
|
||||
|
||||
|
@ -335,6 +340,18 @@ private:
|
|||
friend class pthread_cond;
|
||||
};
|
||||
|
||||
class pthread_spinlock: public pthread_mutex
|
||||
{
|
||||
public:
|
||||
static bool is_good_object (pthread_spinlock_t const *);
|
||||
static int init (pthread_spinlock_t *, int);
|
||||
|
||||
int lock ();
|
||||
int unlock ();
|
||||
|
||||
pthread_spinlock (int);
|
||||
};
|
||||
|
||||
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
||||
#define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
|
||||
|
||||
|
|
Loading…
Reference in New Issue