[comp.os.mach] timeout on condition_wait

erich@kgw2.bwi.WEC.COM (Eric Hammond) (02/17/90)

Suppose cthread T1 begins waiting on a condition C1.
The condition may be signalled by cthread S within n1 seconds,
but, if it isn't, I want cthread T1 to stop waiting and continue
processing.  In other words:

===> I want to do a condition_wait() with a timeout. <===

[ The rest of this message gives further details about my
  particular application.  Any suggestions on how to do the above
  are welcomed, even if the following doesn't make sense to you. ]

Complicate this by the fact that there may be m cthreads (and a
corresponding m conditions) all beginning their condition_wait()s
at different times and with different timeout lengths.  In fact,
additional cthreads may be created at any time desiring this
ability.

Cthread S is the only cthread which signals any of the conditions,
and it does so based on different messages it receives from other
tasks.  I can't easily do a msg_receive() in cthread S with a timeout.

One solution I have thought of is to create a set_timer() function
which keeps track of which cthread times out next and uses itimer
to call a handler function at that time.  The handler function
would then signal the appropriate condition and then set the
itimer to wake it up again at the next appropriate time.  There
would also be a clear_timer() function that could be called when
the condition was signaled by cthread S.  However, this could quickly
get messy.  

The other method I thought of (and the one I am currently using)
is for cthread Ti ("T-sub-i") to cthread_fork() a timer cthread
before doing the condition_wait().  Cthread Ti passes the timer
cthread the number of seconds and the condition (Ci) to signal
when the seconds pass.  The timer cthread simply does a sleep() and
then signals the condition.

The problem I'm having with this second methond is as follows:
Cthread Ti receives a signal on condition Ci from cthread S while
the timer cthread is sleep()ing, and then wants to do another
condition_wait() on condition Ci with another timeout.  The old timer
cthread must be stopped from signalling condition Ci.  I had been
doing this with thread_terminate(cthread_thread(timer_cthread)) from
cthread Ti, but as Rich Draves pointed out this may be risky.

I would appreciate any suggestions or further questions by email
or news.  Thanks!

-- 
Eric Hammond
erich@kgw2.bwi.wec.com

Richard.Draves@CS.CMU.EDU (02/22/90)

Excerpts from netnews.comp.os.mach: 16-Feb-90 timeout on
condition_wait() Eric Hammond@kgw2.bwi.WE (2340)

> ===> I want to do a condition_wait() with a timeout. <===

I would solve this problem by developing a new abstract data type,
timer_condition_t.  Export operations like timer_condition_signal,
timer_condition_broadcast, timer_condition_wait (which takes a timeout).

The question then is how to implement the ADT.  One possibility is to
have a service thread that is responsible for waking up timed-out
sleepers.  The service thread would have a queue of wait events.  Each
wait event would also be on a list tied to the timer_condition_t.  The
wait event would contain a normal condition_t that is used to do the
actual sleeps/wakeups; each sleeping cthread would have its own wait
event.  And of course you'd need appropriate locking.

Rich