-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2359 from lf-lang/watchdog-actions
Effects made accessible in watchdog handlers
- Loading branch information
Showing
6 changed files
with
169 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,14 +8,19 @@ | |
*/ | ||
package org.lflang.generator; | ||
|
||
import java.util.LinkedHashSet; | ||
import java.util.Set; | ||
import org.lflang.TimeValue; | ||
import org.lflang.lf.Action; | ||
import org.lflang.lf.VarRef; | ||
import org.lflang.lf.Variable; | ||
import org.lflang.lf.Watchdog; | ||
|
||
/** | ||
* Instance of a watchdog. Upon creation the actual delay is converted into a proper time value. If | ||
* a parameter is referenced, it is looked up in the given (grand)parent reactor instance. | ||
* | ||
* @author{Benjamin Asch <[email protected]>} | ||
* @author Benjamin Asch | ||
*/ | ||
public class WatchdogInstance extends TriggerInstance<Watchdog> { | ||
|
||
|
@@ -30,9 +35,18 @@ public WatchdogInstance(Watchdog definition, ReactorInstance reactor) { | |
this.timeout = TimeValue.ZERO; | ||
} | ||
|
||
this.name = definition.getName().toString(); | ||
this.name = definition.getName(); | ||
this.definition = definition; | ||
this.reactor = reactor; | ||
for (VarRef effect : definition.getEffects()) { | ||
Variable variable = effect.getVariable(); | ||
if (variable instanceof Action) { | ||
// Effect is an Action. | ||
var actionInstance = reactor.lookupActionInstance((Action) variable); | ||
if (actionInstance != null) this.effects.add(actionInstance); | ||
} | ||
// Otherwise, do nothing (effect is either a mode or an unresolved reference). | ||
} | ||
} | ||
|
||
////////////////////////////////////////////////////// | ||
|
@@ -47,7 +61,7 @@ public Watchdog getDefinition() { | |
} | ||
|
||
public TimeValue getTimeout() { | ||
return (TimeValue) this.timeout; | ||
return this.timeout; | ||
} | ||
|
||
public ReactorInstance getReactor() { | ||
|
@@ -59,6 +73,12 @@ public String toString() { | |
return "WatchdogInstance " + name + "(" + timeout.toString() + ")"; | ||
} | ||
|
||
////////////////////////////////////////////////////// | ||
//// Public fields. | ||
|
||
/** The ports or actions that this reaction may write to. */ | ||
public Set<TriggerInstance<? extends Variable>> effects = new LinkedHashSet<>(); | ||
|
||
////////////////////////////////////////////////////// | ||
//// Private fields. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/** | ||
* Test watchdog. This test starts a watchdog timer of 1500ms every 1s. Half the time, it then | ||
* sleeps after starting the watchdog so that the watchdog expires. There should be a total of two | ||
* watchdog expirations. This version uses an action instead of a reaction to the watchdog. | ||
* @author Benjamin Asch | ||
* @author Edward A. Lee | ||
*/ | ||
target C { | ||
timeout: 11000 ms | ||
} | ||
|
||
reactor Watcher(timeout: time = 1500 ms) { | ||
// Offset may reduce the likelihood of flakiness if long startup times occur. | ||
timer t(1 s, 1 s) | ||
// Period has to be smaller than watchdog timeout. Produced if the watchdog triggers. | ||
output d: int | ||
state count: int = 0 | ||
logical action a | ||
|
||
watchdog poodle(timeout) -> a {= | ||
instant_t p = lf_time_physical_elapsed(); | ||
lf_print("******** Watchdog timed out at elapsed physical time: " PRINTF_TIME, p); | ||
self->count++; | ||
lf_schedule(a, 0); | ||
=} | ||
|
||
reaction(t) -> poodle, d {= | ||
lf_watchdog_start(poodle, 0); | ||
lf_print("Watchdog started at physical time " PRINTF_TIME, lf_time_physical_elapsed()); | ||
lf_print("Will expire at " PRINTF_TIME, lf_time_logical_elapsed() + self->timeout); | ||
lf_set(d, 42); | ||
=} | ||
|
||
reaction(a) -> d {= | ||
lf_print("Reaction poodle was called."); | ||
lf_set(d, 1); | ||
=} | ||
|
||
reaction(shutdown) -> poodle {= | ||
lf_watchdog_stop(poodle); | ||
// Watchdog may expire in tests even without the sleep, but it should at least expire twice. | ||
if (self->count < 2) { | ||
lf_print_error_and_exit("Watchdog expired %d times. Expected at least 2.", self->count); | ||
} | ||
=} | ||
} | ||
|
||
main reactor { | ||
logical action a | ||
state count: int = 0 | ||
|
||
w = new Watcher() | ||
|
||
reaction(startup) {= | ||
if (NUMBER_OF_WATCHDOGS != 1) { | ||
lf_print_error_and_exit("NUMBER_OF_WATCHDOGS was %d", NUMBER_OF_WATCHDOGS); | ||
} | ||
=} | ||
|
||
reaction(w.d) {= | ||
lf_print("Watcher reactor produced an output. %d", self->count % 2); | ||
self->count++; | ||
if (self->count % 4 == 0) { | ||
lf_print(">>>>>> Taking a long time to process that output!"); | ||
lf_sleep(MSEC(1600)); | ||
} | ||
=} | ||
|
||
reaction(shutdown) {= | ||
if (self->count < 12) { | ||
lf_print_error_and_exit("Watchdog produced output %d times. Expected at least 12.", self->count); | ||
} | ||
=} | ||
} |