Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-03-29 14:32:40 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-03-29 14:32:40 +0400
commitf00fe1b8e7bf295a0ca87ac472ead52f50037c09 (patch)
treef1d4a471ad96ee75a652778d692ab6360cd7dc22 /winsup
parenta011f952168ce0219b64c6f0a9dc6a01f86e77c6 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog35
-rw-r--r--winsup/cygwin/cygwin.din5
-rw-r--r--winsup/cygwin/include/cygwin/types.h4
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/include/pthread.h7
-rw-r--r--winsup/cygwin/posix.sgml6
-rw-r--r--winsup/cygwin/pthread.cc10
-rw-r--r--winsup/cygwin/thread.cc130
-rw-r--r--winsup/cygwin/thread.h29
9 files changed, 217 insertions, 13 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0c1a61075..fc9aac203 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,40 @@
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.
(fdsock): If we got an LSP handle, try to create a copy of the base
handle instead. Change comment to explain.
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index e1dcea75b..10565adeb 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -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
diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h
index a202d958d..efc076a45 100644
--- a/winsup/cygwin/include/cygwin/types.h
+++ b/winsup/cygwin/include/cygwin/types.h
@@ -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;
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 91c3c53d9..58c55f6e3 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -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
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 8e35808e1..10a53f3fd 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -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);
diff --git a/winsup/cygwin/posix.sgml b/winsup/cygwin/posix.sgml
index 393a2bcb7..53e760633 100644
--- a/winsup/cygwin/posix.sgml
+++ b/winsup/cygwin/posix.sgml
@@ -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
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index 18f2aea5d..3dddf48b1 100644
--- a/winsup/cygwin/pthread.cc
+++ b/winsup/cygwin/pthread.cc
@@ -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)
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 891b43fb9..29674d4ed 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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.
@@ -174,6 +174,14 @@ pthread_key::is_good_object (pthread_key_t const *key)
}
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)
{
if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
@@ -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
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index bea8e2aa3..f96714f49 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -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)