Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Static scheduler #241

Draft
wants to merge 111 commits into
base: main
Choose a base branch
from
Draft
Changes from 4 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
7de874e
Bring in the FS scheduler from the manual example.
lsk567 Jun 26, 2023
48d5bbf
Merge branch 'main' into static-schedule
lsk567 Jun 26, 2023
0a76f87
Implement DU using a hyperperiod-based semantics.
lsk567 Jun 28, 2023
66b22cc
Merge branch 'main' into static-schedule
lsk567 Jun 28, 2023
2015f09
Support reactor-local time
erlingrj Jun 30, 2023
05622fd
Hide chain optimization for the FS scheduler
erlingrj Jun 30, 2023
4616369
Add the infrastructure for resetting is_present of ports on a per-rea…
erlingrj Jul 3, 2023
f3e3ba0
Merge branch 'main' into static-schedule
lsk567 Jul 6, 2023
5d79291
Merge branch 'static-schedule' into fs-erling
lsk567 Jul 10, 2023
bf504df
Merge pull request #247 from lf-lang/fs-erling
lsk567 Jul 10, 2023
bfe021d
Comment out lf_request_stop() macro
lsk567 Jul 10, 2023
3e4bd00
Change ADV to advance to absolute time wrt hyperperiod; change sync-a…
lsk567 Jul 10, 2023
995a014
Merge branch 'main' into static-schedule
lsk567 Jul 17, 2023
edcae4f
Support lf_schedule
lsk567 Jul 18, 2023
a6e08b3
Support lf_schedule with payloads, given limitations
lsk567 Jul 18, 2023
42cad35
Rename FS to STATIC
lsk567 Jul 18, 2023
e497088
Enable tracing for VM instructions
lsk567 Jul 20, 2023
6aab8ed
Remove tracing hacks
lsk567 Jul 20, 2023
d2f5c9a
Support better tracing experience by storing line numbers
lsk567 Jul 21, 2023
176b74a
Support ADDI and refactor
lsk567 Jul 21, 2023
f2cc481
Update ADV and ADV2
lsk567 Jul 21, 2023
321e17c
Update comments
lsk567 Jul 24, 2023
aafa8c7
Merge pull request #254 from lf-lang/var-refs-in-schedules
lsk567 Jul 24, 2023
402d1da
Remove variables hyperperiod and iteration
lsk567 Jul 24, 2023
fbdb4ac
Merge branch 'main' into static-schedule
lsk567 Jul 24, 2023
e606e51
Fix BIT
lsk567 Jul 24, 2023
f669991
Fix tracing
lsk567 Jul 24, 2023
26bb4af
Fix a bug when initializing time offsets
lsk567 Jul 25, 2023
26439fc
Merge branch 'main' into static-schedule
lsk567 Jul 28, 2023
e7eac8a
Merge branch 'main' into static-schedule
lsk567 Aug 6, 2023
2387ae6
Fix race condition by removing the reactor_reached_stop_tag array sin…
lsk567 Aug 6, 2023
0ffbcc4
Add branch instructions and no longer initialize offsets when initial…
lsk567 Aug 10, 2023
fc5fb2b
Remove debug message
lsk567 Aug 14, 2023
185a0ae
Merge branch 'main' into static-schedule
lsk567 Aug 15, 2023
2d3c89c
Add ADD, ADVI, JAL, JALR, and WLT instructions to deprecate SAC.
lsk567 Aug 22, 2023
ccedcab
Merge branch 'main' into static-schedule
lsk567 Aug 22, 2023
890c54e
Update PRET VM instructions to be more portable
erlingrj Sep 23, 2023
7bea24f
Merge branch 'main' into static-schedule
lsk567 Sep 25, 2023
740d5cc
Merge remote-tracking branch 'origin/static-schedule' into static-upd…
erlingrj Sep 25, 2023
ac59cfa
Merge pull request #277 from lf-lang/static-update-instr
erlingrj Sep 25, 2023
838ad16
Merge branch 'main' into static-schedule
lsk567 Oct 5, 2023
031412e
Remove unnecessary debug msg
lsk567 Oct 5, 2023
e9edc18
Add a schedule init function to deal with the compile-time constant i…
lsk567 Oct 12, 2023
d3d39e9
Extend environment for static scheduling
lsk567 Oct 16, 2023
bb5ae6d
Get a simple example to work
lsk567 Oct 16, 2023
4d32a5c
More tracepoints of the PretVM instructions
ChadliaJerad Oct 26, 2023
90e8c8b
Uncomment static scheduler trace points
ChadliaJerad Nov 12, 2023
e49225a
Merge branch 'main' into static-schedule
lsk567 Nov 15, 2023
d4a1127
Change STATIC to SCHED_STATIC
lsk567 Nov 15, 2023
ce03252
Update include guard
lsk567 Nov 20, 2023
8971b1f
Merge branch 'static-schedule' into static-schedule-explicit-triggers
lsk567 Dec 7, 2023
3e498c8
Add WIP
lsk567 Dec 14, 2023
ce9d422
Add header file for helper functions used in the static schedule
lsk567 Jan 6, 2024
0f30f05
Add WIP. SimpleConnection kind of works.
lsk567 Jan 20, 2024
2512f0c
Make SimpleConnection test case work
lsk567 Jan 25, 2024
4118922
Merge branch 'main' into static-schedule
lsk567 Feb 11, 2024
31428ab
Prune unused code in the static scheduler
lsk567 Feb 12, 2024
2fe28a6
Fix seg fault in BEQ
lsk567 Feb 25, 2024
7fd9ba0
Merge branch 'main' into static-schedule
lsk567 Feb 25, 2024
ebbdb7c
Get logical tag of EXE_starts and EXE_ends
erlingrj Feb 26, 2024
ccf50e5
Add a version of EXE tracing function specific for reactions, clean u…
lsk567 Feb 29, 2024
cac23fb
Merge pull request #367 from lf-lang/static-tracing
lsk567 Feb 29, 2024
a47356b
Update tracing and add debug flag to instructions
lsk567 Mar 6, 2024
261cb8b
Improve static tracing
lsk567 Mar 6, 2024
55bb599
Use spin wait and fix tracing
lsk567 Mar 7, 2024
57fffe1
Add WIP for chrome tracing
lsk567 Mar 9, 2024
3dbb4a1
Add WIP
lsk567 Mar 10, 2024
2d27f14
Only trace EXE now
lsk567 Mar 13, 2024
3635412
Fix unrecognized instruction error
lsk567 Mar 14, 2024
40b45dd
Implement a more flexible DU that decides between spinning and sleep …
lsk567 Mar 14, 2024
4c57e17
Increase spin wait threshold to 100 msec
lsk567 Mar 19, 2024
e27fcd9
Use spin wait for NP for fairness
lsk567 Mar 19, 2024
f783227
Merge branch 'static-schedule' into static-schedule-circular-buffer
lsk567 Mar 22, 2024
e89f09a
Use circular buffers
lsk567 Mar 22, 2024
ca533a9
Increase trace buffer and optimize circular buffer
lsk567 Mar 22, 2024
ec0f645
Increase trace buffer capacity to 64k
lsk567 Mar 22, 2024
d4af904
Drop the buffer capacity back to 32k
lsk567 Mar 22, 2024
732b13a
Drop to 16KB to try to get chrome to work
lsk567 Mar 22, 2024
4ad2cdf
Back to 32k
lsk567 Mar 22, 2024
05fcd4c
Use function pointers to execute virtual instructions. Stop tracing a…
lsk567 Mar 23, 2024
0969328
Remove tracepoints except reaction starts and stops
lsk567 Mar 23, 2024
884386e
ADVI stops clearing is_present fields
lsk567 Mar 24, 2024
bd0b5a2
Use pure spin wait in DU for evaluation
lsk567 Mar 24, 2024
c7b7285
Add useful debugging messages
lsk567 Mar 29, 2024
0e1e61b
Bump trace buffer to 128KB
lsk567 Mar 29, 2024
3a37b15
Stop setting the token field in lf_set
lsk567 Apr 7, 2024
2e0f2ff
Add debug messages back
lsk567 Apr 22, 2024
b230663
Revert "Stop setting the token field in lf_set"
lsk567 Jun 1, 2024
cd5a633
Merge branch 'static-schedule' into static-schedule-opt
lsk567 Jun 2, 2024
44313a2
Fix the incompatible conversion warning/error
lsk567 Jul 3, 2024
5f1c224
Merge branch 'static-schedule' into static-schedule-opt
lsk567 Aug 4, 2024
11dc8de
Fix JAL and update ADVI debug output
lsk567 Aug 14, 2024
7ab1111
Fix port setting for ADVI
lsk567 Aug 31, 2024
6188090
Combine spin wait and thread sleep, and adjust spin wait threshold
Sep 1, 2024
4c8f3fd
Merge branch 'main' into static-schedule
lsk567 Sep 24, 2024
d76e82e
Merge branch 'main' into static-schedule-merge
lsk567 Oct 7, 2024
08e2506
Get tracing to work and various fixes
lsk567 Oct 8, 2024
5874882
Fix tracing
lsk567 Oct 8, 2024
700835b
Remove an unused header
lsk567 Oct 9, 2024
998f555
Fix operand naming and add a debug message to BLT
lsk567 Oct 17, 2024
e8975a9
Merge branch 'main' into static-schedule
lsk567 Oct 21, 2024
51e63f6
Turn off -Werror for now
erlingrj Oct 24, 2024
1082131
Unify the semantics of ADV and ADVI
lsk567 Oct 24, 2024
1837c6c
Merge branch 'static-schedule' of https://github.com/lf-lang/reactor-…
erlingrj Oct 25, 2024
75df70f
Use lf_sleep instead of busywait
erlingrj Nov 7, 2024
9b4b818
Merge branch 'static-schedule' into static-use-lf-sleep
erlingrj Nov 7, 2024
e8f0d54
Typo
erlingrj Nov 8, 2024
6538c34
Merge pull request #495 from lf-lang/static-use-lf-sleep
lsk567 Nov 8, 2024
c63e804
Fix a race condition related to out-of-order execution
lsk567 Nov 11, 2024
75b9a50
Remove author tags for anonymity
lsk567 Nov 18, 2024
1a97ab5
Merge branch 'main' into static-schedule
lsk567 Dec 30, 2024
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
317 changes: 120 additions & 197 deletions core/threaded/scheduler_static.c
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ extern instant_t start_time;

