     { quot callable initial: [ ] }
     start-nanos 
     delay-nanos
-    interval-nanos integer
-    { next-iteration-nanos integer }
-    { stop? boolean } ;
+    interval-nanos
+    iteration-start-nanos
+    { stop? boolean }
+    thread ;
 
 <PRIVATE
 

M: duration >nanoseconds duration>nanoseconds >integer ;

: set-next-alarm-time ( alarm -- alarm )
    ! start + delay + ceiling((now - start) / interval) * interval
    nano-count 
    over start-nanos>> -
    over delay-nanos>> [ + ] when*
    over interval-nanos>> / ceiling
    over interval-nanos>> *
    over start-nanos>> + >>next-iteration-nanos ; inline

DEFER: call-alarm-loop

: loop-alarm ( alarm -- )
    nano-count over
    [ next-iteration-nanos>> - ] [ interval-nanos>> ] bi <
    [ set-next-alarm-time ] dip
    [ dup next-iteration-nanos>> ] [ 0 ] if
    sleep-until call-alarm-loop ;

: maybe-loop-alarm ( alarm -- )

    ] if ;

: call-alarm ( alarm -- )
    '[
        _ self >>thread
        [ delay-nanos>> [ sleep ] when* ]
        [ nano-count >>iteration-start-nanos call-alarm-loop ] bi
    ] "Alarm execution" spawn drop ;

PRIVATE>

