* 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:
Corinna Vinschen 2011-03-29 10:32:40 +00:00
parent a011f95216
commit f00fe1b8e7
9 changed files with 217 additions and 13 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)