diff --git a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt index 008bbc217b..1032a03e51 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt @@ -71,7 +71,7 @@ class RustGenerator( Files.createDirectories(fileConfig.srcGenPath) - val gen = RustModelBuilder.makeGenerationInfo(targetConfig, reactors) + val gen = RustModelBuilder.makeGenerationInfo(targetConfig, reactors, errorReporter) val codeMaps: Map = RustEmitter.generateRustProject(fileConfig, gen) if (targetConfig.noCompile || errorsOccurred()) { diff --git a/org.lflang/src/org/lflang/generator/rust/RustModel.kt b/org.lflang/src/org/lflang/generator/rust/RustModel.kt index 20f7e3eff5..12de9accfb 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustModel.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustModel.kt @@ -35,6 +35,7 @@ import java.nio.file.Path import java.util.* private typealias Ident = String +const val PARALLEL_RT_FEATURE = "parallel-runtime" /** Root model class for the entire generation. */ data class GenerationInfo( @@ -416,7 +417,7 @@ object RustModelBuilder { /** * Given the input to the generator, produce the model classes. */ - fun makeGenerationInfo(targetConfig: TargetConfig, reactors: List): GenerationInfo { + fun makeGenerationInfo(targetConfig: TargetConfig, reactors: List, errorReporter: ErrorReporter): GenerationInfo { val reactorsInfos = makeReactorInfos(reactors) // todo how do we pick the main reactor? it seems like super.doGenerate sets that field... val mainReactor = reactorsInfos.lastOrNull { it.isMain } ?: reactorsInfos.last() @@ -424,7 +425,7 @@ object RustModelBuilder { val dependencies = targetConfig.rust.cargoDependencies.toMutableMap() dependencies.compute(RustEmitterBase.runtimeCrateFullName) { _, spec -> - computeDefaultRuntimeConfiguration(spec, targetConfig) + computeDefaultRuntimeConfiguration(spec, targetConfig, errorReporter) } return GenerationInfo( @@ -452,20 +453,28 @@ object RustModelBuilder { private fun computeDefaultRuntimeConfiguration( userSpec: CargoDependencySpec?, targetConfig: TargetConfig, + errorReporter: ErrorReporter ): CargoDependencySpec { - - val userRtVersion: String? = targetConfig.runtimeVersion - if (userSpec == null) { // default configuration for the runtime crate - return if (targetConfig.externalRuntimePath != null) newCargoSpec( - gitTag = userRtVersion?.let { "v$it" }, - localPath = targetConfig.externalRuntimePath, - ) else newCargoSpec( - gitRepo = RustEmitterBase.runtimeGitUrl, + + val userRtVersion: String? = targetConfig.runtimeVersion + // enable parallel feature if asked + val parallelFeature = listOf(PARALLEL_RT_FEATURE).takeIf { targetConfig.threading } + + val spec = newCargoSpec( gitTag = userRtVersion?.let { "v$it" }, - rev = runtimeGitRevision.takeIf { userRtVersion == null }, + features = parallelFeature, ) + + if (targetConfig.externalRuntimePath != null) { + spec.localPath = targetConfig.externalRuntimePath + } else { + spec.gitRepo = RustEmitterBase.runtimeGitUrl + spec.rev = runtimeGitRevision.takeIf { userRtVersion == null } + } + + return spec } else { if (userSpec.localPath == null && userSpec.gitRepo == null) { // default the location @@ -481,6 +490,15 @@ object RustModelBuilder { userSpec.localPath = targetConfig.externalRuntimePath } + // enable parallel feature if asked + if (targetConfig.threading && PARALLEL_RT_FEATURE !in userSpec.features) { + userSpec.features += PARALLEL_RT_FEATURE + } + + if (!targetConfig.threading && PARALLEL_RT_FEATURE in userSpec.features) { + errorReporter.reportWarning("Threading cannot be disabled as it was enabled manually as a runtime feature.") + } + return userSpec } } diff --git a/org.lflang/src/org/lflang/generator/rust/rust-runtime-version.txt b/org.lflang/src/org/lflang/generator/rust/rust-runtime-version.txt index 47fd52adad..1ba61dbda9 100644 --- a/org.lflang/src/org/lflang/generator/rust/rust-runtime-version.txt +++ b/org.lflang/src/org/lflang/generator/rust/rust-runtime-version.txt @@ -1 +1 @@ -f35bcc79a5422eae256e9082314a05e9b4530bc4 +0100686e1d0fcf648f7979e0fca2017e6b33a9a6 diff --git a/test/Rust/src-gen/Cargo.toml b/test/Rust/src-gen/Cargo.toml index 1032fcac06..7a501e570e 100644 --- a/test/Rust/src-gen/Cargo.toml +++ b/test/Rust/src-gen/Cargo.toml @@ -16,7 +16,7 @@ # If it causes problems, we can throw it away or hide it. [workspace] members = ["*"] -exclude = ["target", "multiport", "generics"] +exclude = ["concurrent", "target", "multiport", "generics"] [profile.release-with-min-size] # use `build-type: MinSizeRel` inherits = "release" diff --git a/test/Rust/src/concurrent/Workers.lf b/test/Rust/src/concurrent/Workers.lf new file mode 100644 index 0000000000..ed2cb125ff --- /dev/null +++ b/test/Rust/src/concurrent/Workers.lf @@ -0,0 +1,10 @@ +target Rust { workers: 16 }; +main reactor { + reaction(startup) {= + if (ctx.num_workers() != 16) { + panic!("Expected to have 16 workers."); + } else { + println!("Using 16 workers."); + } + =} +} \ No newline at end of file