Re: gthread-win32.c



Kaz Kylheku wrote:


Also, one problem here is that if you want to use priorities, the
waiting thread better not have a higher priority than the manager,
because it's then not possible to give up a timeslice to it. The while
loop will lock out the manager. So for priority support, the
manager must have a equal or higher priority than any other thread
which uses wait_for_event().

Hadn't thought of that (obviously). ;)


Events have a ``set'' state which remembers the signal. So if a thread
is removed from the queue and its event is fired before it has reached
the wait operation, the event stays set.  Then when the thread finally
executes the wait, it will fall through, thereby resetting the event.
So the atomicity of giving up the queue lock and suspending is glued
together by the stateful nature of the event.

Ah.  Somehow I was thinking that auto-reset events behaved like pulses.
My bad.


Where things get a little tricky is in handling wakeups due to timeout.
This case can must be detected and then the queue must be dealt with.
The woken thread looks for itself in the queue. If it is no longer on
the queue, then some other thread must have succeeded in dequeueing it,
and hence the auto-reset event is going to be signaled soon, if indeed
it has not already.  If the thread doesn't consume that signal right
away with an extra wait operation, it will get a spurious wakeup later.
If you allow for such spurious wakeups, then you have to check the
queue after each wait, timed out or not, since it can't be assumed that
the thread has been dequeued when the event is fired.

Ok.  I think I understand now.

This method solves the basic events, including wake-one or
wake-all.

Can it also be applied to g_cond_wait?

On NT, we could use SignalObjectAndWait:
	g_cond_wait(cond, mutex)
	1. lock cond->mutex
	2. add this thread to cond->queue
	3. release cond->mutex
	4. SignalObjectAndWait(mutex, this_thread->event, INFINITE,
FALSE)
	5. lock mutex

There is not a race condition between 3 and 4, because if
this_thread->event is set, it will stay set.

There is a race condition between 4 and 5, but looking at the SUSv2, it
looks like a non-guaranteed area.

From SUSv2:
These functions atomically release mutex and cause the calling thread to
block on the condition variable cond; atomically here means "atomically
with respect to access by another thread to the mutex and then the
condition variable"...Upon successful return, the mutex has been locked
and is owned by the calling thread [i.e. SUSv2 only claims the
release-and-wait is atomic].

But, can something be worked out for 9x to replace SignalObjectAndWait,
which should be atomic?
	
Steven





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]