Skip to content

Commit b074e4e

Browse files
authored
Have LFC correctly generate the needed size of the event and reaction queue (#135)
* Remove any platform specific code in code-generated CMakeLists * Fix FlexPRET * Dump working changes * Minimum reaction and event queue size is 1 * Ironing out the final wrinkles
1 parent 3eb9517 commit b074e4e

File tree

10 files changed

+82
-15
lines changed

10 files changed

+82
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ target_compile_definitions(reactor-uc PRIVATE "PLATFORM_${PLATFORM}")
8181
target_compile_definitions(reactor-uc PRIVATE "SCHEDULER_${SCHEDULER}")
8282

8383
# Add compile definitions for event and reaction queue sizes. Has to be PUBLIC because they are used in the header files.
84+
message(STATUS "Setting event queue size to ${EVENT_QUEUE_SIZE} and reaction queue size to ${REACTION_QUEUE_SIZE}")
8485
target_compile_definitions(reactor-uc PUBLIC EVENT_QUEUE_SIZE=${EVENT_QUEUE_SIZE})
8586
target_compile_definitions(reactor-uc PUBLIC REACTION_QUEUE_SIZE=${REACTION_QUEUE_SIZE})
8687

@@ -95,7 +96,6 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
9596
target_compile_options(reactor-uc PUBLIC -Wno-zero-length-bounds -Wno-stack-usage)
9697
endif()
9798

98-
9999
add_compile_options (-fdiagnostics-color=always)
100100
target_include_directories(reactor-uc PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ${CMAKE_CURRENT_LIST_DIR}/external)
101101

lfc/core/src/main/java/org/lflang/target/TargetConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
*
6464
* @author Marten Lohstroh
6565
*/
66-
public class TargetConfig {
66+
public class TargetConfig {
6767

6868
/** Error message to use when a target property does not exist in LF syntax. */
6969
public static final String NOT_IN_LF_SYNTAX_MESSAGE =

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcActionGenerator.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,26 @@ import org.lflang.generator.uc.UcReactorGenerator.Companion.getSources
1212
import org.lflang.lf.*
1313

1414
class UcActionGenerator(private val reactor: Reactor) {
15-
private val Action.bufSize
16-
get(): Int = 12 // FIXME: This should be annotated in the LF code
15+
16+
companion object {
17+
public val Action.maxNumPendingEvents
18+
get(): Int = 12 // FIXME: This should be annotated in the LF code
19+
}
1720

1821
/** Returns the C Enum representing the type of action.*/
1922
private val Action.actionType
2023
get(): String = if (isPhysical) "PHYSICAL_ACTION" else "LOGICAL_ACTION"
2124

2225
private fun generateSelfStruct(action: Action) = with(PrependOperator) {
2326
"""
24-
|DEFINE_ACTION_STRUCT${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.bufSize} ${if (action.type != null) ", ${action.type.toText()}" else ""});
27+
|DEFINE_ACTION_STRUCT${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents} ${if (action.type != null) ", ${action.type.toText()}" else ""});
2528
|
2629
""".trimMargin()
2730
}
2831

2932
private fun generateCtor(action: Action) = with(PrependOperator) {
3033
"""
31-
|DEFINE_ACTION_CTOR${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.bufSize} ${if (action.type != null) ", ${action.type.toText()}" else ""});
34+
|DEFINE_ACTION_CTOR${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents} ${if (action.type != null) ", ${action.type.toText()}" else ""});
3235
|
3336
""".trimMargin()
3437
}

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ package org.lflang.generator.uc
44
import org.lflang.FileConfig
55
import org.lflang.target.TargetConfig
66
import org.lflang.generator.PrependOperator
7+
import org.lflang.generator.uc.UcReactorGenerator.Companion.getEventQueueSize
8+
import org.lflang.generator.uc.UcReactorGenerator.Companion.getReactionQueueSize
79
import org.lflang.joinWithLn
10+
import org.lflang.lf.Reactor
811
import org.lflang.target.property.BuildTypeProperty
912
import org.lflang.target.property.PlatformProperty
1013
import org.lflang.target.property.type.PlatformType
1114
import org.lflang.toUnixString
1215
import org.lflang.unreachable
16+
import org.lflang.util.FileUtil
1317
import java.nio.file.Path
18+
import java.time.LocalDateTime
19+
import kotlin.math.max
1420

15-
class UcCmakeGenerator(private val targetConfig: TargetConfig, private val fileConfig: FileConfig) {
21+
class UcCmakeGenerator(private val main: Reactor, private val targetConfig: TargetConfig, private val fileConfig: FileConfig) {
1622
private val S = '$' // a little trick to escape the dollar sign with $S
1723
private val platform = targetConfig.get(PlatformProperty.INSTANCE).platform
1824

@@ -33,6 +39,9 @@ class UcCmakeGenerator(private val targetConfig: TargetConfig, private val fileC
3339
|)
3440
|set(REACTOR_UC_PATH $S{CMAKE_CURRENT_LIST_DIR}/reactor-uc)
3541
|set(LF_INCLUDE_DIRS $S{CMAKE_CURRENT_LIST_DIR})
42+
|set(REACTION_QUEUE_SIZE ${main.getReactionQueueSize()} CACHE STRING "Size of the reaction queue")
43+
|set(EVENT_QUEUE_SIZE ${main.getEventQueueSize()} CACHE STRING "Size of the event queue")
44+
|
3645
""".trimMargin()
3746
}
3847

@@ -41,6 +50,8 @@ class UcCmakeGenerator(private val targetConfig: TargetConfig, private val fileC
4150
|cmake_minimum_required(VERSION 3.5)
4251
|project(${fileConfig.name} VERSION 0.0.0 LANGUAGES C)
4352
|set(PLATFORM POSIX CACHE STRING "Target platform")
53+
|set(REACTION_QUEUE_SIZE ${max(main.getReactionQueueSize(), 1)} CACHE STRING "Size of the reaction queue")
54+
|set(EVENT_QUEUE_SIZE ${max(main.getEventQueueSize(), 1)} CACHE STRING "Size of the event queue")
4455
|
4556
|set(LF_MAIN_TARGET ${fileConfig.name})
4657
|set(SOURCES

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcConnectionGenerator.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class UcGroupedConnection(val varRef: VarRef, val conn: Connection, val uid: Int
1919
val bankWidth = srcInst?.width?:1
2020
val portWidth = srcPort.width
2121
val uniqueName = "conn_${srcInst?.name?:""}_${srcPort.name}_${uid}"
22-
val bufSize = 16
22+
val maxNumPendingEvents = 16 // FIXME: Must be derived from the program
2323

2424
val delay = conn.delay.orNever().toCCode()
2525
val isPhysical = conn.isPhysical
@@ -179,8 +179,8 @@ class UcConnectionGenerator(private val reactor: Reactor) {
179179
private fun generateLogicalSelfStruct(conn: UcGroupedConnection) = "DEFINE_LOGICAL_CONNECTION_STRUCT(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()})";
180180
private fun generateLogicalCtor(conn: UcGroupedConnection) = "DEFINE_LOGICAL_CONNECTION_CTOR(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()})";
181181

182-
private fun generateDelayedSelfStruct(conn: UcGroupedConnection) = "DEFINE_DELAYED_CONNECTION_STRUCT(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()}, ${conn.srcPort.type.toText()}, ${conn.bufSize}, ${conn.delay})";
183-
private fun generateDelayedCtor(conn: UcGroupedConnection) = "DEFINE_DELAYED_CONNECTION_CTOR(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()}, ${conn.srcPort.type.toText()}, ${conn.bufSize}, ${conn.delay}, ${conn.isPhysical})";
182+
private fun generateDelayedSelfStruct(conn: UcGroupedConnection) = "DEFINE_DELAYED_CONNECTION_STRUCT(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()}, ${conn.srcPort.type.toText()}, ${conn.maxNumPendingEvents}, ${conn.delay})";
183+
private fun generateDelayedCtor(conn: UcGroupedConnection) = "DEFINE_DELAYED_CONNECTION_CTOR(${reactor.codeType}, ${conn.uniqueName}, ${conn.numDownstreams()}, ${conn.srcPort.type.toText()}, ${conn.maxNumPendingEvents}, ${conn.delay}, ${conn.isPhysical})";
184184

185185

186186
private fun generateReactorCtorCode(conn: UcGroupedConnection) = with(PrependOperator) {
@@ -216,4 +216,14 @@ class UcConnectionGenerator(private val reactor: Reactor) {
216216
if (it.isLogical) "LOGICAL_CONNECTION_INSTANCE(${reactor.codeType}, ${it.uniqueName}, ${it.bankWidth}, ${it.portWidth});"
217217
else "DELAYED_CONNECTION_INSTANCE(${reactor.codeType}, ${it.uniqueName}, ${it.bankWidth}, ${it.portWidth});"
218218
}
219+
220+
fun getMaxNumPendingEvents(): Int {
221+
var res = 0
222+
for (conn in ucConnections.connections) {
223+
if (!conn.isLogical) {
224+
res += conn.maxNumPendingEvents
225+
}
226+
}
227+
return res
228+
}
219229
}

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMakeGenerator.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,25 @@ package org.lflang.generator.uc
33
import org.lflang.FileConfig
44
import org.lflang.target.TargetConfig
55
import org.lflang.generator.PrependOperator
6+
import org.lflang.generator.uc.UcReactorGenerator.Companion.getEventQueueSize
7+
import org.lflang.generator.uc.UcReactorGenerator.Companion.getReactionQueueSize
68
import org.lflang.joinWithLn
9+
import org.lflang.lf.Reactor
710
import org.lflang.target.property.BuildTypeProperty
811
import org.lflang.toUnixString
912
import java.nio.file.Path
13+
import java.time.LocalDateTime
14+
import kotlin.math.max
1015

11-
class UcMakeGenerator(private val targetConfig: TargetConfig, private val fileConfig: FileConfig) {
16+
class UcMakeGenerator(private val main: Reactor, private val targetConfig: TargetConfig, private val fileConfig: FileConfig) {
1217
private val S = '$' // a little trick to escape the dollar sign with $S
1318
fun generateMake(sources: List<Path>) = with(PrependOperator) {
1419
"""
1520
| # Makefile genrated for ${fileConfig.name}
1621
|LF_SOURCES = \
1722
${" | "..sources.joinWithLn { it.toUnixString() + " \\ "}}
23+
|REACTION_QUEUE_SIZE = ${max(main.getReactionQueueSize(), 1)}
24+
|EVENT_QUEUE_SIZE = ${max(main.getEventQueueSize(), 1)}
1825
|
1926
""".trimMargin()
2027
}

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcReactorGenerator.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package org.lflang.generator.uc
22

33
import org.lflang.MessageReporter
44
import org.lflang.generator.PrependOperator
5+
import org.lflang.generator.uc.UcActionGenerator.Companion.maxNumPendingEvents
56
import org.lflang.generator.uc.UcInstanceGenerator.Companion.width
67
import org.lflang.generator.uc.UcPortGenerator.Companion.width
78
import org.lflang.lf.*
9+
import org.lflang.reactor
810
import org.lflang.toUnixString
911

1012
class UcReactorGenerator(private val reactor: Reactor, fileConfig: UcFileConfig, messageReporter: MessageReporter) {
@@ -73,9 +75,42 @@ class UcReactorGenerator(private val reactor: Reactor, fileConfig: UcFileConfig,
7375

7476
fun Reactor.getObservers(v: BuiltinTrigger) =
7577
reactions.filter { it.sources.filter { it.name == v.literal }.isNotEmpty() }
78+
79+
fun Reactor.getEventQueueSize(): Int {
80+
var childrenEvents = 0
81+
for (child in this.instantiations) {
82+
childrenEvents += child.reactor.getEventQueueSize()*child.width
83+
}
84+
var currentReactorsEvents = 0
85+
for (timer in this.timers) {
86+
currentReactorsEvents += 1
87+
}
88+
for (action in this.actions) {
89+
currentReactorsEvents += action.maxNumPendingEvents
90+
}
91+
92+
if (hasShutdown) currentReactorsEvents += 1
93+
if (hasStartup) currentReactorsEvents += 1
94+
95+
val ucConnections = UcConnectionGenerator(this)
96+
currentReactorsEvents += ucConnections.getMaxNumPendingEvents()
97+
return childrenEvents + currentReactorsEvents
98+
}
99+
100+
fun Reactor.getReactionQueueSize(): Int {
101+
var res = 0
102+
for (child in instantiations) {
103+
res += child.reactor.getReactionQueueSize() * child.width
104+
}
105+
res += reactions.size
106+
return res
107+
}
108+
76109
}
77110

78111

112+
113+
79114
private fun generateReactorStruct() = with(PrependOperator) {
80115
"""
81116
|typedef struct {

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcStandaloneGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class UcStandaloneGenerator(generator: UcGenerator, val srcGenPath: Path) :
4646
FileUtil.writeToFile(mainCodeMap.generatedCode, srcGenPath.resolve(mainSourceFile), true)
4747
FileUtil.writeToFile(mainGenerator.generateMainHeader(), srcGenPath.resolve(mainHeaderFile), true)
4848

49-
val cmakeGenerator = UcCmakeGenerator(targetConfig, generator.fileConfig)
50-
val makeGenerator = UcMakeGenerator(targetConfig, generator.fileConfig)
49+
val cmakeGenerator = UcCmakeGenerator(mainReactor, targetConfig, generator.fileConfig)
50+
val makeGenerator = UcMakeGenerator(mainReactor, targetConfig, generator.fileConfig)
5151
val pkgName = fileConfig.srcGenPkgPath.fileName.toString()
5252
FileUtil.writeToFile(cmakeGenerator.generateCmake(ucSources), srcGenPath.resolve("CMakeLists.txt"), true)
5353
val runtimeSymlinkPath: Path = srcGenPath.resolve("reactor-uc");

src/queues.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lf_ret_t EventQueue_insert(EventQueue *self, Event *event) {
2020
event->tag.microstep);
2121
if (self->size >= EVENT_QUEUE_SIZE) {
2222
LF_ERR(QUEUE, "EventQueue is full");
23+
assert(false);
2324
return LF_OUT_OF_BOUNDS;
2425
}
2526

src/reaction.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ static size_t calculate_port_level(Port *port) {
1717
if (final_upstream_port) {
1818
for (size_t k = 0; k < final_upstream_port->sources.size; k++) {
1919
Reaction *upstream = final_upstream_port->sources.reactions[k];
20-
size_t upstream_level = upstream->get_level(upstream) + 1;
20+
size_t upstream_level = upstream->get_level(upstream);
2121
if (upstream_level > current) {
2222
current = upstream_level;
2323
}
@@ -27,7 +27,7 @@ static size_t calculate_port_level(Port *port) {
2727

2828
for (size_t i = 0; i < port->sources.size; i++) {
2929
Reaction *source = port->sources.reactions[i];
30-
size_t source_level = source->get_level(source) + 1;
30+
size_t source_level = source->get_level(source);
3131
if (source_level > current) {
3232
current = source_level;
3333
}

0 commit comments

Comments
 (0)