Skip to content

Commit

Permalink
Merge pull request #1207 from lf-lang/c-scaling-wrt-threads
Browse files Browse the repository at this point in the history
C adaptive scheduler
  • Loading branch information
petervdonovan authored Jun 22, 2022
2 parents f098edc + 037b0c0 commit 9cb9ae7
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 27 deletions.
5 changes: 3 additions & 2 deletions org.lflang.tests/src/org/lflang/tests/LFTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.lflang.tests;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
Expand Down Expand Up @@ -229,8 +230,8 @@ private Thread recordStream(StringBuffer builder, InputStream inputStream) {
while ((len = reader.read(buf)) > 0) {
builder.append(buf, 0, len);
}
} catch (Exception e) {
builder.append("[truncated...]\n");
} catch (IOException e) {
throw new RuntimeException("While reading from a stream, an I/O exception occurred:\n" + e);
}
});
t.start();
Expand Down
37 changes: 29 additions & 8 deletions org.lflang/src/org/lflang/TargetProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import org.lflang.util.StringUtil;
import org.lflang.validation.LFValidator;

import com.google.common.collect.ImmutableList;

/**
* A target properties along with a type and a list of supporting targets
* that supports it, as well as a function for configuration updates.
Expand Down Expand Up @@ -194,7 +196,7 @@ public enum TargetProperty {
* compiled binary.
*/
EXTERNAL_RUNTIME_PATH("external-runtime-path", PrimitiveType.STRING,
Arrays.asList(Target.CPP), (config, value, err) -> {
List.of(Target.CPP), (config, value, err) -> {
config.externalRuntimePath = ASTUtils.elementToSingleString(value);
}),

Expand Down Expand Up @@ -1148,7 +1150,7 @@ public boolean validate(Element e) {
*
* @param e The element to type check.
* @param name The name of the target property.
* @param errors A list of errors to append to if problems are found.
* @param v The validator to which any errors should be reported.
*/
public void check(Element e, String name, LFValidator v) {
if (!this.validate(e)) {
Expand Down Expand Up @@ -1311,24 +1313,43 @@ public String toString() {
*/
public enum SchedulerOption {
NP(false), // Non-preemptive
adaptive(false, List.of(
Path.of("scheduler_adaptive.c"),
Path.of("worker_assignments.h"),
Path.of("worker_states.h"),
Path.of("data_collection.h")
)),
GEDF_NP(true), // Global EDF non-preemptive
GEDF_NP_CI(true); // Global EDF non-preemptive with chain ID
// PEDF_NP(true); // Partitioned EDF non-preemptive (FIXME: To be re-added in a future PR)

/**
* Indicate whether or not the scheduler prioritizes reactions by deadline.
*/
private final Boolean prioritizesDeadline;

private final boolean prioritizesDeadline;

/** Relative paths to files required by this scheduler. */
private final List<Path> relativePaths;

SchedulerOption(boolean prioritizesDeadline) {
this(prioritizesDeadline, null);
}

SchedulerOption(boolean prioritizesDeadline, List<Path> relativePaths) {
this.prioritizesDeadline = prioritizesDeadline;
this.relativePaths = relativePaths;
}

/**
* Return true if the scheduler prioritizes reactions by deadline.
*/
public Boolean prioritizesDeadline() {
public boolean prioritizesDeadline() {
return this.prioritizesDeadline;
}

private SchedulerOption(Boolean prioritizesDeadline) {
this.prioritizesDeadline = prioritizesDeadline;

public List<Path> getRelativePaths() {
return relativePaths != null ? ImmutableList.copyOf(relativePaths) :
List.of(Path.of("scheduler_" + this + ".c"));
}

public static SchedulerOption getDefault() {
Expand Down
15 changes: 10 additions & 5 deletions org.lflang/src/org/lflang/generator/c/CCoreFilesUtils.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.lflang.generator.c;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.lflang.TargetProperty.SchedulerOption;

/**
Expand Down Expand Up @@ -112,13 +115,15 @@ private static List<String> getThreadSupportFiles(
SchedulerOption scheduler
) {
return threading ?
List.of(
Stream.concat(
Stream.of(
"threaded/scheduler.h",
"threaded/scheduler_instance.h",
"threaded/scheduler_sync_tag_advance.c",
"threaded/scheduler_" + scheduler + ".c",
"threaded/reactor_threaded.c"
) :
List.of("reactor.c");
),
scheduler.getRelativePaths().stream().map(path -> "threaded/" + path.toString().replace("\\", "/"))
).collect(Collectors.toList()) :
List.of("reactor.c");
}
}
2 changes: 1 addition & 1 deletion org.lflang/src/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2450,7 +2450,7 @@ public String generateNetworkSenderBody(
* input port "port" or has it in its sources. If there are only connections to contained
* reactors, in the top-level reactor.
*
* @param receivingPortID The port to generate the control reaction for
* @param receivingPortID The ID of the port to generate the control reaction for
* @param maxSTP The maximum value of STP is assigned to reactions (if any)
* that have port as their trigger or source
*/
Expand Down
30 changes: 20 additions & 10 deletions org.lflang/src/org/lflang/validation/LFValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,12 @@ public void checkTargetDecl(TargetDecl target) throws IOException {
*/
@Check(CheckType.EXPENSIVE)
public void checkTargetProperties(KeyValuePairs targetProperties) {
validateFastTargetProperty(targetProperties);
validateClockSyncTargetProperties(targetProperties);
validateSchedulerTargetProperties(targetProperties);
}

private void validateFastTargetProperty(KeyValuePairs targetProperties) {
EList<KeyValuePair> fastTargetProperties = new BasicEList<>(targetProperties.getPairs());
fastTargetProperties.removeIf(pair -> TargetProperty.forName(pair.getName()) != TargetProperty.FAST);
KeyValuePair fastTargetProperty = fastTargetProperties.size() > 0 ? fastTargetProperties.get(0) : null;
Expand All @@ -1069,7 +1075,7 @@ public void checkTargetProperties(KeyValuePairs targetProperties) {
break;
}
}

// Check for physical actions
for (Reactor reactor : info.model.getReactors()) {
// Check to see if the program has a physical action in a reactor
Expand All @@ -1085,7 +1091,9 @@ public void checkTargetProperties(KeyValuePairs targetProperties) {
}
}
}

}

private void validateClockSyncTargetProperties(KeyValuePairs targetProperties) {
EList<KeyValuePair> clockSyncTargetProperties = new BasicEList<>(targetProperties.getPairs());
// Check to see if clock-sync is defined
clockSyncTargetProperties.removeIf(pair -> TargetProperty.forName(pair.getName()) != TargetProperty.CLOCK_SYNC);
Expand All @@ -1106,9 +1114,10 @@ public void checkTargetProperties(KeyValuePairs targetProperties) {
);
}
}
}

EList<KeyValuePair> schedulerTargetProperties =
private void validateSchedulerTargetProperties(KeyValuePairs targetProperties) {
EList<KeyValuePair> schedulerTargetProperties =
new BasicEList<>(targetProperties.getPairs());
schedulerTargetProperties.removeIf(pair -> TargetProperty
.forName(pair.getName()) != TargetProperty.SCHEDULER);
Expand All @@ -1120,14 +1129,15 @@ public void checkTargetProperties(KeyValuePairs targetProperties) {
if (!TargetProperty.SchedulerOption.valueOf(schedulerName)
.prioritizesDeadline()) {
// Check if a deadline is assigned to any reaction
if (info.model.getReactors().stream().filter(reactor -> {
// Filter reactors that contain at least one reaction that
// has a deadline handler.
if (info.model.getReactors().stream().anyMatch(
// Filter reactors that contain at least one reaction that
// has a deadline handler.
return ASTUtils.allReactions(reactor).stream()
.filter(reaction -> {
return reaction.getDeadline() != null;
}).count() > 0;
}).count() > 0) {
reactor -> ASTUtils.allReactions(reactor).stream().anyMatch(
reaction -> reaction.getDeadline() != null
))
) {
warning("This program contains deadlines, but the chosen "
+ schedulerName
+ " scheduler does not prioritize reaction execution "
Expand Down

0 comments on commit 9cb9ae7

Please sign in to comment.