factor/basis/alarms/alarms.factor

105 lines
2.6 KiB
Factor
Raw Normal View History

2008-02-21 20:12:37 -05:00
! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman.
2007-11-06 16:51:50 -05:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs boxes calendar combinators.short-circuit
continuations fry heaps init kernel math.order
namespaces quotations threads math system ;
2007-11-06 16:51:50 -05:00
IN: alarms
2008-08-29 11:26:34 -04:00
TUPLE: alarm
{ quot callable initial: [ ] }
2009-11-30 17:31:47 -05:00
{ start integer }
2008-08-29 11:26:34 -04:00
interval
{ entry box } ;
2007-11-06 16:51:50 -05:00
2008-02-21 21:57:41 -05:00
SYMBOL: alarms
SYMBOL: alarm-thread
SYMBOL: current-alarm
2008-02-21 21:57:41 -05:00
: cancel-alarm ( alarm -- )
entry>> [ alarms get-global heap-delete ] if-box? ;
<PRIVATE
2008-02-21 21:57:41 -05:00
: notify-alarm-thread ( -- )
alarm-thread get-global interrupt ;
GENERIC: >nanoseconds ( obj -- duration/f )
M: f >nanoseconds ;
M: real >nanoseconds >integer ;
M: duration >nanoseconds duration>nanoseconds >integer ;
2007-11-06 16:51:50 -05:00
2009-11-30 17:31:47 -05:00
: <alarm> ( quot start interval -- alarm )
alarm new
swap >nanoseconds >>interval
swap >nanoseconds nano-count + >>start
2009-11-30 17:31:47 -05:00
swap >>quot
<box> >>entry ;
2007-11-06 16:51:50 -05:00
2008-02-21 21:57:41 -05:00
: register-alarm ( alarm -- )
2009-11-30 17:31:47 -05:00
[ dup start>> alarms get-global heap-push* ]
[ entry>> >box ] bi
2008-02-21 21:57:41 -05:00
notify-alarm-thread ;
2007-11-06 16:51:50 -05:00
2009-11-30 17:31:47 -05:00
: alarm-expired? ( alarm n -- ? )
[ start>> ] dip <= ;
2007-11-06 16:51:50 -05:00
2008-02-21 20:12:37 -05:00
: reschedule-alarm ( alarm -- )
dup interval>> nano-count + >>start register-alarm ;
2007-11-06 16:51:50 -05:00
: call-alarm ( alarm -- )
2008-08-29 11:26:34 -04:00
[ entry>> box> drop ]
2009-11-30 17:31:47 -05:00
[ dup interval>> [ reschedule-alarm ] [ drop ] if ]
[
[ ] [ quot>> ] [ ] tri
'[
_ current-alarm
[
_ [ _ dup interval>> [ cancel-alarm ] [ drop ] if rethrow ]
recover
] with-variable
] "Alarm execution" spawn drop
] tri ;
2008-02-21 20:12:37 -05:00
2009-11-30 17:31:47 -05:00
: (trigger-alarms) ( alarms n -- )
2008-02-21 20:12:37 -05:00
over heap-empty? [
2drop
] [
over heap-peek drop over alarm-expired? [
2008-03-03 03:22:27 -05:00
over heap-pop drop call-alarm (trigger-alarms)
2008-02-21 20:12:37 -05:00
] [
2drop
] if
] if ;
: trigger-alarms ( alarms -- )
nano-count (trigger-alarms) ;
2008-02-21 20:12:37 -05:00
: next-alarm ( alarms -- nanos/f )
dup heap-empty? [ drop f ] [ heap-peek drop start>> ] if ;
2008-02-21 20:12:37 -05:00
: alarm-thread-loop ( -- )
alarms get-global
dup next-alarm sleep-until
2008-03-12 03:36:58 -04:00
trigger-alarms ;
2008-02-21 20:12:37 -05:00
2008-02-22 17:16:00 -05:00
: cancel-alarms ( alarms -- )
[
2008-08-29 11:26:34 -04:00
heap-pop-all [ nip entry>> box> drop ] assoc-each
2008-02-22 17:16:00 -05:00
] when* ;
2008-02-21 20:12:37 -05:00
: init-alarms ( -- )
alarms [ cancel-alarms <min-heap> ] change-global
2008-03-12 03:36:58 -04:00
[ alarm-thread-loop t ] "Alarms" spawn-server
2008-02-21 20:12:37 -05:00
alarm-thread set-global ;
2009-11-16 14:25:54 -05:00
[ init-alarms ] "alarms" add-startup-hook
2008-02-21 20:19:21 -05:00
PRIVATE>
2009-11-30 17:31:47 -05:00
: add-alarm ( quot start interval -- alarm )
2008-02-21 21:57:41 -05:00
<alarm> [ register-alarm ] keep ;
2008-02-21 20:19:21 -05:00
2009-11-30 17:31:47 -05:00
: later ( quot duration -- alarm ) f add-alarm ;
2009-11-30 17:31:47 -05:00
: every ( quot duration -- alarm ) dup add-alarm ;