[prev in list] [next in list] [prev in thread] [next in thread] 

List:       9fans
Subject:    Re: [9fans] thread confusion
From:       Axel Belinfante <Axel.Belinfante () cs ! utwente ! nl>
Date:       2005-09-27 10:12:54
Message-ID: 200509271012.j8RACsT11583 () zamenhof ! cs ! utwente ! nl
[Download RAW message or body]

> > I do use a timer, by having a proc that repeatedly sleeps
> > and decrements a counter, and when the counter reaches
> > zero it sends a (nil) timeout message on a channel.
> > in alts I not only wait for the io channels but
> > also for the timer timeout channel.
> > 
> > the question is how to start and reset the timer.
> > I have been thinking about using channels for that
> > too, but that seems deadlock prone: how to avoid
> > the case where I want to send a reset message to
> > the timer when the timer wants to send an expiration
> > message to me?
> 
> i think this is a good question.
> 
> i've found writing time-based code using the threads library to be
> quite awkward.  it seems to me that there may be room for an extension
> to help with writing this kind of code.
> 
> the difficulty with the plan 9 thread library (and with Limbo too) is
> that sleep(2) exists in a different universe to channels, so one has
> to use a separate process to bridge the gap.
> 
> but when this thread is sleeping, it's not possible to communicate
> with it, so one needs another thread to act as an intermediary, and
> one has to design the interface carefully - if possible one doesn't
> want a separate process and thread for each thread that wishes to wait
> for a little while.

I have seen the followup discussion after this post and like
the idea of support for this in the thread library.
Indeed the accuracy may/will be higher than what I'm using
right now (but for my use it is not really an issue, I guess).

This is just to share the approach I have taken after
my initial posts on the topic.

(after some bad experience) I've abandoned the idea
of a timer process that only delivers expiration messages,
and with which one communicates to start and cancel timers.
Instead I'm using (something like) the etimer(2) approach.
I have now a proc that regularly sends ticks over a channel
using non-blocking sends, and decrement timers and check
for expiration in the alt.
Hmm... thinking on it while writing this, I suppose
that tickproc could just as well use blocking sends.

void
tickproc(void *v)
{
  for(;;) {
    sleep(tickTime);
    nbsend((Channel*)v, nil);
  }
}

use of ticks:

  ...
  t = ticksToWait;
  done = 0;
  while(!done)
    switch(alt(a)){
    case iochannel:
      done = 1;
      ... other handling ...
      break;
    ...
    case tickchannel:
      t--;
      if (t == 0) {
        done = 1;
        ... handle timeout ...
      }
    }
  ...

This seems to get the job done in
a less complex and more clean way
than what I was using before.

Axel.
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic