Skip to content
New issue

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

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

Already on GitHub? # to your account

[c] Removal of STP violation inheritance mechanism #1251

Merged
merged 2 commits into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
154 changes: 1 addition & 153 deletions org.lflang/src/org/lflang/generator/c/CReactionGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,7 @@ public static String generateInitializationForReaction(String body,
// Next generate all the collected setup code.
code.pr(reactionInitialization.toString());
code.pr("#pragma GCC diagnostic pop");

if (reaction.getStp() == null) {
// Pass down the intended_tag to all input and output effects
// downstream if the current reaction does not have a STP
// handler.
code.pr(generateIntendedTagInheritence(body, reaction, decl, reactionIndex, types, isFederatedAndDecentralized));
}

return code.toString();
}

Expand Down Expand Up @@ -310,152 +304,6 @@ public static int maxContainedReactorBankWidth(
return result;
}

/**
* Generate code that passes existing intended tag to all output ports
* and actions. This intended tag is the minimum intended tag of the
* triggering inputs of the reaction.
*
* @param body The body of the reaction. Used to check for the DISABLE_REACTION_INITIALIZATION_MARKER.
* @param reaction The initialization code will be generated for this specific reaction
* @param decl The reactor that has the reaction
* @param reactionIndex The index of the reaction relative to other reactions in the reactor, starting from 0
*/
public static String generateIntendedTagInheritence(String body, Reaction reaction, ReactorDecl decl, int reactionIndex, CTypes types, boolean isFederatedAndDecentralized) {
// Construct the intended_tag inheritance code to go into
// the body of the function.
CodeBuilder intendedTagInheritenceCode = new CodeBuilder();
// Check if the coordination mode is decentralized and if the reaction has any effects to inherit the STP violation
if (isFederatedAndDecentralized && !(reaction.getEffects() == null || reaction.getEffects().isEmpty())) {
intendedTagInheritenceCode.pr(String.join("\n",
"#pragma GCC diagnostic push",
"#pragma GCC diagnostic ignored \"-Wunused-variable\"",
"if (self->_lf__reaction_"+reactionIndex+".is_STP_violated == true) {"
));
intendedTagInheritenceCode.indent();
intendedTagInheritenceCode.pr(String.join("\n",
"// The operations inside this if clause (if any exists) are expensive ",
"// and must only be done if the reaction has unhandled STP violation.",
"// Otherwise, all intended_tag values are (NEVER, 0) by default.",
"",
"// Inherited intended tag. This will take the minimum",
"// intended_tag of all input triggers",
types.getTargetTagType()+" inherited_min_intended_tag = ("+types.getTargetTagType()+") { .time = FOREVER, .microstep = UINT_MAX };"
));
intendedTagInheritenceCode.pr("// Find the minimum intended tag");
// Go through every trigger of the reaction and check the
// value of intended_tag to choose the minimum.
for (TriggerRef inputTrigger : ASTUtils.convertToEmptyListIfNull(reaction.getTriggers())) {
if (inputTrigger instanceof VarRef inputTriggerAsVarRef) {
Variable variable = inputTriggerAsVarRef.getVariable();
String variableName = inputTriggerAsVarRef.getVariable().getName();
if (variable instanceof Output outputPort) {
// Output from a contained reactor
String containerName = inputTriggerAsVarRef.getContainer().getName();
if (ASTUtils.isMultiport(outputPort)) {
intendedTagInheritenceCode.pr(String.join("\n",
"for (int i=0; i < "+containerName+"."+generateWidthVariable(variableName)+"; i++) {",
" if (lf_tag_compare("+containerName+"."+variableName+"[i]->intended_tag,",
" inherited_min_intended_tag) < 0) {",
" inherited_min_intended_tag = "+containerName+"."+variableName+"[i]->intended_tag;",
" }",
"}"
));
} else
intendedTagInheritenceCode.pr(String.join("\n",
"if (lf_tag_compare("+containerName+"."+variableName+"->intended_tag,",
" inherited_min_intended_tag) < 0) {",
" inherited_min_intended_tag = "+containerName+"."+variableName+"->intended_tag;",
"}"
));
} else if (variable instanceof Port inputPort) {
// Input port
if (ASTUtils.isMultiport(inputPort)) {
intendedTagInheritenceCode.pr(String.join("\n",
"for (int i=0; i < "+generateWidthVariable(variableName)+"; i++) {",
" if (lf_tag_compare("+variableName+"[i]->intended_tag, inherited_min_intended_tag) < 0) {",
" inherited_min_intended_tag = "+variableName+"[i]->intended_tag;",
" }",
"}"
));
} else {
intendedTagInheritenceCode.pr(String.join("\n",
"if (lf_tag_compare("+variableName+"->intended_tag, inherited_min_intended_tag) < 0) {",
" inherited_min_intended_tag = "+variableName+"->intended_tag;",
"}"
));
}
} else if (variable instanceof Action) {
intendedTagInheritenceCode.pr(String.join("\n",
"if (lf_tag_compare("+variableName+"->trigger->intended_tag, inherited_min_intended_tag) < 0) {",
" inherited_min_intended_tag = "+variableName+"->trigger->intended_tag;",
"}"
));
}

}
}
if (reaction.getTriggers() == null || reaction.getTriggers().size() == 0) {
// No triggers are given, which means the reaction would react to any input.
// We need to check the intended tag for every input.
// NOTE: this does not include contained outputs.
for (Input input : ((Reactor) reaction.eContainer()).getInputs()) {
intendedTagInheritenceCode.pr(String.join("\n",
"if (lf_tag_compare("+input.getName()+"->intended_tag, inherited_min_intended_tag) > 0) {",
" inherited_min_intended_tag = "+input.getName()+"->intended_tag;",
"}"
));
}
}

// Once the minimum intended tag has been found,
// it will be passed down to the port effects
// of the reaction. Note that the intended tag
// will not pass on to actions downstream.
// Last reaction that sets the intended tag for the effect
// will be seen.
intendedTagInheritenceCode.pr(String.join("\n",
"// All effects inherit the minimum intended tag of input triggers",
"if (inherited_min_intended_tag.time != NEVER) {"
));
intendedTagInheritenceCode.indent();
for (VarRef effect : ASTUtils.convertToEmptyListIfNull(reaction.getEffects())) {
Variable effectVar = effect.getVariable();
Instantiation effContainer = effect.getContainer();
if (effectVar instanceof Input) {
if (ASTUtils.isMultiport((Port) effectVar)) {
intendedTagInheritenceCode.pr(String.join("\n",
"for(int i=0; i < "+effContainer.getName()+"."+generateWidthVariable(effectVar.getName())+"; i++) {",
" "+effContainer.getName()+"."+effectVar.getName()+"[i]->intended_tag = inherited_min_intended_tag;",
"}"
));
} else {
if (effContainer.getWidthSpec() != null) {
// Contained reactor is a bank.
intendedTagInheritenceCode.pr(String.join("\n",
"for (int bankIndex = 0; bankIndex < self->_lf_"+generateWidthVariable(effContainer.getName())+"; bankIndex++) {",
" "+effContainer.getName()+"[bankIndex]."+effectVar.getName()+" = &(self->_lf_"+effContainer.getName()+"[bankIndex]."+effectVar.getName()+");",
"}"
));
} else {
// Input to a contained reaction
intendedTagInheritenceCode.pr(String.join("\n",
"// Don't reset the intended tag of the output port if it has already been set.",
effContainer.getName()+"."+effectVar.getName()+"->intended_tag = inherited_min_intended_tag;"
));
}
}
}
}
intendedTagInheritenceCode.unindent();
intendedTagInheritenceCode.pr("}");
intendedTagInheritenceCode.unindent();
intendedTagInheritenceCode.pr("#pragma GCC diagnostic pop");
intendedTagInheritenceCode.pr("}");

}
return intendedTagInheritenceCode.toString();
}

/**
* Generate code for the body of a reaction that takes an input and
* schedules an action with the value of that input.
Expand Down
108 changes: 0 additions & 108 deletions test/C/src/federated/DistributedCountDecentralizedLateDownstream.lf

This file was deleted.