accurately scheduling events

I try to schedule musical events and this shall happen quite accurately. I found 'usleep' which is limited to Posix and I cannot interrupt with Ctrl-C if IO actions are scheduled using this function. Then I found 'threadDelay' which can be interrupted, but it is stated that its resolution is 1/50 seconds, which is too coarse. Additionally I found that it liberally rounds the waiting time up to the next multiple of 1/50 second. Even 'threadDelay 0' waits some time. This might be due to the fact that threadDelay was not intended for such applications, but it shall wait at least the time specified: http://www.haskell.org/pipermail/glasgow-haskell-users/2004-January/006148.h... My question: Is there some more accurate time scheduling available? Maybe not only a more accurate 'wait' function but a function which processes a list of events and starts the actions at the appropriate time points. When I write do action0 threadDelay t action1 then action1 is not started duration t after action0 is started, but time t after action0 is finished. This should be avoided by a sophisticated scheduling function. This is how I currently employ threadDelay: http://cvs.haskell.org/darcs/haskore/src/Haskore/Basic/Schedule.lhs

On Mon, Apr 10, 2006 at 02:40:20PM +0200, Henning Thielemann wrote:
My question: Is there some more accurate time scheduling available? Maybe not only a more accurate 'wait' function but a function which processes a list of events and starts the actions at the appropriate time points.
what system are you on? if you are on linux, the best thing is to use the 'real time clock' interface, which can be accessed at /dev/rtc. there is documentation available online, but basically you can set it up to give you periodic interrupts at any interval, you then want to use 'threadWaitRead' in a loop to wait for each event. spawning another OS bound thread that uses 'usleep' and writes a byte to a pipe which you are doing the threadWaitRead loop on might work too and be more portable, but I am not quite sure what issues are involved with ghc not handling ^C right away and whether an alternate bound thread will block it. you can always write a little C stub that will create that thread and return to haskell immediatly. but if possible, the rtc is designed for such a use. you might also look into /dev/sequencer, but that is tied to your sound card hardware which may or may not be acceptable. also see the c routine 'setitimer' which can be set up to periodically deliver a signal to you and should be very precise. I am not sure if haskell will give you enough control to deal with the signal with the latency you want, but it is also worth a try. John -- John Meacham - ⑆repetae.net⑆john⑈

On Mon, Apr 10, 2006 at 02:40:20PM +0200, Henning Thielemann wrote:
My question: Is there some more accurate time scheduling available? Maybe not only a more accurate 'wait' function but a function which processes a list of events and starts the actions at the appropriate time points. When I write
do action0 threadDelay t action1
then action1 is not started duration t after action0 is started, but time t after action0 is finished.
You can try my prototype implementation of retryIfBefore/retryIfAfter STM actions. Internally, it uses threadDelay (through a fake registerTimeout), so it may have the same problems as threadDelay, but: - IIRC, Simon Marlow implemented registerTimeout for GHC 6.6 - maybe it is more accurate than threadDelay... hmmm... I have HEAD somewhere, so I'll try how it works - I could try some other waiting mechanism for short intervals The use of retryIfBefore would be: do t0 <- getCurrentTime action0 atomically (retryIfBefore (addUTCTime t t0)) action1 but for such a simple task, something simpler could be better The code is in a darcs repo here: http://www.uncurry.com/repos/stm-time/ Best regards Tomasz

On Tue, Apr 11, 2006 at 10:04:12AM +0200, Tomasz Zielonka wrote:
- IIRC, Simon Marlow implemented registerTimeout for GHC 6.6 - maybe it is more accurate than threadDelay... hmmm... I have HEAD somewhere, so I'll try how it works
I used Simon's registerDelay (that's how it's called) and in a test the average difference from expected waiting time dropped from 0.010140108245s to 0.00080999391s, which is pretty good. I had to build with -threaded, because registerDelay requires that. I tried ordinary threadDelay with -threaded and, surprise!, the differences dropped too. So, try building your programs with -threaded RTS, and see if now threadDelay works for you :-) Best regards Tomasz
participants (3)
-
Henning Thielemann
-
John Meacham
-
Tomasz Zielonka