Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8d0a19a
Connect to persistent federates only during initialization
ChadliaJerad Mar 27, 2026
59ae4ec
Add a per-federate transients[] bool array to , indicating whether ea…
ChadliaJerad Mar 27, 2026
d39bf03
Add to federates an attribute with the number of outbound p2p connect…
ChadliaJerad Mar 29, 2026
2ba4931
Add tests for transients with decentralized coordination
ChadliaJerad Apr 1, 2026
d30ec42
Add the federate type when code printing the call to lf_connect_to_fe…
ChadliaJerad Apr 2, 2026
6790fea
Clean code i CExtension.java and add STP_offsets to federates with up…
ChadliaJerad Apr 2, 2026
98140a1
Update generated federate attributes + Align reactor-c
ChadliaJerad Apr 2, 2026
9032a7c
Fix 'Attempt to update to earlier t
ChadliaJerad Apr 2, 2026
0c4abf4
Testing transients with physical connections
ChadliaJerad Apr 3, 2026
c8d2627
Use less attributes and less iteratin by using outbound_p2p_connectio…
ChadliaJerad Apr 3, 2026
c4c0821
Better names and align reactor-c
ChadliaJerad Apr 4, 2026
343346d
Apply spotless and align reactor-c
ChadliaJerad Apr 4, 2026
bf6fb3d
Merge branch 'transient-fed' of github.com:lf-lang/lingua-franca into…
Jakio815 Apr 7, 2026
a91bd2a
Update reactor-c
Jakio815 Apr 7, 2026
8d47fb2
Update reactor-c
Jakio815 Apr 7, 2026
2bb7a8a
Update reactor-c
Jakio815 Apr 8, 2026
b13944f
Align reactor-c
ChadliaJerad Apr 10, 2026
3fb1a50
Merge branch 'transient-fed' of github.com:lf-lang/lingua-franca into…
Jakio815 Apr 16, 2026
9b67653
Merge branch 'transient-fed-dec' of github.com:lf-lang/lingua-franca …
Jakio815 Apr 16, 2026
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
52 changes: 42 additions & 10 deletions core/src/main/java/org/lflang/federated/extensions/CExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,12 @@ public String getNetworkBufferType() {
/** Put the C preamble in a `include/_federate.name + _preamble.h` file. */
protected final void writePreambleFile(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter)
throws IOException {
String cPreamble = makePreamble(federate, rtiConfig, messageReporter);
String cPreamble = makePreamble(federate, allFederates, rtiConfig, messageReporter);
String relPath = getPreamblePath(federate);
Path fedPreamblePath = fileConfig.getSrcPath().resolve(relPath);
Files.createDirectories(fedPreamblePath.getParent());
Expand All @@ -509,11 +510,12 @@ protected final void writePreambleFile(
@Override
public String generatePreamble(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter)
throws IOException {
writePreambleFile(federate, fileConfig, rtiConfig, messageReporter);
writePreambleFile(federate, allFederates, fileConfig, rtiConfig, messageReporter);
var includes = new CodeBuilder();
includes.pr(
"""
Expand All @@ -539,7 +541,10 @@ public String generatePreamble(

/** Generate the preamble to setup federated execution in C. */
protected String makePreamble(
FederateInstance federate, RtiConfig rtiConfig, MessageReporter messageReporter) {
FederateInstance federate,
List<FederateInstance> allFederates,
RtiConfig rtiConfig,
MessageReporter messageReporter) {

var code = new CodeBuilder();

Expand Down Expand Up @@ -609,7 +614,7 @@ protected String makePreamble(
"""
.formatted(numOfSTAAOffsets)));

code.pr(generateExecutablePreamble(federate, rtiConfig, messageReporter));
code.pr(generateExecutablePreamble(federate, allFederates, rtiConfig, messageReporter));

code.pr(generateSTAAInitialization(federate));

Expand Down Expand Up @@ -663,12 +668,15 @@ private String generateInitializeTriggers(

/** Generate code for an executed preamble. */
private String generateExecutablePreamble(
FederateInstance federate, RtiConfig rtiConfig, MessageReporter messageReporter) {
FederateInstance federate,
List<FederateInstance> allFederates,
RtiConfig rtiConfig,
MessageReporter messageReporter) {
CodeBuilder code = new CodeBuilder();

code.pr(generateCodeForPhysicalActions(federate, messageReporter));

code.pr(generateCodeToInitializeFederate(federate, rtiConfig, messageReporter));
code.pr(generateCodeToInitializeFederate(federate, allFederates, rtiConfig, messageReporter));
return """
void _lf_executable_preamble(environment_t* env) {
%s
Expand Down Expand Up @@ -698,7 +706,10 @@ void staa_initialization() {
* @return The generated code
*/
private String generateCodeToInitializeFederate(
FederateInstance federate, RtiConfig rtiConfig, MessageReporter messageReporter) {
FederateInstance federate,
List<FederateInstance> allFederates,
RtiConfig rtiConfig,
MessageReporter messageReporter) {
CodeBuilder code = new CodeBuilder();
code.pr("// ***** Start initializing the federated execution. */");
code.pr(
Expand Down Expand Up @@ -758,18 +769,30 @@ else if (globalSTP instanceof CodeExprImpl)
// thread without requiring a mutex lock.
var numberOfInboundConnections = federate.inboundP2PConnections.size();
var numberOfOutboundConnections = federate.outboundP2PConnections.size();
var numberOfInboundConnectionsToTransients =
(int) federate.inboundP2PConnections.stream().filter(f -> f.isTransient).count();
var numberOfOutboundConnectionsToTransients =
(int) federate.outboundP2PConnections.stream().filter(f -> f.isTransient).count();

code.pr(
String.join(
"\n",
"_fed.number_of_inbound_p2p_connections = " + numberOfInboundConnections + ";",
"_fed.number_of_outbound_p2p_connections = " + numberOfOutboundConnections + ";"));
"_fed.number_of_outbound_p2p_connections = " + numberOfOutboundConnections + ";",
"_fed.number_of_inbound_p2p_transients = "
+ numberOfInboundConnectionsToTransients
+ ";",
"_fed.number_of_outbound_p2p_transients = "
+ numberOfOutboundConnectionsToTransients
+ ";"));

code.pr(
String.join(
"\n",
"// Initialize the array of network abstractions for incoming connections to -1.",
"for (int i = 0; i < NUMBER_OF_FEDERATES; i++) {",
" _fed.net_for_inbound_p2p_connections[i] = NULL;",
" _fed.inbound_p2p_connection_is_transient[i] = false;",
"}"));
code.pr(
String.join(
Expand All @@ -778,6 +801,7 @@ else if (globalSTP instanceof CodeExprImpl)
"for (int i = 0; i < NUMBER_OF_FEDERATES; i++) {",
" _fed.net_for_outbound_p2p_connections[i] = NULL;",
"}"));

var clockSyncOptions = federate.targetConfig.getOrDefault(ClockSyncOptionsProperty.INSTANCE);
// If a test clock offset has been specified, insert code to set it here.
if (clockSyncOptions.testOffset != null) {
Expand Down Expand Up @@ -819,13 +843,21 @@ else if (globalSTP instanceof CodeExprImpl)
"// This is done in a separate thread because this thread will call",
"// lf_connect_to_federate for each outbound connection at the same",
"// time that the new thread is listening for such connections for inbound",
"// connections. The thread will live until all connections have been established.",
"// connections. The thread will live until all connections have been established,",
"// or if outbound connections are transient, until the end of the execution.",
"lf_thread_create(&_fed.inbound_p2p_handling_thread_id,"
+ " lf_handle_p2p_connections_from_federates, env);"));
}

for (FederateInstance remoteFederate : federate.outboundP2PConnections) {
code.pr("lf_connect_to_federate(" + remoteFederate.id + ");");
code.pr(
"lf_connect_to_federate(" + remoteFederate.id + ", " + remoteFederate.isTransient + ");");
code.pr(
"_fed.outbound_p2p_connection_is_transient["
+ remoteFederate.id
+ "] = "
+ remoteFederate.isTransient
+ ";");
}
return code.getCode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ default void annotateReaction(Reaction reaction) {}
* Add preamble to the source to set up federated execution.
*
* @param federate The federate to which the generated setup code will correspond.
* @param allFederates The list of all federates in the federation.
* @param fileConfig The federation file configuration.
* @param rtiConfig The settings of the RTI.
* @param messageReporter Used to report errors and warnings.
*/
String generatePreamble(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.lflang.federated.extensions;

import java.io.IOException;
import java.util.List;
import org.lflang.InferredType;
import org.lflang.MessageReporter;
import org.lflang.ast.ASTUtils;
Expand Down Expand Up @@ -261,11 +262,12 @@ public void annotateReaction(Reaction reaction) {
@Override
public String generatePreamble(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter)
throws IOException {
writePreambleFile(federate, fileConfig, rtiConfig, messageReporter);
writePreambleFile(federate, allFederates, fileConfig, rtiConfig, messageReporter);
return "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ public String getNetworkBufferType() {
@Override
public String generatePreamble(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ public FedEmitter(

/** Generate a .lf file for federate `federate`. */
Map<Path, CodeMap> generateFederate(
LFGeneratorContext context, FederateInstance federate, List<String> federateNames)
LFGeneratorContext context,
FederateInstance federate,
List<FederateInstance> allFederates,
List<String> federateNames)
throws IOException {
String fedName = federate.name;
Files.createDirectories(fileConfig.getSrcPath());
Expand All @@ -57,7 +60,7 @@ Map<Path, CodeMap> generateFederate(
context, federateNames, federate, fileConfig, messageReporter, rtiConfig),
new FedImportEmitter().generateImports(federate, fileConfig),
new FedPreambleEmitter()
.generatePreamble(federate, fileConfig, rtiConfig, messageReporter),
.generatePreamble(federate, allFederates, fileConfig, rtiConfig, messageReporter),
new FedReactorEmitter().generateReactorDefinitions(federate),
new FedMainEmitter()
.generateMainReactor(federate, originalMainReactor, messageReporter));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public boolean doGenerate(Resource resource, LFGeneratorContext context) throws
fedEmitter.generateFederate(
context,
federate,
federates,
federates.stream().map(fed -> fed.name).collect(Collectors.toList())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.lflang.ast.ASTUtils.toText;

import java.io.IOException;
import java.util.List;
import org.lflang.MessageReporter;
import org.lflang.ast.ASTUtils;
import org.lflang.federated.extensions.FedTargetExtensionFactory;
Expand All @@ -26,6 +27,7 @@ public FedPreambleEmitter() {}
*/
String generatePreamble(
FederateInstance federate,
List<FederateInstance> allFederates,
FederationFileConfig fileConfig,
RtiConfig rtiConfig,
MessageReporter messageReporter)
Expand Down Expand Up @@ -53,7 +55,8 @@ String generatePreamble(
=}"""
.formatted(
FedTargetExtensionFactory.getExtension(federate.targetConfig.target)
.generatePreamble(federate, fileConfig, rtiConfig, messageReporter)));
.generatePreamble(
federate, allFederates, fileConfig, rtiConfig, messageReporter)));

return preambleCode.getCode();
}
Expand Down
Loading
Loading