2001-12-26 Robert Collins <rbtcollins@hotmail.com>
* thread.cc (pthread_cond::Signal): Use a separate flag for signal detection and broadcast semantics. (__pthread_cond_dowait): Ditto. * thread.h (pthread_cond): New flag for testing when a waiter has woken.
This commit is contained in:
parent
7a0252e203
commit
cbce49804f
|
@ -1,3 +1,10 @@
|
||||||
|
2001-12-26 Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
|
* thread.cc (pthread_cond::Signal): Use a separate flag for signal detection
|
||||||
|
and broadcast semantics.
|
||||||
|
(__pthread_cond_dowait): Ditto.
|
||||||
|
* thread.h (pthread_cond): New flag for testing when a waiter has woken.
|
||||||
|
|
||||||
2001-12-26 Christopher Faylor <cgf@redhat.com>
|
2001-12-26 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
* Makefile.in: Quote arguments to shell scripts.
|
* Makefile.in: Quote arguments to shell scripts.
|
||||||
|
@ -116,6 +123,7 @@
|
||||||
* net.cc (cygwin_getsockopt): Dereference optlen pointer when passing
|
* net.cc (cygwin_getsockopt): Dereference optlen pointer when passing
|
||||||
to __check_null_invalid_struct_errno.
|
to __check_null_invalid_struct_errno.
|
||||||
|
|
||||||
|
>>>>>>> 1.1060
|
||||||
2001-12-03 Christopher Faylor <cgf@redhat.com>
|
2001-12-03 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
* net.cc (cygwin_getsockopt): Allow NULL optval.
|
* net.cc (cygwin_getsockopt): Allow NULL optval.
|
||||||
|
|
|
@ -499,24 +499,37 @@ pthread_cond::Signal ()
|
||||||
system_printf ("Failed to unlock condition variable access mutex, this %p", this);
|
system_printf ("Failed to unlock condition variable access mutex, this %p", this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* Prime the detection flag */
|
||||||
|
ExitingWait = 1;
|
||||||
|
/* Signal any waiting thread */
|
||||||
PulseEvent (win32_obj_id);
|
PulseEvent (win32_obj_id);
|
||||||
/* No one can start waiting until we release the condition access mutex */
|
/* No one can start waiting until we release the condition access mutex */
|
||||||
/* The released thread will decrement waiting when it gets a time slice...
|
/* The released thread will decrement waiting when it gets a time slice...
|
||||||
without waiting for the access mutex
|
without waiting for the access mutex
|
||||||
|
* InterLockedIncrement on 98 +, NT4 + returns the incremented value.
|
||||||
|
* On 95, nt 3.51 < it returns a sign correct number - 0=0, + for greater than 0, -
|
||||||
|
* for less than 0.
|
||||||
|
* Because of this we cannot spin on the waiting count, but rather we need a
|
||||||
|
* dedicated flag for a thread exiting the Wait function.
|
||||||
|
* Also not that Interlocked* sync CPU caches with memory.
|
||||||
*/
|
*/
|
||||||
int spins = 10;
|
int spins = 10;
|
||||||
while (InterlockedIncrement (&waiting) != (temp - 1) && spins)
|
/* When ExitingWait is nonzero after a decrement, the leaving thread has
|
||||||
|
* done it's thing
|
||||||
|
*/
|
||||||
|
while (InterlockedDecrement (&ExitingWait) == 0 && spins)
|
||||||
{
|
{
|
||||||
InterlockedDecrement (&waiting);
|
InterlockedIncrement (&ExitingWait);
|
||||||
/* give up the cpu to force a context switch. */
|
/* give up the cpu to force a context switch. */
|
||||||
Sleep (0);
|
Sleep (0);
|
||||||
if (spins == 5)
|
if (spins == 5)
|
||||||
/* we've had 5 timeslices, and the woekn thread still hasn't done it's
|
/* we've had 5 timeslices, and the woken thread still hasn't done it's
|
||||||
* thing - maybe we raced it with the event? */
|
* thing - maybe we raced it with the event? */
|
||||||
PulseEvent (win32_obj_id);
|
PulseEvent (win32_obj_id);
|
||||||
spins--;
|
spins--;
|
||||||
}
|
}
|
||||||
InterlockedDecrement (&waiting);
|
if (waiting + 1 != temp)
|
||||||
|
system_printf ("Released too many threads - %d now %d originally", waiting, temp);
|
||||||
if (pthread_mutex_unlock (&cond_access))
|
if (pthread_mutex_unlock (&cond_access))
|
||||||
system_printf ("Failed to unlock condition variable access mutex, this %p", this);
|
system_printf ("Failed to unlock condition variable access mutex, this %p", this);
|
||||||
}
|
}
|
||||||
|
@ -1782,6 +1795,8 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||||
bool last = false;
|
bool last = false;
|
||||||
if (InterlockedDecrement (&((*cond)->waiting)) == 0)
|
if (InterlockedDecrement (&((*cond)->waiting)) == 0)
|
||||||
last = true;
|
last = true;
|
||||||
|
/* Tell Signal that we have been released */
|
||||||
|
InterlockedDecrement (&((*cond)->ExitingWait));
|
||||||
(*themutex)->Lock ();
|
(*themutex)->Lock ();
|
||||||
if (last == true)
|
if (last == true)
|
||||||
(*cond)->mutex = NULL;
|
(*cond)->mutex = NULL;
|
||||||
|
|
|
@ -306,6 +306,7 @@ class pthread_cond:public verifyable_object
|
||||||
public:
|
public:
|
||||||
int shared;
|
int shared;
|
||||||
LONG waiting;
|
LONG waiting;
|
||||||
|
LONG ExitingWait;
|
||||||
pthread_mutex *mutex;
|
pthread_mutex *mutex;
|
||||||
/* to allow atomic behaviour for cond_broadcast */
|
/* to allow atomic behaviour for cond_broadcast */
|
||||||
pthread_mutex_t cond_access;
|
pthread_mutex_t cond_access;
|
||||||
|
|
Loading…
Reference in New Issue