Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheduling enclaves in the C target #1872

Closed
wants to merge 69 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
011c763
Add enclaved reactor AST transformation and test files
erlingrj Jun 8, 2023
494c15f
Update tracing API
erlingrj Jun 8, 2023
4d78138
Merge branch 'enclaves' into enclaves2
erlingrj Jun 8, 2023
69f64ac
DelayedConnection should use enclaves
erlingrj Jun 8, 2023
50b4e4a
Bump reactor-C
erlingrj Jun 8, 2023
4141b40
Merge branch 'enclaves' into enclaves2
erlingrj Jun 8, 2023
3dc3919
Merge branch 'enclaves' into enclaves2
erlingrj Jun 10, 2023
80103d6
Use a reactor_mutex in the ConnectionReactor to enforce mutual exclu…
erlingrj Jun 10, 2023
b5b6632
Set LF_ENCLAVES compile def
erlingrj Jun 11, 2023
edd9952
Add a test for simple coordination of enclaves
erlingrj Jun 11, 2023
e5f2e89
Code auto-formatted with Spotless
erlingrj Jun 11, 2023
235483b
Initial work on code-generating the enclave topology
erlingrj Jun 13, 2023
bc89970
Code auto-formatted with Spotless
erlingrj Jun 13, 2023
c0ec4f6
Address Peter's comments
erlingrj Jun 14, 2023
b518935
Get SimpleCoordination working and add some failing tests
erlingrj Jun 16, 2023
240e973
Code auto-formatted with Spotless
erlingrj Jun 16, 2023
b16434e
Add validation checks and a bunch of tests
erlingrj Jun 24, 2023
48e8a1b
Handle enclaved connections with tokens
erlingrj Jun 26, 2023
d2ce286
bump reactor-C
erlingrj Jun 26, 2023
5051337
Handle enclaved connections with tokens
erlingrj Jun 26, 2023
7204d52
Dont initialize reactor_mutex unless we are in threaded moed
erlingrj Jun 26, 2023
d0dccc0
More fixes
erlingrj Jun 27, 2023
7cbb9c8
Update copying of reactor-c for Arduino
erlingrj Jun 29, 2023
76321d8
Move some tests
erlingrj Jun 29, 2023
2c9aa09
Rename enclave test to avoid collision
erlingrj Jun 29, 2023
0f26bdb
Dont generate 0-length arrays because MVSC
erlingrj Jun 29, 2023
be43717
Code auto-formatted with Spotless
erlingrj Jun 29, 2023
1d98b1a
time_t -> instant_t
erlingrj Jun 29, 2023
8f6d89a
Update enclave tests to include platform.h if using lf_sleep
erlingrj Jun 29, 2023
62258c7
Merge remote-tracking branch 'origin/master' into enclaves2
erlingrj Jun 29, 2023
9c7ea0d
Move from errorReporter to messageReporter
erlingrj Jun 29, 2023
a3ab9d4
Support TypeParameterizedReactors with token types
erlingrj Jun 30, 2023
9c405a1
Code auto-formatted with Spotless
erlingrj Jun 30, 2023
de93d76
Run formatter
erlingrj Jun 30, 2023
31dd940
Casting void to mutex
erlingrj Jun 30, 2023
be4a046
Cast malloc return
erlingrj Jun 30, 2023
af350b3
Move ShutdownCoordinated and bump reactor-c
erlingrj Jun 30, 2023
0a4d9ec
Code auto-formatted with Spotless
erlingrj Jun 30, 2023
6ad747d
Add JavaDocs to several funcions
erlingrj Jul 7, 2023
effa420
Add the hasAfterDelay parameter to the ConnectionReactors
erlingrj Jul 8, 2023
6878523
Add tests for the microstep index after an enclaved connection
erlingrj Jul 8, 2023
0fca3cc
Make pass on docs
erlingrj Jul 11, 2023
071c3c9
Code auto-formatted with Spotless
erlingrj Jul 11, 2023
81685f0
Fix more docs and add validator check to catch encalves in modes
erlingrj Jul 12, 2023
2ad1950
Update core/src/main/java/org/lflang/validation/AttributeSpec.java
erlingrj Jul 12, 2023
35bb9d1
Code auto-formatted with Spotless
erlingrj Jul 12, 2023
d6d19f9
Merge branch 'enclaves2' of github.com:lf-lang/lingua-franca into enc…
erlingrj Jul 12, 2023
0f25c8c
Make sure to delete everything federated related for Ardunio except l…
erlingrj Jul 13, 2023
1f73d34
Use new gradle API to run Zephyr tests
erlingrj Jul 13, 2023
99342b8
Fix Arduino file utils to delete federated-related files except RTI l…
erlingrj Jul 13, 2023
dcd0518
Code auto-formatted with Spotless
erlingrj Jul 13, 2023
42d659c
Merge remote-tracking branch 'origin/master' into enclaves2
erlingrj Jul 13, 2023
4522f43
Move EnclaveFederatedRequestStop to failing
erlingrj Jul 13, 2023
c0ee111
Merge branch 'master' into lfe-merge
erlingrj Sep 22, 2023
acb9be9
Bump reactor-c to merged
erlingrj Sep 22, 2023
28e4fe7
Merge branch 'master' into enclaves2
erlingrj Sep 26, 2023
ff27f40
Add enclave tests and other nitpicks from merge
erlingrj Oct 2, 2023
a0f1be4
Merge branch 'enclaves2' of github.com:lf-lang/lingua-franca into enc…
erlingrj Oct 2, 2023
5862c12
Merge remote-tracking branch 'origin/master' into enclaves2
erlingrj Oct 2, 2023
756f8a8
Remove unnecessary starvation test
erlingrj Oct 2, 2023
3fc9fd7
Spotless
erlingrj Oct 4, 2023
f451911
Fix enclave test that had a race condition
erlingrj Oct 4, 2023
7194624
Merge remote-tracking branch 'origin/test-fix-free-memory' into encla…
erlingrj Oct 5, 2023
7c75e15
Remove old LET calculations.
erlingrj Oct 19, 2023
edba77f
Merge master into enclaves2
edwardalee Nov 5, 2023
e3fe29d
Fixed compile errors from merge of master into enclaves2
edwardalee Nov 5, 2023
0bcd4dd
Align reactor-c
edwardalee Nov 8, 2023
bf7fc54
LF_THREADED -> LF_SINGLE_THREADED
erlingrj Nov 8, 2023
26dc03b
Bump reactor-c and move from lf_assert to LF_ASSERT
erlingrj Nov 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ protected boolean supportsDockerOption() {
return true;
}

