Skip to content

Commit

Permalink
Merge pull request #2192 from lf-lang/tracing-refactoring2
Browse files Browse the repository at this point in the history
Plugin API for tracing
  • Loading branch information
lhstrh authored Feb 27, 2024
2 parents e2d06f3 + 2a52b5c commit 5997ca5
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/custom-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
uses: marvinpinto/action-automatic-releases@latest
with:
repo_token: "${{ secrets.NIGHTLY_BUILD }}"
automatic_release_tag: '${{ github.ref_name }}-${{ github.env.timestamp }}'
automatic_release_tag: '${{ github.ref_name }}'
prerelease: true
draft: true
title: "Custom Lingua Franca build for ${{ github.ref_name }} branch"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ public static void handleCompileDefinitions(
}
definitions.put("NUMBER_OF_FEDERATES", String.valueOf(numOfFederates));
definitions.put("EXECUTABLE_PREAMBLE", "");
definitions.put("FEDERATE_ID", String.valueOf(federate.id));

CompileDefinitionsProperty.INSTANCE.update(federate.targetConfig, definitions);

Expand Down
9 changes: 9 additions & 0 deletions core/src/main/java/org/lflang/generator/c/CCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.lflang.target.property.CompilerProperty;
import org.lflang.target.property.PlatformProperty;
import org.lflang.target.property.PlatformProperty.PlatformOptions;
import org.lflang.target.property.TracePluginProperty;
import org.lflang.target.property.type.BuildTypeType.BuildType;
import org.lflang.target.property.type.PlatformType.Platform;
import org.lflang.util.FileUtil;
Expand Down Expand Up @@ -237,6 +238,14 @@ private static List<String> cmakeOptions(TargetConfig targetConfig, FileConfig f
"-DCMAKE_INSTALL_BINDIR="
+ FileUtil.toUnixString(fileConfig.getOutPath().relativize(fileConfig.binPath)),
"-DLF_FILE_SEPARATOR=\"" + maybeQuote + separator + maybeQuote + "\""));
var tracePlugin = targetConfig.getOrDefault(TracePluginProperty.INSTANCE);
if (tracePlugin != null) {
arguments.add(
"-DLF_TRACE_PLUGIN="
+ targetConfig
.getOrDefault(TracePluginProperty.INSTANCE)
.getImplementationArchiveFile());
}
// Add #define for source file directory.
// Do not do this for federated programs because for those, the definition is put
// into the cmake file (and fileConfig.srcPath is the wrong directory anyway).
Expand Down
34 changes: 28 additions & 6 deletions core/src/main/java/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -893,12 +893,14 @@ private void pickCompilePlatform() {
/** Copy target-specific header file to the src-gen directory. */
protected void copyTargetFiles() throws IOException {
Path dest = fileConfig.getSrcGenPath();
var arduino = false;
if (targetConfig.isSet(PlatformProperty.INSTANCE)) {
var platform = targetConfig.get(PlatformProperty.INSTANCE).platform();
switch (platform) {
case ARDUINO -> {
// For Arduino, alter the destination directory.
dest = dest.resolve("src");
arduino = true;
}
case ZEPHYR -> {
// For the Zephyr target, copy default config and board files.
Expand Down Expand Up @@ -927,8 +929,27 @@ protected void copyTargetFiles() throws IOException {
Path coreLib = Paths.get(context.getArgs().externalRuntimeUri());
FileUtil.copyDirectoryContents(coreLib, dest, true);
} else {
FileUtil.copyFromClassPath("/lib/c/reactor-c/core", dest, true, false);
FileUtil.copyFromClassPath("/lib/c/reactor-c/lib", dest, true, false);
for (var directory : List.of("core", "lib")) {
FileUtil.copyFromClassPath("/lib/c/reactor-c/" + directory, dest, true, false);
}
for (var directory :
List.of("logging", "platform", "low_level_platform", "trace", "version", "tag")) {
var entry = "/lib/c/reactor-c/" + directory;
if (arduino) {
if (FileConfig.class.getResource(entry + "/api") != null) {
FileUtil.copyFromClassPath(
entry + "/api",
fileConfig.getSrcGenPath().resolve("include").resolve(directory),
true,
false);
}
if (FileConfig.class.getResource(entry + "/impl") != null) {
FileUtil.copyFromClassPath(entry + "/impl", dest.resolve(directory), true, false);
}
} else {
FileUtil.copyFromClassPath(entry, dest, true, false);
}
}
}
}

Expand Down Expand Up @@ -977,7 +998,11 @@ protected void generateReactorClassHeaders(
}
header.pr("#include \"include/core/reactor.h\"");
src.pr("#include \"include/api/schedule.h\"");
src.pr("#include \"include/core/platform.h\"");
if (CPreambleGenerator.arduinoBased(targetConfig)) {
src.pr("#include \"include/low_level_platform/api/low_level_platform.h\"");
} else {
src.pr("#include \"low_level_platform/api/low_level_platform.h\"");
}
generateIncludes(tpr);
if (cppMode) {
src.pr("}");
Expand Down Expand Up @@ -1384,13 +1409,10 @@ private void recordBuiltinTriggers(ReactorInstance instance) {
if (targetConfig.get(TracingProperty.INSTANCE).isEnabled()) {
var description = CUtil.getShortenedName(reactor);
var reactorRef = CUtil.reactorRef(reactor);
var envTraceRef = CUtil.getEnvironmentStruct(reactor) + ".trace";
temp.pr(
String.join(
"\n",
"_lf_register_trace_event("
+ envTraceRef
+ ","
+ reactorRef
+ ", &("
+ reactorRef
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
public class CPreambleGenerator {

private static boolean arduinoBased(TargetConfig targetConfig) {
public static boolean arduinoBased(TargetConfig targetConfig) {
return targetConfig.isSet(PlatformProperty.INSTANCE)
&& targetConfig.get(PlatformProperty.INSTANCE).platform() == Platform.ARDUINO;
}
Expand All @@ -41,7 +41,11 @@ public static String generateIncludeStatements(TargetConfig targetConfig, boolea
code.pr("extern \"C\" {");
}
code.pr("#include <limits.h>");
code.pr("#include \"include/core/platform.h\"");
if (arduinoBased(targetConfig)) {
code.pr("#include \"include/low_level_platform/api/low_level_platform.h\"");
} else {
code.pr("#include \"low_level_platform/api/low_level_platform.h\"");
}
CCoreFilesUtils.getCTargetHeader()
.forEach(it -> code.pr("#include " + StringUtil.addDoubleQuotes(it)));
code.pr("#include \"include/core/reactor.h\"");
Expand All @@ -51,7 +55,7 @@ public static String generateIncludeStatements(TargetConfig targetConfig, boolea
}

if (targetConfig.get(TracingProperty.INSTANCE).isEnabled()) {
code.pr("#include \"include/core/trace.h\"");
code.pr("#include \"trace/api/trace.h\"");
}
code.pr("#include \"include/core/mixed_radix.h\"");
code.pr("#include \"include/core/port.h\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ public static String generateTraceTableEntries(ReactorInstance instance) {
List<String> code = new ArrayList<>();
var description = CUtil.getShortenedName(instance);
var selfStruct = CUtil.reactorRef(instance);
var envTraceRef = CUtil.getEnvironmentStruct(instance) + ".trace";
code.add(registerTraceEvent(envTraceRef, selfStruct, "NULL", "trace_reactor", description));
code.add(registerTraceEvent(selfStruct, "NULL", "trace_reactor", description));
for (ActionInstance action : instance.actions) {
code.add(
registerTraceEvent(
envTraceRef,
selfStruct,
getTrigger(selfStruct, action.getName()),
"trace_trigger",
Expand All @@ -44,7 +42,6 @@ public static String generateTraceTableEntries(ReactorInstance instance) {
for (TimerInstance timer : instance.timers) {
code.add(
registerTraceEvent(
envTraceRef,
selfStruct,
getTrigger(selfStruct, timer.getName()),
"trace_trigger",
Expand All @@ -54,10 +51,8 @@ public static String generateTraceTableEntries(ReactorInstance instance) {
}

private static String registerTraceEvent(
String envTrace, String obj, String trigger, String type, String description) {
String obj, String trigger, String type, String description) {
return "_lf_register_trace_event("
+ envTrace
+ ", "
+ obj
+ ", "
+ trigger
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/org/lflang/target/Target.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.lflang.target.property.SchedulerProperty;
import org.lflang.target.property.SingleFileProjectProperty;
import org.lflang.target.property.SingleThreadedProperty;
import org.lflang.target.property.TracePluginProperty;
import org.lflang.target.property.TracingProperty;
import org.lflang.target.property.VerifyProperty;
import org.lflang.target.property.WorkersProperty;
Expand Down Expand Up @@ -605,6 +606,7 @@ public void initialize(TargetConfig config) {
SchedulerProperty.INSTANCE,
SingleThreadedProperty.INSTANCE,
TracingProperty.INSTANCE,
TracePluginProperty.INSTANCE,
VerifyProperty.INSTANCE,
WorkersProperty.INSTANCE);
case CPP -> config.register(
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/org/lflang/target/TargetConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
*/
public class TargetConfig {

/** Error message to use when a target property does not exist in LF syntax. */
public static final String NOT_IN_LF_SYNTAX_MESSAGE =
"There is no representation of this property in the LF target property syntax";

/** The target of this configuration (e.g., C, TypeScript, Python). */
public final Target target;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ public void update(TargetConfig config, T value) {
}

/**
* Update the given configuration based on the given corresponding AST node.
* Update the given configuration based on the given corresponding AST node. If the given
* configuration does not belong in the AST, then report an error using the error message given by
* {@code TargetConfig.NOT_IN_LF_SYNTAX_MESSAGE}.
*
* @param config The configuration to update.
* @param pair The pair that holds the value to perform the update with.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.lflang.target.property;

import org.lflang.MessageReporter;
import org.lflang.lf.Element;
import org.lflang.target.TargetConfig;
import org.lflang.target.property.TracePluginProperty.TracePluginOptions;
import org.lflang.target.property.type.PrimitiveType;

/** Property that provides an alternative tracing implementation. */
public class TracePluginProperty extends TargetProperty<TracePluginOptions, PrimitiveType> {

/** Singleton target property instance. */
public static final TracePluginProperty INSTANCE = new TracePluginProperty();

private TracePluginProperty() {
super(PrimitiveType.STRING);
}

@Override
public TracePluginOptions initialValue() {
return null;
}

@Override
protected TracePluginOptions fromAst(Element node, MessageReporter reporter) {
reporter.at(node).error(TargetConfig.NOT_IN_LF_SYNTAX_MESSAGE);
return null;
}

@Override
protected TracePluginOptions fromString(String s, MessageReporter reporter) {
return new TracePluginOptions(s);
}

@Override
public String name() {
return "trace-plugin";
}

@Override
public Element toAstElement(TracePluginOptions value) {
throw new UnsupportedOperationException(TargetConfig.NOT_IN_LF_SYNTAX_MESSAGE);
}

public static class TracePluginOptions {
private final String implementationArchiveFile;

public TracePluginOptions(String implementationArchiveFile) {
this.implementationArchiveFile = implementationArchiveFile;
}

public String getImplementationArchiveFile() {
return implementationArchiveFile;
}
}
}
5 changes: 4 additions & 1 deletion core/src/main/java/org/lflang/util/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ public static void arduinoDeleteHelper(Path srcGenPath, boolean threadingOn) thr
deleteDirectory(srcGenPath.resolve("include/core/threaded"));
deleteDirectory(srcGenPath.resolve("src/core/platform/arduino_mbed"));
}
deleteDirectory(srcGenPath.resolve("src").resolve("trace"));
// Delete all the federated headers
deleteDirectory(srcGenPath.resolve("include/core/federated"));
// arduino-cli needs all headers to be under a "include" directory.
Expand Down Expand Up @@ -748,7 +749,9 @@ public static void relativeIncludeHelper(
if (path.getFileName().toString().contains("CMakeLists.txt")) continue;
if (fileStringToFilePath.put(fileName, path) != null) {
throw new IOException(
"Directory has different files with the same name. Cannot Relativize.");
String.format(
"Directory has different files with the same name (%s). Cannot relativize.",
fileName));
}
}
Pattern regexExpression = Pattern.compile("#include\s+[\"]([^\"]+)*[\"]");
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/resources/lib/c/reactor-c
Submodule reactor-c updated 106 files
1 change: 1 addition & 0 deletions core/src/main/resources/lib/platform/zephyr/prj_lf.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
# Enable the counter API used for hi-res clock
CONFIG_COUNTER=y
CONFIG_THREAD_CUSTOM_DATA=y
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.extensions.InjectionExtension;
import org.eclipse.xtext.testing.util.ParseHelper;
Expand Down Expand Up @@ -1580,7 +1581,17 @@ public Collection<DynamicTest> checkTargetProperties() throws Exception {
Model model = createModel(Target.C, property, it);
System.out.println(property.name());
System.out.println(it.toString());
validator.assertNoErrors(model);
var issues = validator.validate(model);
if (!issues.stream()
.allMatch(
issue ->
issue.getSeverity() != Severity.ERROR
|| issue
.getMessage()
.equals(TargetConfig.NOT_IN_LF_SYNTAX_MESSAGE))) {
throw new RuntimeException(
"there were unexpected errors in the generated model");
}
// Also make sure warnings are produced when files are not present.
if (type == PrimitiveType.FILE) {
validator.assertWarning(
Expand Down

0 comments on commit 5997ca5

Please sign in to comment.