Timer question

Started by pjot, May 31, 2005, 01:27:41 PM

Previous topic - Next topic

pjot

Hi,



Experimenting with the 'timer' function it seemed to be interesting to use it as a kind of thread.



#!/usr/bin/newlisp

(define (ticker)
    (println (date)) (timer 'ticker 1.0))

(ticker)

(while true (println (read-key)))


However, in this program the ticker is only executed once, while you would expect that the 'while' is interrupted with a 'println (date)' every second. According to the manpage of 'setitimer':


Quote
The  system  provides  each  process  with  three interval timers, each decrementing in a distinct time domain.  When any  timer  expires,  a signal is sent to the process, and the timer (potentially) restarts.


Probably the signal is being sent (I trust Unix!), but obviously, newLisp is too busy with other things to capture that signal and carry out the appropriate function.



In other words: the timer function only works when newLisp is not doing anything else? So only in interactive mode?



Peter

pjot

#1
The 'timer' keyword does not appear in the VIM syntax file. Nor the keyword 'semaphore'.



In the meantime I found out that during a 'sleep' newLisp will respond to a timer signal.



Peter

Lutz

#2
Yes, SIGALRM kills sleep and I think SIGCHLD does too, that's the way it is on UNIX.



I added 'timer', 'share' and 'semaphore', it sait 'share' and 'semaphore' where added, but in reality they were not.



Lutz

Lutz

#3
>> > in other words: the timer function only works when newLisp is not >>> doing anything else? So only in interactive mode?



Oh no, absolutely not. 'timer' can interrupt any newLISP code, not only interactively. I have to run now. But I post you an example later tonight.



Lutz

Lutz

#4
Here is an example showing the timer interrupting another function in progress, run this program:

; timer demo

define (alarm)
        (set 'done true)
        (println "ring ..."))

(timer 'alarm 2.0)

(until done
        (println ".")
        (sleep 300))

(println "finished")

(exit)


Lutz

pjot

#5
Yes, it interrupts the function because there is a 'sleep' in there. If you remove the sleep then it does not work.

Lutz

#6
This is not true, the timer can interrupt other operations too:

(define (mysleep n)
        (set 'start (time-of-day))
        (while (> (+ start n) (time-of-day))))

(define (alarm)
        (set 'done true)
        (println "ring ..."))

(timer 'alarm 2.0)

(until done
        (println ".")
        (mysleep 300))

(println "finished")

(exit)


Lutz

pjot

#7
OK indeed it works. But this one doesn't, and I was blinded by it:



#!/usr/bin/newlisp

(define (ticker)
    (println (date)) (timer 'ticker 1.0))

(timer 'ticker 1.0)

(while true (println (read-key)))


But I already choose another way for my program. :-)

Lutz

#8
You only can interrupt inbetween the evaluation of 2 newLISP expressions. The timer signal is received and registered by newLISP, but it must come out of the 'atomic' read-key first to execute the handler. The same is true for all I/O operations. I.e. 'read-buffer' or 'read-line' operations would have to finish first, before the 'timer' or any other 'signal' handler can run.



In the case of network functions you can work with 'net-select' and 'net-peek' before you go into a read operation:

(define (interrupt)
        (set 'timeout true))

(timer 'interrupt 5.0)

(until (or timeout done)
        (if (net-select socket "read" 100000)
                (begin
                        (read-buffer socket 'buffer 1024)
                        (set 'done true)))
)


This code would wait for information on 'socket' for 5 seconds and then time out.



Lutz

pjot

#9
Well, you are ahead of me, indeed I was about to ask stuff regarding READ/WRITE operations.



Thanks for the clarifications.



Peter