From a3db0b1cf7ce5b8f71f403c69cea9b92c3eba59d Mon Sep 17 00:00:00 2001 From: cgf Date: Wed, 10 Feb 2010 07:25:25 +0000 Subject: [PATCH] * dcrt0.cc (_dll_crt0): Set _main_tls as early as possible. * thread.cc (pthread_mutex::can_be_unlocked): Remove check for MUTEX_OWNER_ANONYMOUS since it is racy and unsafe. (pthread::init_mainthread): Initialize thread directly from _my_tls. (pthread::self): Ditto. (pthread::get_tls_self_pointer): Delete. (pthread_mutex::pthread_mutex): Use an event rather than a semaphore. (pthread_mutex::lock): Rename from _. Derive self directly. (pthread_mutex::tryunlock): Ditto. (pthread_mutex::destroy): Ditto. (pthread_mutex::unlock): Ditto. Accommodate change from semaphore to event. (pthread_mutex::_fixup_after_fork): Accommodate change from semaphore to event. (pthread_mutex::init): Don't attempt to initialize a semaphore unless it is in an initialized state. Do this check under mutex_initialization_lock.lock * thread.h (fast_mutex::init): Use event rather than semaphore. (fast_mutex::lock): Ditto. (pthread_mutex::_lock): Delete. (pthread_mutex::_unlock): Ditto. (pthread_mutex::_trylock): Ditto. (pthread_mutex::_destroy): Ditto. (pthread_mutex::get_pthread_self): Ditto. (pthread_mutex::get_tls_self_pointer): Ditto. (pthread_mutex::lock): Un-inline. (pthread_mutex::unlock): Ditto. (pthread_mutex::trylock): Ditto. (pthread_mutex::destroy): Ditto. --- winsup/cygwin/ChangeLog | 32 +++++++++++++ winsup/cygwin/dcrt0.cc | 11 +++-- winsup/cygwin/thread.cc | 117 +++++++++++++++++++++++------------------------- winsup/cygwin/thread.h | 41 ++++------------- 4 files changed, 104 insertions(+), 97 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 2469ee1bd9..72aff2e478 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,35 @@ +2010-02-10 Christopher Faylor + + * dcrt0.cc (_dll_crt0): Set _main_tls as early as possible. + * thread.cc (pthread_mutex::can_be_unlocked): Remove check for + MUTEX_OWNER_ANONYMOUS since it is racy and unsafe. + (pthread::init_mainthread): Initialize thread directly from _my_tls. + (pthread::self): Ditto. + (pthread::get_tls_self_pointer): Delete. + (pthread_mutex::pthread_mutex): Use an event rather than a semaphore. + (pthread_mutex::lock): Rename from _. Derive self directly. + (pthread_mutex::tryunlock): Ditto. + (pthread_mutex::destroy): Ditto. + (pthread_mutex::unlock): Ditto. Accommodate change from semaphore to + event. + (pthread_mutex::_fixup_after_fork): Accommodate change from semaphore + to event. + (pthread_mutex::init): Don't attempt to initialize a semaphore unless + it is in an initialized state. Do this check under + mutex_initialization_lock.lock + * thread.h (fast_mutex::init): Use event rather than semaphore. + (fast_mutex::lock): Ditto. + (pthread_mutex::_lock): Delete. + (pthread_mutex::_unlock): Ditto. + (pthread_mutex::_trylock): Ditto. + (pthread_mutex::_destroy): Ditto. + (pthread_mutex::get_pthread_self): Ditto. + (pthread_mutex::get_tls_self_pointer): Ditto. + (pthread_mutex::lock): Un-inline. + (pthread_mutex::unlock): Ditto. + (pthread_mutex::trylock): Ditto. + (pthread_mutex::destroy): Ditto. + 2010-02-09 Christopher Faylor * cygtls.h (struct _cygtls): Remove unneeded elements. diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 7cd383bf7c..6745f096e7 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -955,11 +955,16 @@ _dll_crt0 () { main_environ = user_data->envptr; if (in_forkee) - fork_info->alloc_stack (); + { + fork_info->alloc_stack (); + _main_tls = &_my_tls; + } else - __sinit (_impure_ptr); + { + _main_tls = &_my_tls; + __sinit (_impure_ptr); + } - _main_tls = &_my_tls; _main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL); } diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 98ffde24fb..16f6ed1608 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 Red Hat, Inc. + 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -187,9 +187,8 @@ pthread_mutex::can_be_unlocked (pthread_mutex_t const *mutex) return false; /* Check if the mutex is owned by the current thread and can be unlocked. * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */ - return ((*mutex)->recursion_counter == 1 - && ((*mutex)->owner == MUTEX_OWNER_ANONYMOUS - || pthread::equal ((*mutex)->owner, self))); + return (*mutex)->recursion_counter == 1 + && pthread::equal ((*mutex)->owner, self); } inline bool @@ -302,7 +301,7 @@ MTinterface::fixup_after_fork () void pthread::init_mainthread () { - pthread *thread = get_tls_self_pointer (); + pthread *thread = _my_tls.tid; if (!thread) { thread = new pthread (); @@ -325,7 +324,7 @@ pthread::init_mainthread () pthread * pthread::self () { - pthread *thread = get_tls_self_pointer (); + pthread *thread = _my_tls.tid; if (!thread) { thread = pthread_null::get_null_pthread (); @@ -334,12 +333,6 @@ pthread::self () return thread; } -pthread * -pthread::get_tls_self_pointer () -{ - return _my_tls.tid; -} - void pthread::set_tls_self_pointer (pthread *thread) { @@ -1561,7 +1554,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) : type (PTHREAD_MUTEX_ERRORCHECK), pshared (PTHREAD_PROCESS_PRIVATE) { - win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); + win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL); if (!win32_obj_id) { magic = 0; @@ -1592,8 +1585,9 @@ pthread_mutex::~pthread_mutex () } int -pthread_mutex::_lock (pthread_t self) +pthread_mutex::lock () { + pthread_t self = ::pthread_self (); int result = 0; if (InterlockedIncrement ((long *)&lock_counter) == 1) @@ -1616,23 +1610,9 @@ pthread_mutex::_lock (pthread_t self) } int -pthread_mutex::_trylock (pthread_t self) -{ - int result = 0; - - if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0) - set_owner (self); - else if (type == PTHREAD_MUTEX_RECURSIVE && pthread::equal (owner, self)) - result = lock_recursive (); - else - result = EBUSY; - - return result; -} - -int -pthread_mutex::_unlock (pthread_t self) +pthread_mutex::unlock () { + pthread_t self = ::pthread_self (); if (!pthread::equal (owner, self)) return EPERM; @@ -1645,17 +1625,32 @@ pthread_mutex::_unlock (pthread_t self) tid = 0; #endif if (InterlockedDecrement ((long *) &lock_counter)) - // Another thread is waiting - ::ReleaseSemaphore (win32_obj_id, 1, NULL); + ::SetEvent (win32_obj_id); // Another thread may be waiting } return 0; } int -pthread_mutex::_destroy (pthread_t self) +pthread_mutex::trylock () +{ + pthread_t self = ::pthread_self (); + int result = 0; + + if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0) + set_owner (self); + else if (type == PTHREAD_MUTEX_RECURSIVE && pthread::equal (owner, self)) + result = lock_recursive (); + else + result = EBUSY; + + return result; +} + +int +pthread_mutex::destroy () { - if (condwaits || _trylock (self)) + if (condwaits || trylock ()) // Do not destroy a condwaited or locked mutex return EBUSY; else if (recursion_counter > 1) @@ -1683,7 +1678,7 @@ pthread_mutex::_fixup_after_fork () #ifdef DEBUGGING tid = 0xffffffff; /* Don't know the tid after a fork */ #endif - win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); + win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL); if (!win32_obj_id) api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex"); } @@ -2665,40 +2660,40 @@ pthread_mutex::init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, const pthread_mutex_t initializer) { - pthread_mutex_t new_mutex; - if (attr && !pthread_mutexattr::is_good_object (attr)) return EINVAL; mutex_initialization_lock.lock (); - - new_mutex = new pthread_mutex (attr ? (*attr) : NULL); - if (!is_good_object (&new_mutex)) + if (pthread_mutex::is_good_initializer (mutex)) { - delete new_mutex; - mutex_initialization_lock.unlock (); - return EAGAIN; - } + pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL); + if (!is_good_object (&new_mutex)) + { + delete new_mutex; + mutex_initialization_lock.unlock (); + return EAGAIN; + } - if (!attr && initializer) - { - if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) - new_mutex->type = PTHREAD_MUTEX_RECURSIVE; - else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP) - new_mutex->type = PTHREAD_MUTEX_NORMAL; - else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) - new_mutex->type = PTHREAD_MUTEX_ERRORCHECK; - } + if (!attr && initializer) + { + if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) + new_mutex->type = PTHREAD_MUTEX_RECURSIVE; + else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP) + new_mutex->type = PTHREAD_MUTEX_NORMAL; + else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) + new_mutex->type = PTHREAD_MUTEX_ERRORCHECK; + } - myfault efault; - if (efault.faulted ()) - { - delete new_mutex; - mutex_initialization_lock.unlock (); - return EINVAL; - } + myfault efault; + if (efault.faulted ()) + { + delete new_mutex; + mutex_initialization_lock.unlock (); + return EINVAL; + } - *mutex = new_mutex; + *mutex = new_mutex; + } mutex_initialization_lock.unlock (); return 0; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 04869f7638..21d278dae8 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 Red Hat, Inc. + 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -57,10 +57,10 @@ public: bool init () { lock_counter = 0; - win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); + win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL); if (!win32_obj_id) { - debug_printf ("CreateSemaphore failed. %E"); + debug_printf ("CreateEvent failed. %E"); return false; } return true; @@ -75,7 +75,7 @@ public: void unlock () { if (InterlockedDecrement ((long *) &lock_counter)) - ::ReleaseSemaphore (win32_obj_id, 1, NULL); + ::SetEvent (win32_obj_id); } private: @@ -285,29 +285,10 @@ public: int type; int pshared; - pthread_t get_pthread_self () const - { - return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS : - ::pthread_self (); - } - - int lock () - { - return _lock (get_pthread_self ()); - } - int trylock () - { - return _trylock (get_pthread_self ()); - } - int unlock () - { - return _unlock (get_pthread_self ()); - } - int destroy () - { - return _destroy (get_pthread_self ()); - } - + int lock (); + int trylock (); + int unlock (); + int destroy (); void set_owner (pthread_t self) { recursion_counter = 1; @@ -337,11 +318,6 @@ public: } private: - int _lock (pthread_t self); - int _trylock (pthread_t self); - int _unlock (pthread_t self); - int _destroy (pthread_t self); - void _fixup_after_fork (); static List mutexes; @@ -446,7 +422,6 @@ private: void precreate (pthread_attr *); void postcreate (); bool create_cancel_event (); - static pthread *get_tls_self_pointer (); static void set_tls_self_pointer (pthread *); void cancel_self (); DWORD get_thread_id (); -- 2.11.0