Skip to content

Commit 86c9fad

Browse files
authored
Add support for fast mode (#137)
* Remove any platform specific code in code-generated CMakeLists * Fix FlexPRET * Dump working changes * Minimum reaction and event queue size is 1 * Ironing out the final wrinkles * Add support for running in fast mode, simply return immediatly from any call to wait_until. * Typo * Update examples
1 parent b78ade8 commit 86c9fad

File tree

11 files changed

+140
-9
lines changed

11 files changed

+140
-9
lines changed

examples/common/timer_source.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ REACTOR_CTOR_SIGNATURE(TimerSource) {
2121
TIMER_REGISTER_EFFECT(self->t, self->r);
2222
}
2323

24-
ENTRY_POINT(TimerSource, SEC(1), false);
24+
ENTRY_POINT(TimerSource, SEC(1), false, false);

include/reactor-uc/environment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct Environment {
1515
Scheduler *scheduler; // The scheduler in charge of executing the reactions.
1616
Platform *platform; // The platform that provides the physical time and sleep functions.
1717
bool has_async_events;
18+
bool fast_mode;
1819
BuiltinTrigger *startup; // A pointer to a startup trigger, if the program has one.
1920
BuiltinTrigger *shutdown; // A pointer to a chain of shutdown triggers, if the program has one.
2021
FederatedConnectionBundle **net_bundles; // A pointer to an array of NetworkChannel pointers that are used to

include/reactor-uc/macros.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ typedef struct FederatedInputConnection FederatedInputConnection;
602602
self->_children[_child_idx++] = &self->instanceName[i].super; \
603603
}
604604

605-
#define ENTRY_POINT(MainReactorName, Timeout, KeepAlive) \
605+
#define ENTRY_POINT(MainReactorName, Timeout, KeepAlive, Fast) \
606606
MainReactorName main_reactor; \
607607
Environment env; \
608608
void lf_exit(void) { Environment_free(&env); } \
@@ -611,6 +611,7 @@ typedef struct FederatedInputConnection FederatedInputConnection;
611611
MainReactorName##_ctor(&main_reactor, NULL, &env); \
612612
env.scheduler->duration = Timeout; \
613613
env.scheduler->keep_alive = KeepAlive; \
614+
env.fast_mode = Fast; \
614615
env.assemble(&env); \
615616
env.start(&env); \
616617
lf_exit(); \

lfc/core/src/main/java/org/lflang/target/Target.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
import java.util.Set;
2727
import net.jcip.annotations.Immutable;
2828
import org.lflang.lf.TargetDecl;
29-
import org.lflang.target.property.BuildTypeProperty;
30-
import org.lflang.target.property.PlatformProperty;
29+
import org.lflang.target.property.*;
3130

3231
/**
3332
* Enumeration of targets and their associated properties.
@@ -567,7 +566,8 @@ public void initialize(TargetConfig config) {
567566
// TracePluginProperty.INSTANCE,
568567
// VerifyProperty.INSTANCE,
569568
// WorkersProperty.INSTANCE);
570-
case UC -> config.register(BuildTypeProperty.INSTANCE, PlatformProperty.INSTANCE);
569+
case UC -> config.register(BuildTypeProperty.INSTANCE, PlatformProperty.INSTANCE, TimeOutProperty.INSTANCE, FastProperty.INSTANCE, KeepaliveProperty.INSTANCE);
570+
571571
// case CPP ->
572572
// config.register(
573573
// BuildTypeProperty.INSTANCE,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.lflang.target.property;
2+
3+
import org.lflang.MessageReporter;
4+
import org.lflang.ast.ASTUtils;
5+
import org.lflang.lf.Element;
6+
import org.lflang.target.property.type.PrimitiveType;
7+
8+
public abstract class BooleanProperty extends TargetProperty<Boolean, PrimitiveType> {
9+
10+
protected BooleanProperty() {
11+
super(PrimitiveType.BOOLEAN);
12+
}
13+
14+
@Override
15+
public Boolean initialValue() {
16+
return false;
17+
}
18+
19+
@Override
20+
public Boolean fromAst(Element node, MessageReporter reporter) {
21+
return ASTUtils.toBoolean(node);
22+
}
23+
24+
@Override
25+
protected Boolean fromString(String string, MessageReporter reporter) {
26+
return Boolean.parseBoolean(string);
27+
}
28+
29+
@Override
30+
public Element toAstElement(Boolean value) {
31+
return ASTUtils.toElement(value);
32+
}
33+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.lflang.target.property;
2+
3+
import org.lflang.MessageReporter;
4+
import org.lflang.ast.ASTUtils;
5+
import org.lflang.lf.Action;
6+
import org.lflang.lf.ActionOrigin;
7+
import org.lflang.lf.LfPackage.Literals;
8+
import org.lflang.lf.Reactor;
9+
import org.lflang.target.Target;
10+
import org.lflang.target.TargetConfig;
11+
12+
/**
13+
* If true, configure the execution environment such that it does not wait for physical time to
14+
* match logical time. The default is false.
15+
*/
16+
public final class FastProperty extends BooleanProperty {
17+
18+
/** Singleton target property instance. */
19+
public static final FastProperty INSTANCE = new FastProperty();
20+
21+
private FastProperty() {
22+
super();
23+
}
24+
25+
@Override
26+
public String name() {
27+
return "fast";
28+
}
29+
30+
@Override
31+
public void validate(TargetConfig config, MessageReporter reporter) {
32+
var pair = config.lookup(this);
33+
if (config.isSet(this) && config.isFederated()) {
34+
reporter
35+
.at(pair, Literals.KEY_VALUE_PAIR__NAME)
36+
.error("The fast target property is incompatible with federated programs.");
37+
}
38+
39+
// if (config.target != Target.CPP) {
40+
// Check for physical actions
41+
for (Reactor reactor : ASTUtils.getAllReactors(config.getMainResource())) {
42+
// Check to see if the program has a physical action in a reactor
43+
for (Action action : reactor.getActions()) {
44+
if (action.getOrigin().equals(ActionOrigin.PHYSICAL)) {
45+
reporter
46+
.at(pair, Literals.KEY_VALUE_PAIR__NAME)
47+
.error(
48+
String.format(
49+
"In the %s target, the fast target property is incompatible with physical"
50+
+ " actions.",
51+
config.target.toString()));
52+
break;
53+
}
54+
}
55+
}
56+
// }
57+
}
58+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.lflang.target.property;
2+
3+
/**
4+
* If true, configure the execution environment to keep executing if there are no more events on the
5+
* event queue. The default is false.
6+
*/
7+
public final class KeepaliveProperty extends BooleanProperty {
8+
9+
/** Singleton target property instance. */
10+
public static final KeepaliveProperty INSTANCE = new KeepaliveProperty();
11+
12+
private KeepaliveProperty() {
13+
super();
14+
}
15+
16+
@Override
17+
public String name() {
18+
return "keepalive";
19+
}
20+
}

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMainGenerator.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import org.lflang.generator.uc.UcReactorGenerator.Companion.codeType
66
import org.lflang.inferredType
77
import org.lflang.lf.Parameter
88
import org.lflang.lf.Reactor
9+
import org.lflang.target.property.FastProperty
10+
import org.lflang.target.property.KeepaliveProperty
911
import org.lflang.target.property.PlatformProperty
1012
import org.lflang.target.property.TimeOutProperty
1113
import org.lflang.target.property.type.PlatformType
@@ -37,13 +39,15 @@ class UcMainGenerator(
3739

3840
fun getDuration() = if (targetConfig.isSet(TimeOutProperty.INSTANCE)) targetConfig.get(TimeOutProperty.INSTANCE).toCCode() else "FOREVER"
3941

40-
fun keepAlive() = "false"
42+
fun keepAlive() = if(targetConfig.isSet(KeepaliveProperty.INSTANCE)) "true" else "false"
43+
44+
fun fast() = if(targetConfig.isSet(FastProperty.INSTANCE)) "true" else "false"
4145

4246
fun generateMainSource() = with(PrependOperator) {
4347
"""
4448
|#include "reactor-uc/reactor-uc.h"
4549
|#include "${fileConfig.getReactorHeaderPath(main).toUnixString()}"
46-
|ENTRY_POINT(${main.codeType}, ${getDuration()}, ${keepAlive()});
50+
|ENTRY_POINT(${main.codeType}, ${getDuration()}, ${keepAlive()}, ${fast()});
4751
${" |"..generateMainFunction()}
4852
""".trimMargin()
4953
}

src/environment.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void Environment_start(Environment *self) {
2828
}
2929

3030
lf_ret_t Environment_wait_until(Environment *self, instant_t wakeup_time) {
31-
if (wakeup_time <= self->get_physical_time(self)) {
31+
if (wakeup_time <= self->get_physical_time(self) || self->fast_mode) {
3232
return LF_OK;
3333
}
3434

@@ -82,6 +82,7 @@ void Environment_ctor(Environment *self, Reactor *main) {
8282
self->enter_critical_section = Environment_enter_critical_section;
8383
self->request_shutdown = Environment_request_shutdown;
8484
self->has_async_events = false;
85+
self->fast_mode = false;
8586
self->startup = NULL;
8687
self->shutdown = NULL;
8788
}

test/lf/src/Fast.lf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
target uC {
2+
fast: true,
3+
timeout: 1 hour
4+
}
5+
6+
main reactor {
7+
timer t(0, 1 sec)
8+
reaction(t) {= =}
9+
10+
reaction(shutdown) {=
11+
printf("Finally shutdown executed for %" PRId64 " logical sec\n", env->get_elapsed_logical_time(env)/SEC(1));
12+
=}
13+
}

0 commit comments

Comments
 (0)