diff --git a/basis/alarms/alarms-docs.factor b/basis/alarms/alarms-docs.factor index 2c5a567d62..396011a351 100644 --- a/basis/alarms/alarms-docs.factor +++ b/basis/alarms/alarms-docs.factor @@ -4,9 +4,23 @@ IN: alarms HELP: alarm { $class-description "An alarm. Can be passed to " { $link cancel-alarm } "." } ; +HELP: current-alarm +{ $description "A symbol that contains the currently executing alarm, availble only to the alarm quotation. One use for this symbol is if a repeated alarm wishes to cancel itself from executing in the future." +} +{ $examples + { $unchecked-example + """USING: alarms calendar io threads ;""" + """[""" + """ "Hi, this should only get printed once..." print flush""" + """ current-alarm get cancel-alarm""" + """] 1 seconds every""" + "" + } +} ; + HELP: add-alarm { $values { "quot" quotation } { "start" duration } { "interval" { $maybe "duration/f" } } { "alarm" alarm } } -{ $description "Creates and registers an alarm to start at " { $snippet "start" } " offset from the current time. If " { $snippet "interval" } " is " { $link f } ", this will be a one-time alarm, otherwise it will fire with the given frequency, with scheduling happening before the quotation is called in order to ensure that the next event will happen on time. The quotation will be called from the alarm thread." } ; +{ $description "Creates and registers an alarm to start at " { $snippet "start" } " offset from the current time. If " { $snippet "interval" } " is " { $link f } ", this will be a one-time alarm, otherwise it will fire with the given frequency, with scheduling happening before the quotation is called in order to ensure that the next event will happen on time. The quotation will be called from a new thread spawned by the alarm thread. If a repeated alarm's quotation throws an exception, the alarm will not be rescheduled." } ; HELP: later { $values { "quot" quotation } { "duration" duration } { "alarm" alarm } } @@ -27,7 +41,7 @@ HELP: every { $values { "quot" quotation } { "duration" duration } { "alarm" alarm } } -{ $description "Creates and registers an alarm which calls the quotation repeatedly, using " { $snippet "dt" } " as the frequency." } +{ $description "Creates and registers an alarm which calls the quotation repeatedly, using " { $snippet "dt" } " as the frequency. If the quotation throws an exception that is not caught inside it, the alarm scheduler will cancel the alarm and will not reschedule it again." } { $examples { $unchecked-example "USING: alarms io calendar ;" @@ -44,6 +58,8 @@ ARTICLE: "alarms" "Alarms" { $subsections every } "Register a one-time alarm:" { $subsections later } +"The currently executing alarm:" +{ $subsections current-alarm } "Low-level interface to add alarms:" { $subsections add-alarm } "Cancelling an alarm:" diff --git a/basis/alarms/alarms.factor b/basis/alarms/alarms.factor index 251d82eec8..9ab30a1fa4 100644 --- a/basis/alarms/alarms.factor +++ b/basis/alarms/alarms.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs boxes calendar -combinators.short-circuit fry heaps init kernel math.order +USING: accessors assocs boxes calendar combinators.short-circuit +continuations fry heaps init kernel math.order namespaces quotations threads math system ; IN: alarms @@ -11,21 +11,27 @@ TUPLE: alarm interval { entry box } ; -> [ alarms get-global heap-delete ] if-box? ; + +duration duration>nanoseconds >integer ; +GENERIC: >nanoseconds ( obj -- duration/f ) +M: f >nanoseconds ; +M: real >nanoseconds >integer ; +M: duration >nanoseconds duration>nanoseconds >integer ; : ( quot start interval -- alarm ) alarm new - swap dup [ normalize-argument ] when >>interval - swap dup [ normalize-argument nano-count + ] when >>start + swap >nanoseconds >>interval + swap >nanoseconds nano-count + >>start swap >>quot >>entry ; @@ -43,7 +49,16 @@ SYMBOL: alarm-thread : call-alarm ( alarm -- ) [ entry>> box> drop ] [ dup interval>> [ reschedule-alarm ] [ drop ] if ] - [ quot>> "Alarm execution" spawn drop ] tri ; + [ + [ ] [ quot>> ] [ ] tri + '[ + _ current-alarm + [ + _ [ _ dup interval>> [ cancel-alarm ] [ drop ] if rethrow ] + recover + ] with-variable + ] "Alarm execution" spawn drop + ] tri ; : (trigger-alarms) ( alarms n -- ) over heap-empty? [ @@ -87,6 +102,3 @@ PRIVATE> : later ( quot duration -- alarm ) f add-alarm ; : every ( quot duration -- alarm ) dup add-alarm ; - -: cancel-alarm ( alarm -- ) - entry>> [ alarms get-global heap-delete ] if-box? ; diff --git a/basis/calendar/calendar.factor b/basis/calendar/calendar.factor index fd51feeed9..25cf35c062 100644 --- a/basis/calendar/calendar.factor +++ b/basis/calendar/calendar.factor @@ -143,8 +143,7 @@ GENERIC: easter ( obj -- obj' ) 32 2 e * + 2 i * + h - k - 7 mod :> l a 11 h * + 22 l * + 451 /i :> m - h l + 7 m * - 114 + 31 /mod 1 + :> ( month day ) - month day ; + h l + 7 m * - 114 + 31 /mod 1 + ; M: integer easter ( year -- timestamp ) dup easter-month-day ; @@ -171,11 +170,6 @@ M: timestamp easter ( timestamp -- timestamp ) : microseconds ( x -- duration ) 1000000 / seconds ; : nanoseconds ( x -- duration ) 1000000000 / seconds ; -GENERIC: >duration ( obj -- duration/f ) -M: duration >duration ; -M: real >duration seconds ; -M: f >duration ; - GENERIC: year ( obj -- n ) M: integer year ; M: timestamp year year>> ; diff --git a/basis/math/matrices/elimination/elimination.factor b/basis/math/matrices/elimination/elimination.factor index 4dc29ad951..371eb8a36c 100644 --- a/basis/math/matrices/elimination/elimination.factor +++ b/basis/math/matrices/elimination/elimination.factor @@ -52,8 +52,11 @@ SYMBOL: matrix [ first-col ] keep dup 1 + rows-from clear-col ; +: find-row ( row# quot -- i elt ) + [ rows-from ] dip find ; inline + : pivot-row ( col# row# -- n ) - rows-from swap '[ [ _ ] dip nth-row nth abs ] sort-with last ; + [ dupd nth-row nth zero? not ] find-row 2nip ; : (echelon) ( col# row# -- ) over cols < over rows < and [