@Override
protected boolean supportsEnclaves() {
return true;
}

@Test
@Override
public void runBasicTests() {
Expand Down
36 changes: 26 additions & 10 deletions core/src/main/java/org/lflang/AttributeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@

package org.lflang;

import static org.lflang.ast.ASTUtils.factory;

import java.util.List;
import java.util.Objects;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.XtextResource;
Expand All @@ -46,6 +45,7 @@
import org.lflang.lf.StateVar;
import org.lflang.lf.Timer;
import org.lflang.util.StringUtil;
import org.lflang.validation.AttributeSpec;

/**
* A helper class for processing attributes in the AST.
Expand Down Expand Up @@ -255,16 +255,32 @@ public static boolean isEnclave(Instantiation node) {
return getEnclaveAttribute(node) != null;
}

public static int getEnclaveNumWorkersFromAttribute(Instantiation node) {
Attribute enclaveAttr = getEnclaveAttribute(node);
if (enclaveAttr != null) {
for( AttrParm attrParm: enclaveAttr.getAttrParms()) {
if (attrParm.getName().equals(AttributeSpec.WORKERS_ATTR)) {
int value = Integer.valueOf(attrParm.getValue());
if (value > 0) {
return value;
} else {
return 1;
}
}
}
}
return 1; // Not specified
}

/**
* Annotate @{code node} with enclave @attribute
*
* @param node
* Move the enclave attribute from source inst to target inst.
* @param source
* @param target
*/
public static void setEnclaveAttribute(Instantiation node) {
if (!isEnclave(node)) {
Attribute enclaveAttr = factory.createAttribute();
enclaveAttr.setAttrName("enclave");
node.getAttributes().add(enclaveAttr);
public static void copyEnclaveAttribute(Instantiation source, Instantiation target) {
Attribute enclaveAttr = EcoreUtil.copy(getEnclaveAttribute(source));
if (enclaveAttr != null) {
target.getAttributes().add(enclaveAttr);
}
}
}
22 changes: 22 additions & 0 deletions core/src/main/java/org/lflang/ast/ASTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

package org.lflang.ast;

import static org.lflang.AttributeUtils.isEnclave;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
Expand All @@ -33,8 +35,10 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -63,6 +67,7 @@
import org.lflang.generator.CodeMap;
import org.lflang.generator.InvalidSourceException;
import org.lflang.generator.ReactorInstance;
import org.lflang.generator.c.CUtil;
import org.lflang.lf.Action;
import org.lflang.lf.Assignment;
import org.lflang.lf.Code;
Expand Down Expand Up @@ -1853,4 +1858,21 @@ public static void addReactionAttribute(Reaction reaction, String name) {
fedAttr.setAttrName(name);
reaction.getAttributes().add(fedAttr);
}

public static List<Instantiation> getEnclaves(Reactor top) {
List<Instantiation> enclaves = new ArrayList<>();
Queue<Reactor> queue = new LinkedList<>();
queue.add(top);

while (!queue.isEmpty()) {
Reactor inst = queue.poll();
for (Instantiation child: inst.getInstantiations()) {
if (isEnclave(child)) {
enclaves.add(child);
}
queue.add(ASTUtils.toDefinition(child.getReactorClass()));
}
}
return enclaves;
}
}
5 changes: 3 additions & 2 deletions core/src/main/java/org/lflang/generator/EnclaveInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ public class EnclaveInfo {
public int numShutdownReactions = 0;
public int numTimerTriggers = 0;
public int numResetReactions = 0;
public int numWorkers = 1;
public int numWorkers = 0;
public int numModalReactors = 0;
public int numModalResetStates = 0;

public String traceFileName = null;
private ReactorInstance instance;

public EnclaveInfo(ReactorInstance inst) {
public EnclaveInfo(ReactorInstance inst, int numWorkers) {
instance = inst;
this.numWorkers = numWorkers;
}
}
64 changes: 42 additions & 22 deletions core/src/main/java/org/lflang/generator/ReactionInstanceGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
package org.lflang.generator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.lflang.generator.ReactionInstance.Runtime;
Expand Down Expand Up @@ -101,19 +103,36 @@ public void rebuildAndAssignDeadlines() {
this.clear();
}

public Integer[] getNumReactionsPerLevel() {
List<Integer> res = new ArrayList<>();
for (Map<ReactorInstance, Integer> numReactionsMap : numReactionsPerEnclavePerLevel) {
Integer numReactions = numReactionsMap.values().stream().mapToInt(Integer::intValue).sum();
res.add(numReactions);
}
return res.toArray(new Integer[0]);
}
public Integer[] getNumReactionsPerLevel(ReactorInstance enclave) {
List<Integer> res = new ArrayList<>();
for (Map<ReactorInstance, Integer> breadthMap : numReactionsPerEnclavePerLevel) {
var breadth = breadthMap.get(enclave);
if (breadth != null) {
res.add(breadth);
} else {
res.add(0);
}
}
return res.toArray(new Integer[0]);
}
/*
* Get an array of non-negative integers representing the number of reactions
* per each level, where levels are indices of the array.
*/
public Integer[] getNumReactionsPerLevel() {
return numReactionsPerLevel.toArray(new Integer[0]);
}

/** Return the max breadth of the reaction dependency graph */
public int getBreadth() {
public int getBreadth(ReactorInstance enclave) {
var maxBreadth = 0;
for (Integer breadth : numReactionsPerLevel) {
if (breadth > maxBreadth) {
for (Map<ReactorInstance, Integer> breadthMap: numReactionsPerEnclavePerLevel) {
var breadth = breadthMap.get(enclave);
if (breadth != null && breadth > maxBreadth) {
maxBreadth = breadth;
}
}
Expand Down Expand Up @@ -247,11 +266,9 @@ protected void addNodesAndEdges(ReactorInstance reactor) {
///////////////////////////////////////////////////////////
//// Private fields

/**
* Number of reactions per level, represented as a list of integers where the indices are the
* levels.
*/
private List<Integer> numReactionsPerLevel = new ArrayList<>(List.of(0));
// Number of reactions per level, per enclave. Used to calculate how many workers to use
// for each enclave
private List<Map<ReactorInstance, Integer>> numReactionsPerEnclavePerLevel = new ArrayList<>();

///////////////////////////////////////////////////////////
//// Private methods
Expand Down Expand Up @@ -301,8 +318,9 @@ private void assignLevels() {
// Remove visited origin.
removeNode(origin);

ReactorInstance enclave = CUtil.getClosestEnclave(origin.getReaction().parent);
// Update numReactionsPerLevel info
adjustNumReactionsPerLevel(origin.level, 1);
adjustNumReactionsPerLevel(origin.level, enclave);
}
}

Expand Down Expand Up @@ -346,21 +364,23 @@ private void assignInferredDeadlines() {
}

/**
* Adjust {@link #numReactionsPerLevel} at index <code>level<code> by
* Adjust {@link #numReactionsPerEnclavePerLevel} at index <code>level<code> by
* adding to the previously recorded number <code>valueToAdd<code>.
* If there is no previously recorded number for this level, then
* create one with index <code>level</code> and value <code>valueToAdd</code>.
* @param level The level.
* @param valueToAdd The value to add to the number of levels.
* @param enclave The enclave with which to increment the level count.
*/
private void adjustNumReactionsPerLevel(int level, int valueToAdd) {
if (numReactionsPerLevel.size() > level) {
numReactionsPerLevel.set(level, numReactionsPerLevel.get(level) + valueToAdd);
private void adjustNumReactionsPerLevel(int level, ReactorInstance enclave) {
while (numReactionsPerEnclavePerLevel.size() <= level) {
numReactionsPerEnclavePerLevel.add(new HashMap<>());
}

Map<ReactorInstance, Integer> numReactionsPerLevel = numReactionsPerEnclavePerLevel.get(level);
if (numReactionsPerLevel.containsKey(enclave)) {
numReactionsPerLevel.put(enclave, numReactionsPerLevel.get(enclave) + 1);
} else {
while (numReactionsPerLevel.size() < level) {
numReactionsPerLevel.add(0);
}
numReactionsPerLevel.add(valueToAdd);
numReactionsPerLevel.put(enclave, 1);
}
}

Expand Down
18 changes: 17 additions & 1 deletion core/src/main/java/org/lflang/generator/ReactorInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

package org.lflang.generator;

import static org.lflang.AttributeUtils.getEnclaveNumWorkersFromAttribute;
import static org.lflang.AttributeUtils.isEnclave;
import static org.lflang.ast.ASTUtils.getLiteralTimeValue;

Expand Down Expand Up @@ -774,6 +775,7 @@ protected TriggerInstance<BuiltinTriggerVariable> getOrCreateBuiltinTrigger(
trigger.getType(), ref -> TriggerInstance.builtinTrigger(trigger, this));
}

// FIXME: This appears to never be used
/** Create all the watchdog instances of this reactor instance. */
protected void createWatchdogInstances() {
List<Watchdog> watchdogs = ASTUtils.allWatchdogs(reactorDefinition);
Expand All @@ -789,6 +791,20 @@ protected void createWatchdogInstances() {
}
}

public boolean hasLocalMutex() {
if (watchdogs.size() > 0) {
return true;
}
// FIXME: How can we do this test better?
if (parent != null && parent.enclaveInfo != null) {
if (reactorDefinition.getName().equals("EnclaveConnectionReactor")) {
return true;
}
}

return false;
}

////////////////////////////////////////
//// Private constructors

Expand Down Expand Up @@ -820,7 +836,7 @@ public ReactorInstance(
// enclaveInfo object to track information about the enclave needed for
// later code-generation
if (isEnclave(definition) || this.isMainOrFederated()) {
enclaveInfo = new EnclaveInfo(this);
this.enclaveInfo = new EnclaveInfo(this, getEnclaveNumWorkersFromAttribute(definition));
}

// check for recursive instantiation
Expand Down
Loading