* 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:
parent
161387a725
commit
3700578ee8
|
@ -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>
|
2010-02-09 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* cygtls.h (struct _cygtls): Remove unneeded elements.
|
* cygtls.h (struct _cygtls): Remove unneeded elements.
|
||||||
|
|
|
@ -955,11 +955,16 @@ _dll_crt0 ()
|
||||||
{
|
{
|
||||||
main_environ = user_data->envptr;
|
main_environ = user_data->envptr;
|
||||||
if (in_forkee)
|
if (in_forkee)
|
||||||
fork_info->alloc_stack ();
|
{
|
||||||
|
fork_info->alloc_stack ();
|
||||||
|
_main_tls = &_my_tls;
|
||||||
|
}
|
||||||
else
|
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);
|
_main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* thread.cc: Locking and threading module functions
|
/* thread.cc: Locking and threading module functions
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -187,9 +187,8 @@ pthread_mutex::can_be_unlocked (pthread_mutex_t const *mutex)
|
||||||
return false;
|
return false;
|
||||||
/* Check if the mutex is owned by the current thread and can be unlocked.
|
/* 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. */
|
* Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
|
||||||
return ((*mutex)->recursion_counter == 1
|
return (*mutex)->recursion_counter == 1
|
||||||
&& ((*mutex)->owner == MUTEX_OWNER_ANONYMOUS
|
&& pthread::equal ((*mutex)->owner, self);
|
||||||
|| pthread::equal ((*mutex)->owner, self)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -302,7 +301,7 @@ MTinterface::fixup_after_fork ()
|
||||||
void
|
void
|
||||||
pthread::init_mainthread ()
|
pthread::init_mainthread ()
|
||||||
{
|
{
|
||||||
pthread *thread = get_tls_self_pointer ();
|
pthread *thread = _my_tls.tid;
|
||||||
if (!thread)
|
if (!thread)
|
||||||
{
|
{
|
||||||
thread = new pthread ();
|
thread = new pthread ();
|
||||||
|
@ -325,7 +324,7 @@ pthread::init_mainthread ()
|
||||||
pthread *
|
pthread *
|
||||||
pthread::self ()
|
pthread::self ()
|
||||||
{
|
{
|
||||||
pthread *thread = get_tls_self_pointer ();
|
pthread *thread = _my_tls.tid;
|
||||||
if (!thread)
|
if (!thread)
|
||||||
{
|
{
|
||||||
thread = pthread_null::get_null_pthread ();
|
thread = pthread_null::get_null_pthread ();
|
||||||
|
@ -334,12 +333,6 @@ pthread::self ()
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread *
|
|
||||||
pthread::get_tls_self_pointer ()
|
|
||||||
{
|
|
||||||
return _my_tls.tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pthread::set_tls_self_pointer (pthread *thread)
|
pthread::set_tls_self_pointer (pthread *thread)
|
||||||
{
|
{
|
||||||
|
@ -1561,7 +1554,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
|
||||||
type (PTHREAD_MUTEX_ERRORCHECK),
|
type (PTHREAD_MUTEX_ERRORCHECK),
|
||||||
pshared (PTHREAD_PROCESS_PRIVATE)
|
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)
|
if (!win32_obj_id)
|
||||||
{
|
{
|
||||||
magic = 0;
|
magic = 0;
|
||||||
|
@ -1592,8 +1585,9 @@ pthread_mutex::~pthread_mutex ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_mutex::_lock (pthread_t self)
|
pthread_mutex::lock ()
|
||||||
{
|
{
|
||||||
|
pthread_t self = ::pthread_self ();
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (InterlockedIncrement ((long *)&lock_counter) == 1)
|
if (InterlockedIncrement ((long *)&lock_counter) == 1)
|
||||||
|
@ -1616,8 +1610,31 @@ pthread_mutex::_lock (pthread_t self)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
int result = 0;
|
||||||
|
|
||||||
if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
|
if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
|
||||||
|
@ -1631,31 +1648,9 @@ pthread_mutex::_trylock (pthread_t self)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_mutex::_unlock (pthread_t self)
|
pthread_mutex::destroy ()
|
||||||
{
|
{
|
||||||
if (!pthread::equal (owner, self))
|
if (condwaits || trylock ())
|
||||||
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))
|
|
||||||
// Do not destroy a condwaited or locked mutex
|
// Do not destroy a condwaited or locked mutex
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
else if (recursion_counter > 1)
|
else if (recursion_counter > 1)
|
||||||
|
@ -1683,7 +1678,7 @@ pthread_mutex::_fixup_after_fork ()
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
tid = 0xffffffff; /* Don't know the tid after a fork */
|
tid = 0xffffffff; /* Don't know the tid after a fork */
|
||||||
#endif
|
#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)
|
if (!win32_obj_id)
|
||||||
api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
|
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_mutexattr_t *attr,
|
||||||
const pthread_mutex_t initializer)
|
const pthread_mutex_t initializer)
|
||||||
{
|
{
|
||||||
pthread_mutex_t new_mutex;
|
|
||||||
|
|
||||||
if (attr && !pthread_mutexattr::is_good_object (attr))
|
if (attr && !pthread_mutexattr::is_good_object (attr))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
mutex_initialization_lock.lock ();
|
mutex_initialization_lock.lock ();
|
||||||
|
if (pthread_mutex::is_good_initializer (mutex))
|
||||||
new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
|
|
||||||
if (!is_good_object (&new_mutex))
|
|
||||||
{
|
{
|
||||||
delete new_mutex;
|
pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
|
||||||
mutex_initialization_lock.unlock ();
|
if (!is_good_object (&new_mutex))
|
||||||
return EAGAIN;
|
{
|
||||||
}
|
delete new_mutex;
|
||||||
|
mutex_initialization_lock.unlock ();
|
||||||
|
return EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!attr && initializer)
|
if (!attr && initializer)
|
||||||
{
|
{
|
||||||
if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
|
if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
|
||||||
new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
|
new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
|
||||||
else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
|
else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
|
||||||
new_mutex->type = PTHREAD_MUTEX_NORMAL;
|
new_mutex->type = PTHREAD_MUTEX_NORMAL;
|
||||||
else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
|
else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
|
||||||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
myfault efault;
|
myfault efault;
|
||||||
if (efault.faulted ())
|
if (efault.faulted ())
|
||||||
{
|
{
|
||||||
delete new_mutex;
|
delete new_mutex;
|
||||||
mutex_initialization_lock.unlock ();
|
mutex_initialization_lock.unlock ();
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*mutex = new_mutex;
|
*mutex = new_mutex;
|
||||||
|
}
|
||||||
mutex_initialization_lock.unlock ();
|
mutex_initialization_lock.unlock ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* thread.h: Locking and threading module definitions
|
/* thread.h: Locking and threading module definitions
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
|
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.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -57,10 +57,10 @@ public:
|
||||||
bool init ()
|
bool init ()
|
||||||
{
|
{
|
||||||
lock_counter = 0;
|
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)
|
if (!win32_obj_id)
|
||||||
{
|
{
|
||||||
debug_printf ("CreateSemaphore failed. %E");
|
debug_printf ("CreateEvent failed. %E");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
void unlock ()
|
void unlock ()
|
||||||
{
|
{
|
||||||
if (InterlockedDecrement ((long *) &lock_counter))
|
if (InterlockedDecrement ((long *) &lock_counter))
|
||||||
::ReleaseSemaphore (win32_obj_id, 1, NULL);
|
::SetEvent (win32_obj_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -285,29 +285,10 @@ public:
|
||||||
int type;
|
int type;
|
||||||
int pshared;
|
int pshared;
|
||||||
|
|
||||||
pthread_t get_pthread_self () const
|
int lock ();
|
||||||
{
|
int trylock ();
|
||||||
return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
|
int unlock ();
|
||||||
::pthread_self ();
|
int destroy ();
|
||||||
}
|
|
||||||
|
|
||||||
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 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_owner (pthread_t self)
|
void set_owner (pthread_t self)
|
||||||
{
|
{
|
||||||
recursion_counter = 1;
|
recursion_counter = 1;
|
||||||
|
@ -337,11 +318,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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 ();
|
void _fixup_after_fork ();
|
||||||
|
|
||||||
static List<pthread_mutex> mutexes;
|
static List<pthread_mutex> mutexes;
|
||||||
|
@ -446,7 +422,6 @@ private:
|
||||||
void precreate (pthread_attr *);
|
void precreate (pthread_attr *);
|
||||||
void postcreate ();
|
void postcreate ();
|
||||||
bool create_cancel_event ();
|
bool create_cancel_event ();
|
||||||
static pthread *get_tls_self_pointer ();
|
|
||||||
static void set_tls_self_pointer (pthread *);
|
static void set_tls_self_pointer (pthread *);
|
||||||
void cancel_self ();
|
void cancel_self ();
|
||||||
DWORD get_thread_id ();
|
DWORD get_thread_id ();
|
||||||
|
|
Loading…
Reference in New Issue