* 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 _<func>.  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.
This commit is contained in:
Christopher Faylor 2010-02-10 07:25:26 +00:00
parent 161387a725
commit 3700578ee8
4 changed files with 109 additions and 102 deletions

View File

@ -1,3 +1,35 @@
2010-02-10 Christopher Faylor <me+cygwin@cgf.cx>
* 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 _<func>. 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 <me+cygwin@cgf.cx>
* cygtls.h (struct _cygtls): Remove unneeded elements.

View File

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

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 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,8 +1610,31 @@ pthread_mutex::_lock (pthread_t self)
}
int
pthread_mutex::_trylock (pthread_t self)
pthread_mutex::unlock ()
{
pthread_t self = ::pthread_self ();
if (!pthread::equal (owner, self))
return EPERM;
/* Don't try to unlock anything if recursion_counter == 0 initially.
That means that we've forked. */
if (recursion_counter > 0 && --recursion_counter == 0)
{
owner = NULL;
#ifdef DEBUGGING
tid = 0;
#endif
if (InterlockedDecrement ((long *) &lock_counter))
::SetEvent (win32_obj_id); // Another thread may be waiting
}
return 0;
}
int
pthread_mutex::trylock ()
{
pthread_t self = ::pthread_self ();
int result = 0;
if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
@ -1631,31 +1648,9 @@ pthread_mutex::_trylock (pthread_t self)
}
int
pthread_mutex::_unlock (pthread_t self)
pthread_mutex::destroy ()
{
if (!pthread::equal (owner, self))
return EPERM;
/* Don't try to unlock anything if recursion_counter == 0 initially.
That means that we've forked. */
if (recursion_counter > 0 && --recursion_counter == 0)
{
owner = NULL;
#ifdef DEBUGGING
tid = 0;
#endif
if (InterlockedDecrement ((long *) &lock_counter))
// Another thread is waiting
::ReleaseSemaphore (win32_obj_id, 1, NULL);
}
return 0;
}
int
pthread_mutex::_destroy (pthread_t self)
{
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;

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 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<pthread_mutex> 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 ();