// Global variables defined in schedule.c:
extern const inst_t* static_schedules[];
extern const long long int hyperperiod;
extern const uint64_t hyperperiod;
extern volatile uint32_t hyperperiod_iterations[];
extern volatile uint32_t counters[];
extern const size_t num_counters;
@@ -132,15 +132,91 @@ void _lf_sched_wait_for_work(
}

/**
* @brief BIT: Branch If Timeout
* Check if timeout is reached. If not, don't do anything.
* If so, jump to a specified location (rs1).
* @brief The implementation of the ADDI instruction
*/
void execute_inst_ADDI(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_ADDI_starts(scheduler->env->trace, worker_number, (int) *pc);
uint64_t *dst = (uint64_t *) rs1;
uint64_t *src = (uint64_t *) rs2;
*dst = *src + rs3;
*pc += 1; // Increment pc.
tracepoint_static_scheduler_ADDI_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief The implementation of the ADV instruction
*/
void execute_inst_ADV(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_ADV_starts(scheduler->env->trace, worker_number, (int) *pc);

// This mutex is quite expensive.
lf_mutex_lock(&(scheduler->env->mutex));

uint64_t *src = (uint64_t *)rs2;
self_base_t* reactor =
scheduler->reactor_self_instances[rs1];
reactor->tag.time = *src + rs3;
reactor->tag.microstep = 0;

// Reset all "is_present" fields of the output ports of the reactor
// Doing this here has the major implicatio that ADV has to execute AFTER
// all downstream reactions have finished. Since it is modifying state that is
// visible to thos reactions.
for (int i = 0; i<reactor->num_output_ports; i++) {
reactor->output_ports[i]->is_present = false;
}

if (_lf_is_tag_after_stop_tag(scheduler->env, reactor->tag)) {
scheduler->reactor_reached_stop_tag[rs1] = true;
}

lf_mutex_unlock(&(scheduler->env->mutex));

*pc += 1; // Increment pc.

tracepoint_static_scheduler_ADV_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief The implementation of the ADV2 instruction
*/
void execute_inst_ADV2(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_ADV2_starts(scheduler->env->trace, worker_number, (int) *pc);

uint64_t *src = (uint64_t *)rs2;
self_base_t* reactor =
scheduler->reactor_self_instances[rs1];
reactor->tag.time = *src + rs3;
reactor->tag.microstep = 0;

// Reset all "is_present" fields of the output ports of the reactor
// Doing this here has the major implicatio that ADV has to execute AFTER
// all downstream reactions have finished. Since it is modifying state that is
// visible to thos reactions.
for (int i = 0; i<reactor->num_output_ports; i++) {
reactor->output_ports[i]->is_present = false;
}

if (_lf_is_tag_after_stop_tag(scheduler->env, reactor->tag)) {
scheduler->reactor_reached_stop_tag[rs1] = true;
}

*pc += 1; // Increment pc.

tracepoint_static_scheduler_ADV2_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief The implementation of the BIT instruction
*
* FIXME: Should the timeout value be an operand?
* FIXME: Use a global variable num_active_reactors instead of iterating over
* a for loop.
*/
void execute_inst_BIT(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_BIT(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_BIT_starts(scheduler->env->trace, worker_number, (int) *pc);
bool stop = true;
@@ -156,17 +232,9 @@ void execute_inst_BIT(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief EIT: "Execute-If-Triggered"
* Check if the reaction status is "queued."
* If so, return the reaction pointer and advance pc.
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the EIT instruction
*/
void execute_inst_EIT(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_EIT(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_EIT_starts(scheduler->env->trace, worker_number, (int) *pc);
reaction_t* reaction = scheduler->reaction_instances[rs1];
@@ -181,15 +249,9 @@ void execute_inst_EIT(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief EXE: Execute a reaction
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the EXE instruction
*/
void execute_inst_EXE(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_EXE(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_EXE_starts(scheduler->env->trace, worker_number, (int) *pc);
reaction_t* reaction = scheduler->reaction_instances[rs1];
@@ -200,22 +262,16 @@ void execute_inst_EXE(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief DU: Delay Until a physical time offset (rs1) wrt the current hyperperiod is reached.
*
* @param worker_number
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the DU instruction
*/
void execute_inst_DU(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_DU(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_DU_starts(scheduler->env->trace, worker_number, (int) *pc);
// FIXME: There seems to be an overflow problem.
// When wakeup_time overflows but lf_time_physical() doesn't,
// _lf_interruptable_sleep_until_locked() terminates immediately.
instant_t wakeup_time = start_time + hyperperiod * (*iteration) + rs1;
// _lf_interruptable_sleep_until_locked() terminates immediately.
uint64_t *src = (uint64_t *)rs1;
instant_t wakeup_time = start_time + *src + rs2;
LF_PRINT_DEBUG("start_time: %lld, wakeup_time: %lld, rs1: %lld, iteration: %d, current_physical_time: %lld, hyperperiod: %lld\n", start_time, wakeup_time, rs1, (*iteration), lf_time_physical(), hyperperiod);
LF_PRINT_DEBUG("*** Worker %zu delaying", worker_number);
_lf_interruptable_sleep_until_locked(scheduler->env, wakeup_time);
@@ -225,15 +281,9 @@ void execute_inst_DU(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief WU: Wait until a counting variable reaches a specified value.
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the WU instruction
*/
void execute_inst_WU(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_WU(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_WU_starts(scheduler->env->trace, worker_number, (int) *pc);
LF_PRINT_DEBUG("*** Worker %zu waiting", worker_number);
@@ -244,90 +294,9 @@ void execute_inst_WU(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief ADV: Advance time for a reactor up to a tag (relative to the current hyperperiod).
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
*/
void execute_inst_ADV(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_ADV_starts(scheduler->env->trace, worker_number, (int) *pc);

// This mutex is quite expensive.
lf_mutex_lock(&(scheduler->env->mutex));

self_base_t* reactor =
scheduler->reactor_self_instances[rs1];
reactor->tag.time = hyperperiod * (*iteration) + rs2;
reactor->tag.microstep = 0;

// Reset all "is_present" fields of the output ports of the reactor
// Doing this here has the major implicatio that ADV has to execute AFTER
// all downstream reactions have finished. Since it is modifying state that is
// visible to thos reactions.
for (int i = 0; i<reactor->num_output_ports; i++) {
reactor->output_ports[i]->is_present = false;
}

if (_lf_is_tag_after_stop_tag(scheduler->env, reactor->tag)) {
scheduler->reactor_reached_stop_tag[rs1] = true;
}

lf_mutex_unlock(&(scheduler->env->mutex));

*pc += 1; // Increment pc.

tracepoint_static_scheduler_ADV_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief ADV: Advance time for a reactor up to a tag (relative to the current hyperperiod).
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
*/
void execute_inst_ADV2(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_ADV2_starts(scheduler->env->trace, worker_number, (int) *pc);

self_base_t* reactor =
scheduler->reactor_self_instances[rs1];
reactor->tag.time = hyperperiod * (*iteration) + rs2;
reactor->tag.microstep = 0;

// Reset all "is_present" fields of the output ports of the reactor
// Doing this here has the major implicatio that ADV has to execute AFTER
// all downstream reactions have finished. Since it is modifying state that is
// visible to thos reactions.
for (int i = 0; i<reactor->num_output_ports; i++) {
reactor->output_ports[i]->is_present = false;
}

if (_lf_is_tag_after_stop_tag(scheduler->env, reactor->tag)) {
scheduler->reactor_reached_stop_tag[rs1] = true;
}

*pc += 1; // Increment pc.

tracepoint_static_scheduler_ADV2_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief JMP: Jump to a particular line in the schedule.
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the JMP instruction
*/
void execute_inst_JMP(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_JMP(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_JMP_starts(scheduler->env->trace, worker_number, (int) *pc);
if (rs2 != -1) *iteration += 1;
@@ -336,21 +305,15 @@ void execute_inst_JMP(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief SAC: (Sync-Advance-Clear) synchronize all workers until all execute SAC
* and let the last idle worker reset all counters to 0.
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the SAC instruction
*/
void execute_inst_SAC(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_SAC(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_SAC_starts(scheduler->env->trace, worker_number, (int) *pc);

// Compute the next tag for all reactors.
instant_t next_timestamp = hyperperiod * (*iteration) + rs1;
uint64_t *src = (uint64_t *)rs1;
instant_t next_timestamp = *src + rs2;

tracepoint_worker_wait_starts(scheduler->env->trace, worker_number);
_lf_sched_wait_for_work(scheduler, worker_number, next_timestamp);
@@ -361,47 +324,9 @@ void execute_inst_SAC(lf_scheduler_t* scheduler, size_t worker_number, long long
}

/**
* @brief INC: INCrement a counter (rs1) by an amount (rs2).
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
* @brief The implementation of the STP instruction
*/
void execute_inst_INC(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_INC_starts(scheduler->env->trace, worker_number, (int) *pc);
lf_mutex_lock(&(scheduler->env->mutex));
scheduler->counters[rs1] += rs2;
lf_mutex_unlock(&(scheduler->env->mutex));
*pc += 1; // Increment pc.
tracepoint_static_scheduler_INC_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief INC2: [Lock-free] INCrement a counter (rs1) by an amount (rs2).
* The compiler needs to guarantee a single writer.
*
* @param rs1
* @param rs2
* @param pc
* @param returned_reaction
* @param exit_loop
*/
void execute_inst_INC2(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_INC2_starts(scheduler->env->trace, worker_number, (int) *pc);
scheduler->counters[rs1] += rs2;
*pc += 1; // Increment pc.
tracepoint_static_scheduler_INC2_ends(scheduler->env->trace, worker_number, (int) *pc);
}

/**
* @brief STP: SToP the execution.
*
*/
void execute_inst_STP(lf_scheduler_t* scheduler, size_t worker_number, long long int rs1, long long int rs2, size_t* pc,
void execute_inst_STP(lf_scheduler_t* scheduler, size_t worker_number, uint64_t rs1, uint64_t rs2, uint64_t rs3, size_t* pc,
reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
tracepoint_static_scheduler_STP_starts(scheduler->env->trace, worker_number, (int) *pc);
*exit_loop = true;
@@ -421,57 +346,53 @@ void execute_inst_STP(lf_scheduler_t* scheduler, size_t worker_number, long long
* @param exit_loop a pointer to a boolean indicating whether
* the outer while loop should be exited
*/
void execute_inst(lf_scheduler_t* scheduler, size_t worker_number, opcode_t op, long long int rs1, long long int rs2,
void execute_inst(lf_scheduler_t* scheduler, size_t worker_number, opcode_t op, uint64_t rs1, uint64_t rs2, uint64_t rs3,
size_t* pc, reaction_t** returned_reaction, bool* exit_loop, volatile uint32_t* iteration) {
char* op_str = NULL;
switch (op) {
case ADDI:
op_str = "ADDI";
execute_inst_ADDI(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case ADV:
op_str = "ADV";
execute_inst_ADV(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_ADV(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case ADV2:
op_str = "ADV2";
execute_inst_ADV2(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_ADV2(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case BIT:
op_str = "BIT";
execute_inst_BIT(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_BIT(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case DU:
op_str = "DU";
execute_inst_DU(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_DU(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case EIT:
op_str = "EIT";
execute_inst_EIT(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_EIT(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case EXE:
op_str = "EXE";
execute_inst_EXE(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
break;
case INC:
op_str = "INC";
execute_inst_INC(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
break;
case INC2:
op_str = "INC2";
execute_inst_INC2(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_EXE(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case JMP:
op_str = "JMP";
execute_inst_JMP(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_JMP(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case SAC:
op_str = "SAC";
execute_inst_SAC(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_SAC(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case STP:
op_str = "STP";
execute_inst_STP(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_STP(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
case WU:
op_str = "WU";
execute_inst_WU(scheduler, worker_number, rs1, rs2, pc, returned_reaction, exit_loop, iteration);
execute_inst_WU(scheduler, worker_number, rs1, rs2, rs3, pc, returned_reaction, exit_loop, iteration);
break;
default:
lf_print_error_and_exit("Invalid instruction: %d", op);
@@ -561,17 +482,19 @@ reaction_t* lf_sched_get_ready_reaction(lf_scheduler_t* scheduler, int worker_nu
bool exit_loop = false;
size_t* pc = &scheduler->pc[worker_number];
opcode_t op;
long long int rs1;
long long int rs2;
uint64_t rs1;
uint64_t rs2;
uint64_t rs3;
volatile uint32_t* iteration = &hyperperiod_iterations[worker_number];

while (!exit_loop) {
op = current_schedule[*pc].op;
rs1 = current_schedule[*pc].rs1;
rs2 = current_schedule[*pc].rs2;
rs3 = current_schedule[*pc].rs3;

// Execute the current instruction
execute_inst(scheduler, worker_number, op, rs1, rs2, pc,
execute_inst(scheduler, worker_number, op, rs1, rs2, rs3, pc,
&returned_reaction, &exit_loop, iteration);

LF_PRINT_DEBUG("Worker %d: returned_reaction = %p, exit_loop = %d",
109 changes: 73 additions & 36 deletions core/trace.c
Original file line number Diff line number Diff line change
@@ -457,75 +457,112 @@ void tracepoint_reaction_deadline_missed(trace_t* trace, reaction_t *reaction, i
tracepoint(trace, reaction_deadline_missed, reaction->self, NULL, worker, worker, reaction->number, NULL, NULL, 0, false);
}

/** Trace the start of the ADDI instruction */
void tracepoint_static_scheduler_ADDI_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADDI_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the ADV instruction */
void tracepoint_static_scheduler_ADV_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_ADV_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the ADV2 instruction */
void tracepoint_static_scheduler_ADV2_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV2_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_ADV2_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV2_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the BIT instruction */
void tracepoint_static_scheduler_BIT_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_BIT_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_BIT_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_BIT_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the DU instruction */
void tracepoint_static_scheduler_DU_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_DU_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_DU_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_DU_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the EIT instruction */
void tracepoint_static_scheduler_EIT_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EIT_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_EIT_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EIT_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the start of the EXE instruction */
void tracepoint_static_scheduler_EXE_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EXE_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_EXE_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EXE_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the start of the JMP instruction */
void tracepoint_static_scheduler_JMP_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_JMP_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_INC_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_INC_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the start of the SAC instruction */
void tracepoint_static_scheduler_SAC_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_SAC_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_INC_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_INC_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the start of the STP instruction */
void tracepoint_static_scheduler_STP_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_STP_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_INC2_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_INC2_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the start of the WU instruction */
void tracepoint_static_scheduler_WU_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_WU_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_INC2_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_INC2_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the end of the ADDI instruction */
void tracepoint_static_scheduler_ADDI_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADDI_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_JMP_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_JMP_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);

/** Trace the end of the ADV instruction */
void tracepoint_static_scheduler_ADV_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the ADV2 instruction */
void tracepoint_static_scheduler_ADV2_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_ADV2_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the BIT instruction */
void tracepoint_static_scheduler_BIT_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_BIT_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the DU instruction */
void tracepoint_static_scheduler_DU_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_DU_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the EIT instruction */
void tracepoint_static_scheduler_EIT_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EIT_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the EXE instruction */
void tracepoint_static_scheduler_EXE_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_EXE_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the JMP instruction */
void tracepoint_static_scheduler_JMP_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_JMP_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_SAC_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_SAC_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the SAC instruction */
void tracepoint_static_scheduler_SAC_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_SAC_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_STP_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_STP_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the STP instruction */
void tracepoint_static_scheduler_STP_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_STP_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
void tracepoint_static_scheduler_WU_starts(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_WU_starts, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}

/** Trace the end of the WU instruction */
void tracepoint_static_scheduler_WU_ends(trace_t* trace, int worker, int pc) {
tracepoint(trace, static_scheduler_WU_ends, NULL, NULL, worker, worker, pc, NULL, NULL, 0, false);
}
19 changes: 9 additions & 10 deletions include/core/threaded/scheduler_instructions.h
Original file line number Diff line number Diff line change
@@ -3,36 +3,35 @@
* @brief Format of the instruction set
*
* VM Instruction Set
* - ADV rs1, rs2 : ADVance the logical time of a reactor (rs1) by a specified amount (rs2). Add a delay_until here.
* - ADDI rs1, rs2, rs3 : [Lock-free] Add to an integer variable (rs2) by an amount (rs3), and store the result in a destination variable (rs1).
* - ADV rs1, rs2 : ADVance the logical time of a reactor (rs1) based on a variable offset (rs2) plus a fixed time duration (rs3).
* - ADV2 rs1, rs2 : Lock-free version of ADV. The compiler needs to guarantee only a single thread can update a reactor's tag.
* - BIT rs1, : (Branch-If-Timeout) Branch to a location (rs1) if all reactors reach timeout.
* - DU rs1, rs2 : Delay Until a physical time offset (rs1) wrt the current hyperperiod is reached.
* - DU rs1, rs2 : Delay Until the physical time reaches a variable offset (rs1) plus a fixed time duration (rs2).
* - EIT rs1 : Execute a reaction (rs1) If Triggered. FIXME: Combine with a branch.
* - EXE rs1 : EXEcute a reaction (rs1) (used for known triggers such as startup, shutdown, and timers).
* - INC rs1, rs2 : INCrement a counter (rs1) by an amount (rs2).
* - INC2 rs1, rs2 : Lock-free version of INC. The compiler needs to guarantee single writer.
* - JMP rs1 : JuMP to a location (rs1).
* - SAC : (Sync-Advance-Clear) synchronize all workers until all execute SAC and let the last idle worker reset all counters to 0.
* - SAC : (Sync-Advance-Clear) synchronize all workers until all execute SAC, let the last idle worker reset all counters to 0, and advance all reactors' logical time to a variable offset (rs1) plus a fixed time duration (rs2).
* - STP : SToP the execution.
* - WU rs1, rs2 : Wait Until a counting variable (rs1) to reach a desired value (rs2).
*/
typedef enum {
ADDI,
ADV,
ADV2,
BIT,
DU,
EIT,
EXE,
INC,
INC2,
JMP,
SAC,
STP,
WU,
} opcode_t;

typedef struct inst_t {
opcode_t op;
long long int rs1;
long long int rs2;
opcode_t op;
uint64_t rs1;
uint64_t rs2;
uint64_t rs3;
} inst_t;
55 changes: 24 additions & 31 deletions include/core/trace.h
Original file line number Diff line number Diff line change
@@ -77,26 +77,24 @@ typedef enum
scheduler_advancing_time_starts,
scheduler_advancing_time_ends,
// Static scheduler instructions
static_scheduler_ADDI_starts,
static_scheduler_ADV_starts,
static_scheduler_ADV2_starts,
static_scheduler_BIT_starts,
static_scheduler_DU_starts,
static_scheduler_EIT_starts,
static_scheduler_EXE_starts,
static_scheduler_INC_starts,
static_scheduler_INC2_starts,
static_scheduler_JMP_starts,
static_scheduler_SAC_starts,
static_scheduler_STP_starts,
static_scheduler_WU_starts,
static_scheduler_ADDI_ends,
static_scheduler_ADV_ends,
static_scheduler_ADV2_ends,
static_scheduler_BIT_ends,
static_scheduler_DU_ends,
static_scheduler_EIT_ends,
static_scheduler_EXE_ends,
static_scheduler_INC_ends,
static_scheduler_INC2_ends,
static_scheduler_JMP_ends,
static_scheduler_SAC_ends,
static_scheduler_STP_ends,
@@ -480,32 +478,29 @@ void tracepoint_scheduler_advancing_time_ends(trace_t* trace);
*/
void tracepoint_reaction_deadline_missed(trace_t* trace, reaction_t *reaction, int worker);

void tracepoint_static_scheduler_ADDI_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV2_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV2_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_BIT_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_BIT_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_DU_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_DU_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EIT_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EIT_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EXE_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EXE_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_INC_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_INC_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_INC2_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_INC2_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_JMP_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_JMP_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_SAC_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_SAC_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_STP_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_STP_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_WU_starts(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADDI_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_ADV2_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_BIT_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_DU_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EIT_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_EXE_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_JMP_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_SAC_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_STP_ends(trace_t* trace, int worker, int pc);
void tracepoint_static_scheduler_WU_ends(trace_t* trace, int worker, int pc);


/**
* Flush any buffered trace records to the trace file and
* close the files.
@@ -598,29 +593,27 @@ void tracepoint_rti_from_federate(trace_t* trace, trace_event_t event_type, int
#define tracepoint_scheduler_advancing_time_starts(...);
#define tracepoint_scheduler_advancing_time_ends(...);
#define tracepoint_reaction_deadline_missed(...);
#define tracepoint_static_scheduler_ADDI_starts(...);
#define tracepoint_static_scheduler_ADV_starts(...);
#define tracepoint_static_scheduler_ADV_ends(...);
#define tracepoint_static_scheduler_ADV2_starts(...);
#define tracepoint_static_scheduler_ADV2_ends(...);
#define tracepoint_static_scheduler_BIT_starts(...);
#define tracepoint_static_scheduler_BIT_ends(...);
#define tracepoint_static_scheduler_DU_starts(...);
#define tracepoint_static_scheduler_DU_ends(...);
#define tracepoint_static_scheduler_EIT_starts(...);
#define tracepoint_static_scheduler_EIT_ends(...);
#define tracepoint_static_scheduler_EXE_starts(...);
#define tracepoint_static_scheduler_EXE_ends(...);
#define tracepoint_static_scheduler_INC_starts(...);
#define tracepoint_static_scheduler_INC_ends(...);
#define tracepoint_static_scheduler_INC2_starts(...);
#define tracepoint_static_scheduler_INC2_ends(...);
#define tracepoint_static_scheduler_JMP_starts(...);
#define tracepoint_static_scheduler_JMP_ends(...);
#define tracepoint_static_scheduler_SAC_starts(...);
#define tracepoint_static_scheduler_SAC_ends(...);
#define tracepoint_static_scheduler_STP_starts(...);
#define tracepoint_static_scheduler_STP_ends(...);
#define tracepoint_static_scheduler_WU_starts(...);
#define tracepoint_static_scheduler_ADDI_ends(...);
#define tracepoint_static_scheduler_ADV_ends(...);
#define tracepoint_static_scheduler_ADV2_ends(...);
#define tracepoint_static_scheduler_BIT_ends(...);
#define tracepoint_static_scheduler_DU_ends(...);
#define tracepoint_static_scheduler_EIT_ends(...);
#define tracepoint_static_scheduler_EXE_ends(...);
#define tracepoint_static_scheduler_JMP_ends(...);
#define tracepoint_static_scheduler_SAC_ends(...);
#define tracepoint_static_scheduler_STP_ends(...);
#define tracepoint_static_scheduler_WU_ends(...);
#define tracepoint_federate_to_rti(...);
#define tracepoint_federate_from_rti(...);