From 6aa7f922ad39b07f2fc99a0ce764d665f71e19bf Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 1 Nov 2024 21:58:48 -0700 Subject: [PATCH 1/4] Add DECLARE_CTOR macro --- include/reactor-uc/macros.h | 56 ++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/include/reactor-uc/macros.h b/include/reactor-uc/macros.h index fc9307e57..32ecf3faa 100644 --- a/include/reactor-uc/macros.h +++ b/include/reactor-uc/macros.h @@ -60,8 +60,8 @@ #define REACTION_REGISTER_EFFECT(reaction, effect) \ do { \ Reaction *__reaction = (Reaction *)&(reaction); \ - assert((__reaction)->effects_registered < (__reaction)->effects_size); \ - (__reaction)->effects[(__reaction)->effects_registered++] = (Trigger *)&(effect); \ + assert(__reaction->effects_registered < __reaction->effects_size); \ + __reaction->effects[__reaction->effects_registered++] = (Trigger *)&(effect); \ } while (0) // Register a reaction as a source of a trigger. `trigger` must be a pointer to @@ -104,8 +104,11 @@ Connection *conns_out[NumConnsOut]; \ } PortName; +#define DECLARE_OUTPUT_PORT_CTOR(PortName, SourceSize) \ + void PortName##_ctor(PortName *self, Reactor *parent, Connection **conn_out, size_t conn_num) + #define DEFINE_OUTPUT_PORT_CTOR(PortName, SourceSize) \ - void PortName##_ctor(PortName *self, Reactor *parent, Connection **conn_out, size_t conn_num) { \ + DECLARE_OUTPUT_PORT_CTOR(PortName, SourceSize) { \ Output_ctor(&self->super, parent, self->sources, SourceSize, conn_out, conn_num); \ } @@ -116,9 +119,11 @@ BufferType value; \ Connection *conns_out[(NumConnsOut)]; \ } PortName; +#define DECLARE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) \ + void PortName##_ctor(PortName *self, Reactor *parent) #define DEFINE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) \ - void PortName##_ctor(PortName *self, Reactor *parent) { \ + DECLARE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) { \ Input_ctor(&self->super, parent, self->effects, (EffectSize), (Connection **)&self->conns_out, NumConnsOut, \ &self->value, sizeof(BufferType)); \ } @@ -129,13 +134,19 @@ Reaction *effects[(EffectSize)]; \ } TimerName; +#define DECLARE_TIMER_CTOR(TimerName, EffectSize) \ + void TimerName##_ctor(TimerName *self, Reactor *parent, interval_t offset, interval_t period) + #define DEFINE_TIMER_CTOR(TimerName, EffectSize) \ - void TimerName##_ctor(TimerName *self, Reactor *parent, interval_t offset, interval_t period) { \ + DECLARE_TIMER_CTOR(TimerName, EffectSize) { \ Timer_ctor(&self->super, parent, offset, period, self->effects, EffectSize); \ } +#define DECLARE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) \ + void TimerName##_ctor(TimerName *self, Reactor *parent) + #define DEFINE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) \ - void TimerName##_ctor(TimerName *self, Reactor *parent) { \ + DECLARE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) { \ Timer_ctor(&self->super, parent, Offset, Period, self->effects, EffectSize); \ } @@ -148,8 +159,11 @@ #define DEFINE_REACTION_BODY(ReactorName, ReactionIndex) \ void ReactorName##_Reaction##ReactionIndex##_body(Reaction *_self) +#define DECLARE_REACTION_CTOR(ReactorName, ReactionIndex) \ + void ReactorName##_Reaction##ReactionIndex##_ctor(ReactorName##_Reaction##ReactionIndex *self, Reactor *parent) + #define DEFINE_REACTION_CTOR(ReactorName, ReactionIndex) \ - void ReactorName##_Reaction##ReactionIndex##_ctor(ReactorName##_Reaction##ReactionIndex *self, Reactor *parent) { \ + DECLARE_REACTION_CTOR(ReactorName, ReactionIndex) { \ Reaction_ctor(&self->super, parent, ReactorName##_Reaction##ReactionIndex##_body, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0]), ReactionIndex); \ } @@ -160,8 +174,10 @@ Reaction *effects[(EffectSize)]; \ } StartupName; +#define DECLARE_STARTUP_CTOR(StartupName, EffectSize) void StartupName##_ctor(StartupName *self, Reactor *parent) + #define DEFINE_STARTUP_CTOR(StartupName, EffectSize) \ - void StartupName##_ctor(StartupName *self, Reactor *parent) { \ + DECLARE_STARTUP_CTOR(StartupName, EffectSize) { \ BuiltinTrigger_ctor(&self->super, TRIG_STARTUP, parent, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0])); \ } @@ -172,8 +188,10 @@ Reaction *effects[(EffectSize)]; \ } ShutdownName; +#define DECLARE_SHUTDOWN_CTOR(ShutdownName, EffectSize) void ShutdownName##_ctor(ShutdownName *self, Reactor *parent) + #define DEFINE_SHUTDOWN_CTOR(ShutdownName, EffectSize) \ - void ShutdownName##_ctor(ShutdownName *self, Reactor *parent) { \ + DECLARE_SHUTDOWN_CTOR(ShutdownName, EffectSize) { \ BuiltinTrigger_ctor(&self->super, TRIG_SHUTDOWN, parent, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0])); \ } @@ -188,14 +206,20 @@ Reaction *effects[(EffectSize)]; \ } ActionName; +#define DECLARE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) \ + void ActionName##_ctor(ActionName *self, Reactor *parent) + #define DEFINE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) \ - void ActionName##_ctor(ActionName *self, Reactor *parent) { \ + DECLARE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) { \ Action_ctor(&self->super, ActionType, MinDelay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } +#define DECLARE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ + void ActionName##_ctor(ActionName *self, Reactor *parent, interval_t min_delay) + #define DEFINE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ - void ActionName##_ctor(ActionName *self, Reactor *parent, interval_t min_delay) { \ + DECLARE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) { \ Action_ctor(&self->super, ActionType, min_delay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } @@ -206,8 +230,11 @@ Input *downstreams[(DownstreamSize)]; \ } ConnectionName; +#define DECLARE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) \ + void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) + #define DEFINE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) \ - void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) { \ + DECLARE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) { \ LogicalConnection_ctor(&self->super, parent, (Port **)self->downstreams, \ sizeof(self->downstreams) / sizeof(self->downstreams[0])); \ } @@ -220,8 +247,11 @@ Input *downstreams[(BufferSize)]; \ } ConnectionName; +#define DECLARE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) \ + void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) + #define DEFINE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) \ - void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) { \ + DECLARE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) { \ DelayedConnection_ctor(&self->super, parent, (Port **)self->downstreams, DownstreamSize, Delay, IsPhysical, \ sizeof(BufferType), (void *)self->payload_buf, self->payload_used_buf, BufferSize); \ } From fdc3716f85307ddc80b4a2719f83ddc0f9d3431a Mon Sep 17 00:00:00 2001 From: erlingrj Date: Fri, 1 Nov 2024 21:59:09 -0700 Subject: [PATCH 2/4] Start writing clock sync library reactrors --- lib/clock-sync/README.md | 12 +++++ lib/clock-sync/clock-master.c | 70 +++++++++++++++++++++++++++++ lib/clock-sync/clock-master.h | 85 +++++++++++++++++++++++++++++++++++ lib/clock-sync/clock-slave.c | 54 ++++++++++++++++++++++ lib/clock-sync/clock-slave.h | 73 ++++++++++++++++++++++++++++++ lib/clock-sync/clock-sync.h | 12 +++++ 6 files changed, 306 insertions(+) create mode 100644 lib/clock-sync/README.md create mode 100644 lib/clock-sync/clock-master.c create mode 100644 lib/clock-sync/clock-master.h create mode 100644 lib/clock-sync/clock-slave.c create mode 100644 lib/clock-sync/clock-slave.h create mode 100644 lib/clock-sync/clock-sync.h diff --git a/lib/clock-sync/README.md b/lib/clock-sync/README.md new file mode 100644 index 000000000..004411164 --- /dev/null +++ b/lib/clock-sync/README.md @@ -0,0 +1,12 @@ +# Clock Synchronization library +These library reactors are inspired by the PTP protocol. Currently the sync reactors only have +one input and output, meaning that we need one per connection to remote federate. +Connections between the slave and master should be physical. + +Three messages are exchanged between Master and Slave: +1. First the master sends a SYNC message to the slave. The SYNC message contains the timestamp t1 +2. The slave records the time of reception of SYNC as t2 (this will be the logical tag at which the reaction triggered by the SYNC message is executed.) +3. The sync responds with a DELAY_REQ message. The slave stores t3, the time of transmission. +4. The master records the time of receiving the DELAY_REQ as t4. Again this will be the logical tag +of the reaction triggered by the receiving event. The master sends this timestamp in a DELAY_RESP message sent back. + diff --git a/lib/clock-sync/clock-master.c b/lib/clock-sync/clock-master.c new file mode 100644 index 000000000..6b97788ab --- /dev/null +++ b/lib/clock-sync/clock-master.c @@ -0,0 +1,70 @@ +#include "clock-master.h" + +DEFINE_OUTPUT_PORT_CTOR(Out, 2); +DEFINE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_OUTPUT_PORT_CTOR(Out, 1); +DEFINE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); + +// Startup reaction +DEFINE_REACTION_BODY(ClockMaster, 0) { + ClockMaster *self = (ClockMaster *)_self->parent; + Action0 *action = &self->action; + Action0 *send_action = &self->send_action; + Environment *env = self->super.env; + + // Schedule next round + lf_schedule(action, CLOCK_SYNC, self->period); + + // Schedule the sending + lf_schedule(send_action, CLOCK_SYNC, MSEC(0)); +} +DEFINE_REACTION_CTOR(ClockMaster, 0); + +// Reaction triggered by action. Should start a new round of clock sync. +DEFINE_REACTION_BODY(ClockMaster, 1) { + ClockMaster *self = (ClockMaster *)_self->parent; + Environment *env = self->super.env; + Action0 *action = &self->action; + Action0 *send_action = &self->send_action; + assert(action->value == CLOCK_SYNC); + + // Schedule the sending + lf_schedule(send_action, CLOCK_SYNC, MSEC(0)); +} +DEFINE_REACTION_CTOR(ClockMaster, 1); + +// Reaction triggered by input +DEFINE_REACTION_BODY(ClockMaster, 2) { + ClockMaster *self = (ClockMaster *)_self->parent; + Environment *env = self->super.env; + In *in = &self->in; + Action0 *send_action = &self->send_action; + assert(in->value.type == CLOCK_DELAY_REQ); + lf_schedule(send_action, CLOCK_DELAY_RESP, MSEC(0)); +} +DEFINE_REACTION_CTOR(ClockMaster, 2); + +// Reaction triggered by send action +DEFINE_REACTION_BODY(ClockMaster, 3) { + ClockMaster *self = (ClockMaster *)_self->parent; + Environment *env = self->super.env; + Action0 *action = &self->send_action; + Out *out = &self->out; + + ClockSyncMessage msg; + msg.type = action->value; + + switch (action->value) { + case CLOCK_SYNC: + msg.time = env->get_physical_time(env); + break; + case CLOCK_DELAY_RESP: + msg.time = env->get_logical_time(env); + break; + default: + assert(0); + } + + lf_set(out, msg); +} +DEFINE_REACTION_CTOR(ClockMaster, 3); \ No newline at end of file diff --git a/lib/clock-sync/clock-master.h b/lib/clock-sync/clock-master.h new file mode 100644 index 000000000..57987bf01 --- /dev/null +++ b/lib/clock-sync/clock-master.h @@ -0,0 +1,85 @@ +#ifndef REACTOR_UC_CLOCK_MASTER_H +#define REACTOR_UC_CLOCK_MASTER_H + +#include "reactor-uc/reactor-uc.h" +#include "clock-sync.h" + +DEFINE_ACTION_STRUCT(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); +DECLARE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_STARTUP_STRUCT(Startup0, 1); +DECLARE_STARTUP_CTOR(Startup0, 1); +DEFINE_OUTPUT_PORT_STRUCT(Out, 2, 1); +DECLARE_OUTPUT_PORT_CTOR(Out, 2); +DEFINE_INPUT_PORT_STRUCT(In, 1, ClockSyncMessage, 1); +DECLARE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); + +DEFINE_REACTION_STRUCT(ClockMaster, 0, 1); +DEFINE_REACTION_STRUCT(ClockMaster, 1, 2); +DEFINE_REACTION_STRUCT(ClockMaster, 2, 1); +DEFINE_REACTION_STRUCT(ClockMaster, 3, 1); + +DECLARE_REACTION_CTOR(ClockMaster, 0); +DECLARE_REACTION_CTOR(ClockMaster, 1); +DECLARE_REACTION_CTOR(ClockMaster, 2); +DECLARE_REACTION_CTOR(ClockMaster, 3); + +#define CLOCK_MASTER_NUM_REACTIONS 4 +#define CLOCK_MASTER_NUM_TRIGGERS 5 + +typedef struct { + Reactor super; + ClockMaster_Reaction0 reaction0; + ClockMaster_Reaction1 reaction1; + ClockMaster_Reaction2 reaction2; + ClockMaster_Reaction3 reaction3; + Action0 action; + Action0 send_action; + Startup0 startup; + Out out; + In in; + Reaction *_reactions[CLOCK_MASTER_NUM_REACTIONS]; + Trigger *_triggers[CLOCK_MASTER_NUM_TRIGGERS]; + interval_t period; +} ClockMaster; + +void ClockMaster_ctor(ClockMaster *self, Environment *env, Connection **conn_out, interval_t period) { + self->_reactions[0] = (Reaction *)&self->reaction0; + self->_reactions[1] = (Reaction *)&self->reaction1; + self->_reactions[2] = (Reaction *)&self->reaction2; + self->_reactions[3] = (Reaction *)&self->reaction3; + self->_triggers[0] = (Trigger *)&self->startup; + self->_triggers[1] = (Trigger *)&self->action; + self->_triggers[2] = (Trigger *)&self->send_action; + self->_triggers[3] = (Trigger *)&self->out; + self->_triggers[4] = (Trigger *)&self->in; + + self->period = period; + Reactor_ctor(&self->super, "ClockSync", env, NULL, NULL, 0, self->_reactions, CLOCK_MASTER_NUM_REACTIONS, + self->_triggers, CLOCK_MASTER_NUM_TRIGGERS); + + ClockMaster_Reaction0_ctor(&self->reaction0, &self->super); + ClockMaster_Reaction1_ctor(&self->reaction1, &self->super); + ClockMaster_Reaction2_ctor(&self->reaction2, &self->super); + ClockMaster_Reaction3_ctor(&self->reaction3, &self->super); + + Action0_ctor(&self->action, &self->super); + Action0_ctor(&self->send_action, &self->super); + Startup0_ctor(&self->startup, &self->super); + In_ctor(&self->in, &self->super); + Out_ctor(&self->out, &self->super, conn_out, 1); + + ACTION_REGISTER_EFFECT(self->action, self->reaction1); + ACTION_REGISTER_EFFECT(self->send_action, self->reaction3); + BUILTIN_REGISTER_EFFECT(self->startup, self->reaction0); + INPUT_REGISTER_EFFECT(self->in, self->reaction2); + OUTPUT_REGISTER_SOURCE(self->out, self->reaction1); + OUTPUT_REGISTER_SOURCE(self->out, self->reaction2); + ACTION_REGISTER_SOURCE(self->action, self->reaction1); + REACTION_REGISTER_EFFECT(self->reaction0, self->action); + REACTION_REGISTER_EFFECT(self->reaction1, self->action); + REACTION_REGISTER_EFFECT(self->reaction1, self->send_action); + REACTION_REGISTER_EFFECT(self->reaction2, self->send_action); + REACTION_REGISTER_EFFECT(self->reaction3, self->out); +} + +#endif diff --git a/lib/clock-sync/clock-slave.c b/lib/clock-sync/clock-slave.c new file mode 100644 index 000000000..2f79cdf19 --- /dev/null +++ b/lib/clock-sync/clock-slave.c @@ -0,0 +1,54 @@ + +#include "clock-slave.h" + +DEFINE_OUTPUT_PORT_CTOR(Out, 2); +DEFINE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_OUTPUT_PORT_CTOR(Out, 1); +DEFINE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); +// TODO: Make sure that we dont overwrite timestamps before we have calculated the offset. +// maybe the slave should request this whole thing, and not the master? + +// Startup reaction +DEFINE_REACTION_BODY(ClockSlave, 0) { + ClockSlave *self = (ClockSlave *)_self->parent; + Action0 *send_action = &self->send_action; + Environment *env = self->super.env; +} +DEFINE_REACTION_CTOR(ClockSlave, 0); + +// Send reaction +DEFINE_REACTION_BODY(ClockSlave, 1) { + ClockSlave *self = (ClockSlave *)_self->parent; + Environment *env = self->super.env; + + Action0 *action = &self->send_action; + Out *out = &self->out; + assert(action->value == CLOCK_DELAY_REQ); + + ClockSyncMessage msg; + msg.type = action->value; + msg.time = 0; + self->t3 = env->get_physical_time(env); + lf_set(out, msg); +} +DEFINE_REACTION_CTOR(ClockSlave, 1); + +// Reaction triggered by input +DEFINE_REACTION_BODY(ClockSlave, 2) { + ClockSlave *self = (ClockSlave *)_self->parent; + Environment *env = self->super.env; + In *in = &self->in; + Action0 *send_action = &self->send_action; + + if (in->value.type == CLOCK_SYNC) { + self->t1 = in->value.time; + self->t2 = env->get_logical_time(env); + lf_schedule(send_action, CLOCK_DELAY_REQ, MSEC(0)); + } else if (in->value.type == CLOCK_DELAY_RESP) { + self->t4 = in->value.time; + // FIXME: Calculate offset and adjust clock. + } else { + assert(0); + } +} +DEFINE_REACTION_CTOR(ClockSlave, 2); \ No newline at end of file diff --git a/lib/clock-sync/clock-slave.h b/lib/clock-sync/clock-slave.h new file mode 100644 index 000000000..4af97a0cb --- /dev/null +++ b/lib/clock-sync/clock-slave.h @@ -0,0 +1,73 @@ +#ifndef REACTOR_UC_CLOCK_SLAVE_H +#define REACTOR_UC_CLOCK_SLAVE_H + +#include "reactor-uc/reactor-uc.h" +#include "clock-sync.h" + +DEFINE_ACTION_STRUCT(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); +DECLARE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_STARTUP_STRUCT(Startup0, 1); +DECLARE_STARTUP_CTOR(Startup0, 1); +DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 1); +DECLARE_OUTPUT_PORT_CTOR(Out, 1); +DEFINE_INPUT_PORT_STRUCT(In, 1, ClockSyncMessage, 1); +DECLARE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); + +DEFINE_REACTION_STRUCT(ClockSlave, 0, 0); +DEFINE_REACTION_STRUCT(ClockSlave, 1, 1); +DEFINE_REACTION_STRUCT(ClockSlave, 2, 1); + +DECLARE_REACTION_CTOR(ClockSlave, 0); +DECLARE_REACTION_CTOR(ClockSlave, 1); +DECLARE_REACTION_CTOR(ClockSlave, 2); + +#define CLOCK_SLAVE_NUM_REACTIONS 3 +#define CLOCK_SLAVE_NUM_TRIGGERS 4 + +typedef struct { + Reactor super; + ClockSlave_Reaction0 reaction0; + ClockSlave_Reaction1 reaction1; + ClockSlave_Reaction2 reaction2; + Action0 send_action; + Startup0 startup; + Out out; + In in; + Reaction *_reactions[CLOCK_SLAVE_NUM_REACTIONS]; + Trigger *_triggers[CLOCK_SLAVE_NUM_TRIGGERS]; + instant_t t1; + instant_t t2; + instant_t t3; + instant_t t4; +} ClockSlave; + +void ClockSlave_ctor(ClockSlave *self, Environment *env, Connection **conn_out) { + self->_reactions[0] = (Reaction *)&self->reaction0; + self->_reactions[1] = (Reaction *)&self->reaction1; + self->_reactions[2] = (Reaction *)&self->reaction2; + self->_triggers[0] = (Trigger *)&self->startup; + self->_triggers[1] = (Trigger *)&self->send_action; + self->_triggers[2] = (Trigger *)&self->out; + self->_triggers[3] = (Trigger *)&self->in; + + Reactor_ctor(&self->super, "ClockSlave", env, NULL, NULL, 0, self->_reactions, CLOCK_SLAVE_NUM_REACTIONS, + self->_triggers, CLOCK_SLAVE_NUM_TRIGGERS); + + ClockSlave_Reaction0_ctor(&self->reaction0, &self->super); + ClockSlave_Reaction1_ctor(&self->reaction1, &self->super); + ClockSlave_Reaction2_ctor(&self->reaction2, &self->super); + + Action0_ctor(&self->send_action, &self->super); + Startup0_ctor(&self->startup, &self->super); + In_ctor(&self->in, &self->super); + Out_ctor(&self->out, &self->super, conn_out, 1); + + BUILTIN_REGISTER_EFFECT(self->startup, self->reaction0); + ACTION_REGISTER_EFFECT(self->send_action, self->reaction1); + INPUT_REGISTER_EFFECT(self->in, self->reaction2); + OUTPUT_REGISTER_SOURCE(self->out, self->reaction1); + REACTION_REGISTER_EFFECT(self->reaction2, self->send_action); + REACTION_REGISTER_EFFECT(self->reaction1, self->out); +} + +#endif diff --git a/lib/clock-sync/clock-sync.h b/lib/clock-sync/clock-sync.h new file mode 100644 index 000000000..e9a92c8bd --- /dev/null +++ b/lib/clock-sync/clock-sync.h @@ -0,0 +1,12 @@ +#ifndef REACTOR_UC_CLOCK_SYNC_H +#define REACTOR_UC_CLOCK_SYNC_H + +#include "reactor-uc/reactor-uc.h" + +typedef enum { CLOCK_SYNC, CLOCK_DELAY_REQ, CLOCK_DELAY_RESP } ClockSyncMessageType; +typedef struct { + ClockSyncMessageType type; + instant_t time; +} ClockSyncMessage; + +#endif \ No newline at end of file From 166e3823d5027baa5b1c8bb411331cee3a5733d3 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sun, 3 Nov 2024 14:07:51 -0800 Subject: [PATCH 3/4] Undo the adding of DECLARE macros --- include/reactor-uc/macros.h | 56 +++++++++---------------------------- 1 file changed, 13 insertions(+), 43 deletions(-) diff --git a/include/reactor-uc/macros.h b/include/reactor-uc/macros.h index 32ecf3faa..fc9307e57 100644 --- a/include/reactor-uc/macros.h +++ b/include/reactor-uc/macros.h @@ -60,8 +60,8 @@ #define REACTION_REGISTER_EFFECT(reaction, effect) \ do { \ Reaction *__reaction = (Reaction *)&(reaction); \ - assert(__reaction->effects_registered < __reaction->effects_size); \ - __reaction->effects[__reaction->effects_registered++] = (Trigger *)&(effect); \ + assert((__reaction)->effects_registered < (__reaction)->effects_size); \ + (__reaction)->effects[(__reaction)->effects_registered++] = (Trigger *)&(effect); \ } while (0) // Register a reaction as a source of a trigger. `trigger` must be a pointer to @@ -104,11 +104,8 @@ Connection *conns_out[NumConnsOut]; \ } PortName; -#define DECLARE_OUTPUT_PORT_CTOR(PortName, SourceSize) \ - void PortName##_ctor(PortName *self, Reactor *parent, Connection **conn_out, size_t conn_num) - #define DEFINE_OUTPUT_PORT_CTOR(PortName, SourceSize) \ - DECLARE_OUTPUT_PORT_CTOR(PortName, SourceSize) { \ + void PortName##_ctor(PortName *self, Reactor *parent, Connection **conn_out, size_t conn_num) { \ Output_ctor(&self->super, parent, self->sources, SourceSize, conn_out, conn_num); \ } @@ -119,11 +116,9 @@ BufferType value; \ Connection *conns_out[(NumConnsOut)]; \ } PortName; -#define DECLARE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) \ - void PortName##_ctor(PortName *self, Reactor *parent) #define DEFINE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) \ - DECLARE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) { \ + void PortName##_ctor(PortName *self, Reactor *parent) { \ Input_ctor(&self->super, parent, self->effects, (EffectSize), (Connection **)&self->conns_out, NumConnsOut, \ &self->value, sizeof(BufferType)); \ } @@ -134,19 +129,13 @@ Reaction *effects[(EffectSize)]; \ } TimerName; -#define DECLARE_TIMER_CTOR(TimerName, EffectSize) \ - void TimerName##_ctor(TimerName *self, Reactor *parent, interval_t offset, interval_t period) - #define DEFINE_TIMER_CTOR(TimerName, EffectSize) \ - DECLARE_TIMER_CTOR(TimerName, EffectSize) { \ + void TimerName##_ctor(TimerName *self, Reactor *parent, interval_t offset, interval_t period) { \ Timer_ctor(&self->super, parent, offset, period, self->effects, EffectSize); \ } -#define DECLARE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) \ - void TimerName##_ctor(TimerName *self, Reactor *parent) - #define DEFINE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) \ - DECLARE_TIMER_CTOR_FIXED(TimerName, EffectSize, Offset, Period) { \ + void TimerName##_ctor(TimerName *self, Reactor *parent) { \ Timer_ctor(&self->super, parent, Offset, Period, self->effects, EffectSize); \ } @@ -159,11 +148,8 @@ #define DEFINE_REACTION_BODY(ReactorName, ReactionIndex) \ void ReactorName##_Reaction##ReactionIndex##_body(Reaction *_self) -#define DECLARE_REACTION_CTOR(ReactorName, ReactionIndex) \ - void ReactorName##_Reaction##ReactionIndex##_ctor(ReactorName##_Reaction##ReactionIndex *self, Reactor *parent) - #define DEFINE_REACTION_CTOR(ReactorName, ReactionIndex) \ - DECLARE_REACTION_CTOR(ReactorName, ReactionIndex) { \ + void ReactorName##_Reaction##ReactionIndex##_ctor(ReactorName##_Reaction##ReactionIndex *self, Reactor *parent) { \ Reaction_ctor(&self->super, parent, ReactorName##_Reaction##ReactionIndex##_body, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0]), ReactionIndex); \ } @@ -174,10 +160,8 @@ Reaction *effects[(EffectSize)]; \ } StartupName; -#define DECLARE_STARTUP_CTOR(StartupName, EffectSize) void StartupName##_ctor(StartupName *self, Reactor *parent) - #define DEFINE_STARTUP_CTOR(StartupName, EffectSize) \ - DECLARE_STARTUP_CTOR(StartupName, EffectSize) { \ + void StartupName##_ctor(StartupName *self, Reactor *parent) { \ BuiltinTrigger_ctor(&self->super, TRIG_STARTUP, parent, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0])); \ } @@ -188,10 +172,8 @@ Reaction *effects[(EffectSize)]; \ } ShutdownName; -#define DECLARE_SHUTDOWN_CTOR(ShutdownName, EffectSize) void ShutdownName##_ctor(ShutdownName *self, Reactor *parent) - #define DEFINE_SHUTDOWN_CTOR(ShutdownName, EffectSize) \ - DECLARE_SHUTDOWN_CTOR(ShutdownName, EffectSize) { \ + void ShutdownName##_ctor(ShutdownName *self, Reactor *parent) { \ BuiltinTrigger_ctor(&self->super, TRIG_SHUTDOWN, parent, self->effects, \ sizeof(self->effects) / sizeof(self->effects[0])); \ } @@ -206,20 +188,14 @@ Reaction *effects[(EffectSize)]; \ } ActionName; -#define DECLARE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) \ - void ActionName##_ctor(ActionName *self, Reactor *parent) - #define DEFINE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) \ - DECLARE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) { \ + void ActionName##_ctor(ActionName *self, Reactor *parent) { \ Action_ctor(&self->super, ActionType, MinDelay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } -#define DECLARE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ - void ActionName##_ctor(ActionName *self, Reactor *parent, interval_t min_delay) - #define DEFINE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ - DECLARE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) { \ + void ActionName##_ctor(ActionName *self, Reactor *parent, interval_t min_delay) { \ Action_ctor(&self->super, ActionType, min_delay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } @@ -230,11 +206,8 @@ Input *downstreams[(DownstreamSize)]; \ } ConnectionName; -#define DECLARE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) \ - void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) - #define DEFINE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) \ - DECLARE_LOGICAL_CONNECTION_CTOR(ConnectionName, DownstreamSize) { \ + void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) { \ LogicalConnection_ctor(&self->super, parent, (Port **)self->downstreams, \ sizeof(self->downstreams) / sizeof(self->downstreams[0])); \ } @@ -247,11 +220,8 @@ Input *downstreams[(BufferSize)]; \ } ConnectionName; -#define DECLARE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) \ - void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) - #define DEFINE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) \ - DECLARE_DELAYED_CONNECTION_CTOR(ConnectionName, DownstreamSize, BufferType, BufferSize, Delay, IsPhysical) { \ + void ConnectionName##_ctor(ConnectionName *self, Reactor *parent) { \ DelayedConnection_ctor(&self->super, parent, (Port **)self->downstreams, DownstreamSize, Delay, IsPhysical, \ sizeof(BufferType), (void *)self->payload_buf, self->payload_used_buf, BufferSize); \ } From 7a6a96198e17756839ef88f7325c6ef37d8b53b1 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sun, 3 Nov 2024 17:14:11 -0800 Subject: [PATCH 4/4] Rework macro system, --- examples/posix/federated/receiver.c | 4 +- examples/posix/federated/sender.c | 8 +- .../federated_receiver1/src/receiver.c | 4 +- .../federated_receiver2/src/receiver.c | 4 +- .../federated_sender/src/sender.c | 4 +- include/reactor-uc/macros.h | 119 +++++++++++++----- include/reactor-uc/port.h | 7 +- include/reactor-uc/trigger.h | 7 +- .../lflang/generator/uc/UcPortGenerator.kt | 8 +- lib/clock-sync/clock-master.c | 110 ++++++++++------ lib/clock-sync/clock-master.h | 90 ++++--------- lib/clock-sync/clock-slave.c | 37 +++++- lib/clock-sync/clock-slave.h | 45 +------ src/action.c | 10 +- src/builtin_triggers.c | 5 +- src/connection.c | 2 +- src/port.c | 14 +-- src/timer.c | 5 +- src/trigger.c | 11 +- test/unit/delayed_conn_test.c | 8 +- test/unit/port_test.c | 8 +- 21 files changed, 273 insertions(+), 237 deletions(-) diff --git a/examples/posix/federated/receiver.c b/examples/posix/federated/receiver.c index bb11668d7..2d0301814 100644 --- a/examples/posix/federated/receiver.c +++ b/examples/posix/federated/receiver.c @@ -20,8 +20,8 @@ lf_ret_t deserialize_msg_t(void *user_struct, const unsigned char *msg_buf, size } DEFINE_REACTION_STRUCT(Receiver, 0, 1) -DEFINE_INPUT_PORT_STRUCT(In, 1, msg_t, 0) -DEFINE_INPUT_PORT_CTOR(In, 1, msg_t, 0) +DEFINE_INPUT_STRUCT(In, 1, msg_t, 0) +DEFINE_INPUT_CTOR(In, 1, msg_t, 0) typedef struct { Reactor super; diff --git a/examples/posix/federated/sender.c b/examples/posix/federated/sender.c index 9be199f26..f378db25f 100644 --- a/examples/posix/federated/sender.c +++ b/examples/posix/federated/sender.c @@ -24,8 +24,8 @@ size_t serialize_msg_t(const void *user_struct, size_t user_struct_size, unsigne DEFINE_TIMER_STRUCT(Timer1, 1) DEFINE_TIMER_CTOR_FIXED(Timer1, 1, MSEC(0), SEC(1)) DEFINE_REACTION_STRUCT(Sender, 0, 1) -DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 1) -DEFINE_OUTPUT_PORT_CTOR(Out, 1) +DEFINE_OUTPUT_STRUCT(Out, 1, 1) +DEFINE_OUTPUT_CTOR(Out, 1) typedef struct { Reactor super; @@ -63,8 +63,8 @@ void Sender_ctor(Sender *self, Reactor *parent, Environment *env, Connection **c } DEFINE_REACTION_STRUCT(Receiver, 0, 1) -DEFINE_INPUT_PORT_STRUCT(In, 1, msg_t, 0) -DEFINE_INPUT_PORT_CTOR(In, 1, msg_t, 0) +DEFINE_INPUT_STRUCT(In, 1, msg_t, 0) +DEFINE_INPUT_CTOR(In, 1, msg_t, 0) typedef struct { Reactor super; diff --git a/examples/zephyr/basic_federated/federated_receiver1/src/receiver.c b/examples/zephyr/basic_federated/federated_receiver1/src/receiver.c index 33d478b34..3c32aef01 100644 --- a/examples/zephyr/basic_federated/federated_receiver1/src/receiver.c +++ b/examples/zephyr/basic_federated/federated_receiver1/src/receiver.c @@ -20,8 +20,8 @@ typedef struct { } msg_t; DEFINE_REACTION_STRUCT(Receiver, 0, 0) -DEFINE_INPUT_PORT_STRUCT(In, 1, msg_t, 0) -DEFINE_INPUT_PORT_CTOR(In, 1, msg_t, 0) +DEFINE_INPUT_STRUCT(In, 1, msg_t, 0) +DEFINE_INPUT_CTOR(In, 1, msg_t, 0) typedef struct { Reactor super; diff --git a/examples/zephyr/basic_federated/federated_receiver2/src/receiver.c b/examples/zephyr/basic_federated/federated_receiver2/src/receiver.c index 1c02df83c..8f378ed1e 100644 --- a/examples/zephyr/basic_federated/federated_receiver2/src/receiver.c +++ b/examples/zephyr/basic_federated/federated_receiver2/src/receiver.c @@ -20,8 +20,8 @@ typedef struct { } msg_t; DEFINE_REACTION_STRUCT(Receiver, 0, 0) -DEFINE_INPUT_PORT_STRUCT(In, 1, msg_t, 0) -DEFINE_INPUT_PORT_CTOR(In, 1, msg_t, 0) +DEFINE_INPUT_STRUCT(In, 1, msg_t, 0) +DEFINE_INPUT_CTOR(In, 1, msg_t, 0) typedef struct { Reactor super; diff --git a/examples/zephyr/basic_federated/federated_sender/src/sender.c b/examples/zephyr/basic_federated/federated_sender/src/sender.c index 16c66d06a..67b9ae17a 100644 --- a/examples/zephyr/basic_federated/federated_sender/src/sender.c +++ b/examples/zephyr/basic_federated/federated_sender/src/sender.c @@ -20,8 +20,8 @@ static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); DEFINE_ACTION_STRUCT(Action1, PHYSICAL_ACTION, 1, 0, bool, 2) DEFINE_ACTION_CTOR_FIXED(Action1, PHYSICAL_ACTION, 1, 0, bool, 2, MSEC(0)) DEFINE_REACTION_STRUCT(Sender, 0, 1) -DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 2) -DEFINE_OUTPUT_PORT_CTOR(Out, 1) +DEFINE_OUTPUT_STRUCT(Out, 1, 2) +DEFINE_OUTPUT_CTOR(Out, 1) Action1 *action_ptr = NULL; void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { diff --git a/include/reactor-uc/macros.h b/include/reactor-uc/macros.h index fc9307e57..c7c3f08fb 100644 --- a/include/reactor-uc/macros.h +++ b/include/reactor-uc/macros.h @@ -1,6 +1,8 @@ #ifndef REACTOR_UC_MACROS_H #define REACTOR_UC_MACROS_H +#define EXPAND(x) x + // Sets an output port, copies data and triggers all downstream reactions. #define lf_set(port, val) \ do { \ @@ -46,22 +48,36 @@ (trigger)->effects.reactions[(trigger)->effects.num_registered++] = (effect); \ } while (0) +#define REACTION_TRIGGER(_Reaction, _Trigger) \ + TRIGGER_REGISTER_SOURCE((Trigger *)&self->##_Trigger, (Trigger *)&self->##_Reaction) \ + REACTION_REGISTER_EFFECT(_Reaction, _Trigger) + // The following macros casts the inputs into the correct types before calling TRIGGER_REGISTER_EFFECTs -#define ACTION_REGISTER_EFFECT(action, effect) TRIGGER_REGISTER_EFFECT((Action *)&(action), (Reaction *)&(effect)) +#define ACTION_REGISTER_EFFECT(TheAction, TheEffect) \ + TRIGGER_REGISTER_EFFECT((Action *)&self->##TheAction, (Reaction *)&self->##TheEffect) + +#define REACTION_TRIGGER(_Reaction, _Trigger) \ + TRIGGER_REGISTER_EFFECT(((Trigger *)&self->##_Trigger), ((Reaction *)&self->##_Reaction)) + +#define REACTION_EFFECT(_Reaction, _Trigger) \ + TRIGGER_REGISTER_SOURCE(((Trigger *)&self->##_Trigger), ((Reaction *)&self->##_Reaction)); \ + REACTION_REGISTER_EFFECT(_Reaction, _Trigger) + #define TIMER_REGISTER_EFFECT(timer, effect) TRIGGER_REGISTER_EFFECT((Timer *)(&(timer)), (Reaction *)(&(effect))) -#define BUILTIN_REGISTER_EFFECT(builtin, effect) \ - TRIGGER_REGISTER_EFFECT((BuiltinTrigger *)&(builtin), (Reaction *)&(effect)) -#define INPUT_REGISTER_EFFECT(input, effect) TRIGGER_REGISTER_EFFECT((Input *)&(input), (Reaction *)&(effect)) +#define STARTUP_REGISTER_EFFECT(effect) \ + TRIGGER_REGISTER_EFFECT((BuiltinTrigger *)&(self->startup), (Reaction *)&self->##effect) +#define INPUT_REGISTER_EFFECT(_Input, _Effect) \ + TRIGGER_REGISTER_EFFECT((Input *)&self->##_Input, (Reaction *)&self->##_Effect) /** * @brief Convenience macro for registering a trigger as an effect of a reaction. * */ -#define REACTION_REGISTER_EFFECT(reaction, effect) \ +#define REACTION_REGISTER_EFFECT(_Reaction, _Effect) \ do { \ - Reaction *__reaction = (Reaction *)&(reaction); \ + Reaction *__reaction = (Reaction *)&self->##_Reaction; \ assert((__reaction)->effects_registered < (__reaction)->effects_size); \ - (__reaction)->effects[(__reaction)->effects_registered++] = (Trigger *)&(effect); \ + (__reaction)->effects[(__reaction)->effects_registered++] = (Trigger *)&self->##_Effect; \ } while (0) // Register a reaction as a source of a trigger. `trigger` must be a pointer to @@ -74,7 +90,8 @@ // Convenient translation from a user trigger to a pointer to the derived Trigger type. #define ACTION_REGISTER_SOURCE(action, source) TRIGGER_REGISTER_SOURCE((Action *)&(action), (Reaction *)&(source)) -#define OUTPUT_REGISTER_SOURCE(output, source) TRIGGER_REGISTER_SOURCE((Output *)&(output), (Reaction *)&(source)) +#define OUTPUT_REGISTER_SOURCE(_Output, _Source) \ + TRIGGER_REGISTER_SOURCE((Output *)&self->##_Output, (Reaction *)&self->##_Source); // Convenience macro to register a downstream port on a connection. // TODO: Replace entirely the need for `register_downstream`. @@ -97,28 +114,43 @@ CONN_REGISTER_UPSTREAM(ConnectionVariable, SourcePort); \ CONN_REGISTER_DOWNSTREAM(ConnectionVariable, DestinationPort) -#define DEFINE_OUTPUT_PORT_STRUCT(PortName, SourceSize, NumConnsOut) \ +// Macros for creating the structs and ctors + +#define APPEND_TO_LIST(LIST, ITEM) LIST ITEM + +#define DEFINE_OUTPUT_STRUCT(ReactorName, PortName, SourceSize, NumConnsOut) \ typedef struct { \ Output super; \ Reaction *sources[(SourceSize)]; \ Connection *conns_out[NumConnsOut]; \ - } PortName; + } ReactorName##_##PortName; -#define DEFINE_OUTPUT_PORT_CTOR(PortName, SourceSize) \ - void PortName##_ctor(PortName *self, Reactor *parent, Connection **conn_out, size_t conn_num) { \ +#define DEFINE_OUTPUT_CTOR(ReactorName, PortName, SourceSize) \ + void ReactorName##_PortName##_ctor(ReactorName##_##PortName *self, Reactor *parent, Connection **conn_out, \ + size_t conn_num) { \ Output_ctor(&self->super, parent, self->sources, SourceSize, conn_out, conn_num); \ } -#define DEFINE_INPUT_PORT_STRUCT(PortName, EffectSize, BufferType, NumConnsOut) \ +#define INSTANTIATE_PORT(ReactorName, PortName) ReactorName##_##PortName PortName; + +#define INIT_OUTPUT(ReactorName, PortName, Conns, ConnSize) \ + self->_triggers[_triggers_idx++] = (Trigger *)&self->##PortName; \ + ReactorName##_##PortName##_ctor(&self->##PortName, &self->super, Conns, ConnSize) + +#define INIT_INPUT(ReactorName, PortName) \ + self->_triggers[_triggers_idx++] = (Trigger *)&self->##PortName; \ + ReactorName##_##PortName##_ctor(&self->##PortName, &self->super) + +#define DEFINE_INPUT_STRUCT(ReactorName, PortName, EffectSize, BufferType, NumConnsOut) \ typedef struct { \ Input super; \ Reaction *effects[(EffectSize)]; \ BufferType value; \ Connection *conns_out[(NumConnsOut)]; \ - } PortName; + } ReactorName##_##PortName; -#define DEFINE_INPUT_PORT_CTOR(PortName, EffectSize, BufferType, NumConnsOut) \ - void PortName##_ctor(PortName *self, Reactor *parent) { \ +#define DEFINE_INPUT_CTOR(ReactorName, PortName, EffectSize, BufferType, NumConnsOut) \ + void ReactorName##_##PortName##_ctor(ReactorName##_##PortName *self, Reactor *parent) { \ Input_ctor(&self->super, parent, self->effects, (EffectSize), (Connection **)&self->conns_out, NumConnsOut, \ &self->value, sizeof(BufferType)); \ } @@ -139,26 +171,33 @@ Timer_ctor(&self->super, parent, Offset, Period, self->effects, EffectSize); \ } -#define DEFINE_REACTION_STRUCT(ReactorName, ReactionIndex, EffectSize) \ +#define DEFINE_REACTION_STRUCT(ReactorName, ReactionName, EffectSize) \ typedef struct { \ Reaction super; \ Trigger *effects[(EffectSize)]; \ - } ReactorName##_Reaction##ReactionIndex; + } ReactorName##_Reaction_##ReactionName; + +#define INSTANTIATE_REACTION(ReactorName, ReactionName) ReactorName##_Reaction_##ReactionName ReactionName; -#define DEFINE_REACTION_BODY(ReactorName, ReactionIndex) \ - void ReactorName##_Reaction##ReactionIndex##_body(Reaction *_self) +#define INIT_REACTION(ReactorName, ReactionName) \ + self->_reactions[_reactions_idx++] = (Reaction *)&self->##ReactionName; \ + ReactorName##_Reaction_##ReactionName##_ctor(&self->##ReactionName, &self->super) -#define DEFINE_REACTION_CTOR(ReactorName, ReactionIndex) \ - void ReactorName##_Reaction##ReactionIndex##_ctor(ReactorName##_Reaction##ReactionIndex *self, Reactor *parent) { \ - Reaction_ctor(&self->super, parent, ReactorName##_Reaction##ReactionIndex##_body, self->effects, \ - sizeof(self->effects) / sizeof(self->effects[0]), ReactionIndex); \ +#define DEFINE_REACTION_BODY(ReactorName, ReactionName) \ + void ReactorName##_Reaction_##ReactionName##_body(Reaction *_self) + +#define DEFINE_REACTION_CTOR(ReactorName, ReactionName, Priority) \ + DEFINE_REACTION_BODY(ReactorName, ReactionName); \ + void ReactorName##_Reaction_##ReactionName##_ctor(ReactorName##_Reaction_##ReactionName *self, Reactor *parent) { \ + Reaction_ctor(&self->super, parent, ReactorName##_Reaction_##ReactionName##_body, self->effects, \ + sizeof(self->effects) / sizeof(self->effects[0]), Priority); \ } -#define DEFINE_STARTUP_STRUCT(StartupName, EffectSize) \ +#define DEFINE_STARTUP_STRUCT(ReactorName, EffectSize) \ typedef struct { \ BuiltinTrigger super; \ Reaction *effects[(EffectSize)]; \ - } StartupName; + } ReactorName##_Startup; #define DEFINE_STARTUP_CTOR(StartupName, EffectSize) \ void StartupName##_ctor(StartupName *self, Reactor *parent) { \ @@ -166,6 +205,11 @@ sizeof(self->effects) / sizeof(self->effects[0])); \ } +#define INSTANTIATE_STARTUP(ReactorName) ReactorName##_Startup startup; +#define INIT_STARTUP(ReactorName) \ + self->_triggers[_triggers_idx++] = (Trigger *)&self->startup; \ + StartupName##_ctor(&self->startup, &self->super) + #define DEFINE_SHUTDOWN_STRUCT(ShutdownName, EffectSize) \ typedef struct { \ BuiltinTrigger super; \ @@ -178,7 +222,7 @@ sizeof(self->effects) / sizeof(self->effects[0])); \ } -#define DEFINE_ACTION_STRUCT(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ +#define DEFINE_ACTION_STRUCT(ReactorName, ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ typedef struct { \ Action super; \ BufferType value; \ @@ -186,20 +230,33 @@ bool payload_used_buf[(BufferSize)]; \ Reaction *sources[(SourceSize)]; \ Reaction *effects[(EffectSize)]; \ - } ActionName; + } ReactorName##_##ActionName -#define DEFINE_ACTION_CTOR_FIXED(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, MinDelay) \ - void ActionName##_ctor(ActionName *self, Reactor *parent) { \ +#define DEFINE_ACTION_CTOR_FIXED(ReactorName, ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize, \ + MinDelay) \ + void ReactorName##_##ActionName##_ctor(ReactorName##_##ActionName *self, Reactor *parent) { \ Action_ctor(&self->super, ActionType, MinDelay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } -#define DEFINE_ACTION_CTOR(ActionName, ActionType, EffectSize, SourceSize, BufferType, BufferSize) \ +#define DEFINE_ACTION_CTOR(ActionName, EffectSize, SourceSize, BufferType, BufferSize) \ void ActionName##_ctor(ActionName *self, Reactor *parent, interval_t min_delay) { \ Action_ctor(&self->super, ActionType, min_delay, parent, self->sources, SourceSize, self->effects, EffectSize, \ &self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, BufferSize); \ } +#define INSTANTIATE_ACTION(ReactorName, ActionName) ReactorName##_##ActionName ActionName; + +#define INIT_ACTION(ReactorName, ActionName) \ + self->_triggers[_triggers_idx++] = (Trigger *)&self->##ActionName; \ + ActionName##_ctor(&self->##ActionName, &self->super) + +#define SCOPE_ACTION(ReactorName, ActionName) ReactorName##_##ActionName *##ActionName = &self->##ActionName + +#define SCOPE_PORT(ReactorName, PortName) ReactorName##_##PortName *##PortName = &self->##PortName +#define SCOPE_SELF(ReactorName) ReactorName *self = (ReactorName *)_self->parent +#define SCOPE_ENV() Environment *env = self->super.env + #define DEFINE_LOGICAL_CONNECTION_STRUCT(ConnectionName, DownstreamSize) \ typedef struct { \ LogicalConnection super; \ diff --git a/include/reactor-uc/port.h b/include/reactor-uc/port.h index 01586d9c5..f57a7b0bf 100644 --- a/include/reactor-uc/port.h +++ b/include/reactor-uc/port.h @@ -21,14 +21,12 @@ struct Port { struct Input { Port super; - TriggerEffects effects; // The reactions triggered by this Input port. - void *value_ptr; // Pointer to the `buffer` field in the user Input port struct. - size_t value_size; // Size of the data stored in this Input Port. + void *value_ptr; // Pointer to the `buffer` field in the user Input port struct. + size_t value_size; // Size of the data stored in this Input Port. }; struct Output { Port super; - TriggerSources sources; // The reactions that can write to this Output port. }; void Input_ctor(Input *self, Reactor *parent, Reaction **effects, size_t effects_size, Connection **conns_out, @@ -38,6 +36,7 @@ void Output_ctor(Output *self, Reactor *parent, Reaction **sources, size_t sourc size_t conns_out_size); void Port_ctor(Port *self, TriggerType type, Reactor *parent, Connection **conns_out, size_t conns_out_size, + Reaction **sources, size_t sources_size, Reaction **effects, size_t effects_size, void (*prepare)(Trigger *, Event *), void (*cleanup)(Trigger *)); #endif diff --git a/include/reactor-uc/trigger.h b/include/reactor-uc/trigger.h index eacf375db..758e70a6a 100644 --- a/include/reactor-uc/trigger.h +++ b/include/reactor-uc/trigger.h @@ -54,6 +54,8 @@ typedef struct { struct Trigger { TriggerType type; Reactor *parent; + TriggerSources sources; + TriggerEffects effects; bool is_present; bool is_registered_for_cleanup; // Field used by Scheduler to avoid adding the same trigger multiple times to the // linked list of triggers registered for cleanup @@ -64,7 +66,8 @@ struct Trigger { void (*cleanup)(Trigger *); } __attribute__((aligned(MEM_ALIGNMENT))); -void Trigger_ctor(Trigger *self, TriggerType type, Reactor *parent, EventPayloadPool *payload_pool, - void (*prepare)(Trigger *, Event *), void (*cleanup)(Trigger *)); +void Trigger_ctor(Trigger *self, TriggerType type, Reactor *parent, EventPayloadPool *payload_pool, Reaction **sources, + size_t sources_size, Reaction **effects, size_t effects_size, void (*prepare)(Trigger *, Event *), + void (*cleanup)(Trigger *)); #endif diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcPortGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcPortGenerator.kt index 13a41dab9..eb34fa919 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcPortGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcPortGenerator.kt @@ -41,10 +41,10 @@ class UcPortGenerator(private val reactor: Reactor, private val connectionGenera fun getEffects(port: Input) = reactor.reactions.filter { it.triggers.filter { it.name == port.name }.isNotEmpty() } fun getSources(port: Output) = reactor.reactions.filter { it.effects.filter { it.name == port.name }.isNotEmpty() } - fun generateSelfStruct(input: Input) = "DEFINE_INPUT_PORT_STRUCT(${input.codeType}, ${getEffects(input).size}, ${input.type.toText()})" - fun generateInputCtor(input: Input) = "DEFINE_INPUT_PORT_CTOR(${input.codeType}, ${getEffects(input).size}, ${input.type.toText()})" - fun generateSelfStruct(output: Output) = "DEFINE_OUTPUT_PORT_STRUCT(${output.codeType}, ${getSources(output).size})" - fun generateOutputCtor(output: Output) = "DEFINE_OUTPUT_PORT_CTOR(${output.codeType}, ${getSources(output).size})" + fun generateSelfStruct(input: Input) = "DEFINE_INPUT_STRUCT(${input.codeType}, ${getEffects(input).size}, ${input.type.toText()})" + fun generateInputCtor(input: Input) = "DEFINE_INPUT_CTOR(${input.codeType}, ${getEffects(input).size}, ${input.type.toText()})" + fun generateSelfStruct(output: Output) = "DEFINE_OUTPUT_STRUCT(${output.codeType}, ${getSources(output).size})" + fun generateOutputCtor(output: Output) = "DEFINE_OUTPUT_CTOR(${output.codeType}, ${getSources(output).size})" fun generateSelfStructs() = reactor.inputs.plus(reactor.outputs).joinToString(prefix = "// Port structs\n", separator = "\n", postfix = "\n") { when (it) { diff --git a/lib/clock-sync/clock-master.c b/lib/clock-sync/clock-master.c index 6b97788ab..0867f449c 100644 --- a/lib/clock-sync/clock-master.c +++ b/lib/clock-sync/clock-master.c @@ -1,60 +1,62 @@ #include "clock-master.h" -DEFINE_OUTPUT_PORT_CTOR(Out, 2); -DEFINE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); -DEFINE_OUTPUT_PORT_CTOR(Out, 1); -DEFINE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); +DEFINE_ACTION_CTOR_FIXED(ClockMaster, a_periodic, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_ACTION_CTOR_FIXED(ClockMaster, a_send, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); +DEFINE_OUTPUT_CTOR(ClockMaster, p_out, 1); +DEFINE_INPUT_CTOR(ClockMaster, p_in, 1, ClockSyncMessage, 1); + +DEFINE_REACTION_CTOR(ClockMaster, r_startup, 0); +DEFINE_REACTION_CTOR(ClockMaster, r_action, 1); +DEFINE_REACTION_CTOR(ClockMaster, r_input, 2); +DEFINE_REACTION_CTOR(ClockMaster, r_send, 3); // Startup reaction -DEFINE_REACTION_BODY(ClockMaster, 0) { - ClockMaster *self = (ClockMaster *)_self->parent; - Action0 *action = &self->action; - Action0 *send_action = &self->send_action; - Environment *env = self->super.env; +DEFINE_REACTION_BODY(ClockMaster, r_startup) { + SCOPE_SELF(ClockMaster); + SCOPE_ACTION(ClockMaster, a_periodic); + SCOPE_ACTION(ClockMaster, a_send); + SCOPE_ENV(); // Schedule next round - lf_schedule(action, CLOCK_SYNC, self->period); + lf_schedule(a_periodic, CLOCK_SYNC, self->period); // Schedule the sending - lf_schedule(send_action, CLOCK_SYNC, MSEC(0)); + lf_schedule(a_send, CLOCK_SYNC, MSEC(0)); } -DEFINE_REACTION_CTOR(ClockMaster, 0); // Reaction triggered by action. Should start a new round of clock sync. -DEFINE_REACTION_BODY(ClockMaster, 1) { - ClockMaster *self = (ClockMaster *)_self->parent; - Environment *env = self->super.env; - Action0 *action = &self->action; - Action0 *send_action = &self->send_action; - assert(action->value == CLOCK_SYNC); +DEFINE_REACTION_BODY(ClockMaster, r_action) { + SCOPE_SELF(ClockMaster); + SCOPE_ACTION(ClockMaster, a_send); + SCOPE_ACTION(ClockMaster, a_periodic); + assert(a_periodic->value == CLOCK_SYNC); // Schedule the sending - lf_schedule(send_action, CLOCK_SYNC, MSEC(0)); + lf_schedule(a_send, CLOCK_SYNC, MSEC(0)); } -DEFINE_REACTION_CTOR(ClockMaster, 1); // Reaction triggered by input -DEFINE_REACTION_BODY(ClockMaster, 2) { - ClockMaster *self = (ClockMaster *)_self->parent; - Environment *env = self->super.env; - In *in = &self->in; - Action0 *send_action = &self->send_action; - assert(in->value.type == CLOCK_DELAY_REQ); - lf_schedule(send_action, CLOCK_DELAY_RESP, MSEC(0)); +DEFINE_REACTION_BODY(ClockMaster, r_input) { + SCOPE_SELF(ClockMaster); + SCOPE_ENV(); + SCOPE_ACTION(ClockMaster, a_send); + SCOPE_PORT(ClockMaster, p_in); + + assert(p_in->value.type == CLOCK_DELAY_REQ); + lf_schedule(a_send, CLOCK_DELAY_RESP, MSEC(0)); } -DEFINE_REACTION_CTOR(ClockMaster, 2); // Reaction triggered by send action -DEFINE_REACTION_BODY(ClockMaster, 3) { - ClockMaster *self = (ClockMaster *)_self->parent; - Environment *env = self->super.env; - Action0 *action = &self->send_action; - Out *out = &self->out; +DEFINE_REACTION_BODY(ClockMaster, r_send) { + SCOPE_SELF(ClockMaster); + SCOPE_ENV(); + SCOPE_ACTION(ClockMaster, a_send); + SCOPE_PORT(ClockMaster, p_out); ClockSyncMessage msg; - msg.type = action->value; + msg.type = a_send->value; - switch (action->value) { + switch (a_send->value) { case CLOCK_SYNC: msg.time = env->get_physical_time(env); break; @@ -65,6 +67,40 @@ DEFINE_REACTION_BODY(ClockMaster, 3) { assert(0); } - lf_set(out, msg); + lf_set(p_out, msg); } -DEFINE_REACTION_CTOR(ClockMaster, 3); \ No newline at end of file + +void ClockMaster_ctor(ClockMaster *self, Reactor *parent, Environment *env, Connection **conn_out, interval_t period) { + int _reactions_idx = 0; + int _triggers_idx = 0; + int _child_idx = 0; + + INIT_REACTION(ClockMaster, r_startup); + INIT_REACTION(ClockMaster, r_action); + INIT_REACTION(ClockMaster, r_input); + INIT_REACTION(ClockMaster, r_send); + + INIT_STARTUP(ClockMaster); + INIT_ACTION(ClockMaster, a_send); + INIT_ACTION(ClockMaster, a_periodic); + INIT_OUTPUT(ClockMaster, p_out, conn_out, 1); + INIT_INPUT(ClockMaster, p_in); + + self->period = period; + + Reactor_ctor(&self->super, "ClockSync", env, parent, self->_children, _child_idx, self->_reactions, _reactions_idx, + self->_triggers, _triggers_idx); + + REACTION_TRIGGER(r_action, a_periodic); + REACTION_EFFECT(r_action, r_send); + + REACTION_TRIGGER(r_input, p_in); + REACTION_EFFECT(r_input, r_send); + + REACTION_TRIGGER(r_startup, startup); + REACTION_EFFECT(r_startup, a_periodic); + REACTION_EFFECT(r_startup, a_send); + + REACTION_TRIGGER(r_send, a_send); + REACTION_EFFECT(r_send, p_out); +} \ No newline at end of file diff --git a/lib/clock-sync/clock-master.h b/lib/clock-sync/clock-master.h index 57987bf01..96161c76e 100644 --- a/lib/clock-sync/clock-master.h +++ b/lib/clock-sync/clock-master.h @@ -4,82 +4,40 @@ #include "reactor-uc/reactor-uc.h" #include "clock-sync.h" -DEFINE_ACTION_STRUCT(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); -DECLARE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); -DEFINE_STARTUP_STRUCT(Startup0, 1); -DECLARE_STARTUP_CTOR(Startup0, 1); -DEFINE_OUTPUT_PORT_STRUCT(Out, 2, 1); -DECLARE_OUTPUT_PORT_CTOR(Out, 2); -DEFINE_INPUT_PORT_STRUCT(In, 1, ClockSyncMessage, 1); -DECLARE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); +DEFINE_ACTION_STRUCT(ClockMaster, a_send, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); +DEFINE_ACTION_STRUCT(ClockMaster, a_periodic, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); +DEFINE_STARTUP_STRUCT(ClockMaster, 1); +DEFINE_OUTPUT_STRUCT(ClockMaster, p_out, 2, 1); +DEFINE_INPUT_STRUCT(ClockMaster, p_in, 1, ClockSyncMessage, 1); -DEFINE_REACTION_STRUCT(ClockMaster, 0, 1); -DEFINE_REACTION_STRUCT(ClockMaster, 1, 2); -DEFINE_REACTION_STRUCT(ClockMaster, 2, 1); -DEFINE_REACTION_STRUCT(ClockMaster, 3, 1); - -DECLARE_REACTION_CTOR(ClockMaster, 0); -DECLARE_REACTION_CTOR(ClockMaster, 1); -DECLARE_REACTION_CTOR(ClockMaster, 2); -DECLARE_REACTION_CTOR(ClockMaster, 3); +DEFINE_REACTION_STRUCT(ClockMaster, r_startup, 1); +DEFINE_REACTION_STRUCT(ClockMaster, r_action, 2); +DEFINE_REACTION_STRUCT(ClockMaster, r_send, 1); +DEFINE_REACTION_STRUCT(ClockMaster, r_input, 1); #define CLOCK_MASTER_NUM_REACTIONS 4 -#define CLOCK_MASTER_NUM_TRIGGERS 5 +#define CLOCK_MASTER_NUM_TRIGGERS 4 +#define CLOCK_MASTER_NUM_CHILDREN 0 typedef struct { Reactor super; - ClockMaster_Reaction0 reaction0; - ClockMaster_Reaction1 reaction1; - ClockMaster_Reaction2 reaction2; - ClockMaster_Reaction3 reaction3; - Action0 action; - Action0 send_action; - Startup0 startup; - Out out; - In in; + + INSTANTIATE_REACTION(ClockMaster, r_startup); + INSTANTIATE_REACTION(ClockMaster, r_action); + INSTANTIATE_REACTION(ClockMaster, r_send); + INSTANTIATE_REACTION(ClockMaster, r_input); + INSTANTIATE_ACTION(ClockMaster, a_send); + INSTANTIATE_ACTION(ClockMaster, a_periodic); + INSTANTIATE_STARTUP(ClockMaster); + INSTANTIATE_PORT(ClockMaster, p_out); + INSTANTIATE_PORT(ClockMaster, p_in); + Reaction *_reactions[CLOCK_MASTER_NUM_REACTIONS]; Trigger *_triggers[CLOCK_MASTER_NUM_TRIGGERS]; + Reactor *_children[CLOCK_MASTER_NUM_CHILDREN]; interval_t period; } ClockMaster; -void ClockMaster_ctor(ClockMaster *self, Environment *env, Connection **conn_out, interval_t period) { - self->_reactions[0] = (Reaction *)&self->reaction0; - self->_reactions[1] = (Reaction *)&self->reaction1; - self->_reactions[2] = (Reaction *)&self->reaction2; - self->_reactions[3] = (Reaction *)&self->reaction3; - self->_triggers[0] = (Trigger *)&self->startup; - self->_triggers[1] = (Trigger *)&self->action; - self->_triggers[2] = (Trigger *)&self->send_action; - self->_triggers[3] = (Trigger *)&self->out; - self->_triggers[4] = (Trigger *)&self->in; - - self->period = period; - Reactor_ctor(&self->super, "ClockSync", env, NULL, NULL, 0, self->_reactions, CLOCK_MASTER_NUM_REACTIONS, - self->_triggers, CLOCK_MASTER_NUM_TRIGGERS); - - ClockMaster_Reaction0_ctor(&self->reaction0, &self->super); - ClockMaster_Reaction1_ctor(&self->reaction1, &self->super); - ClockMaster_Reaction2_ctor(&self->reaction2, &self->super); - ClockMaster_Reaction3_ctor(&self->reaction3, &self->super); - - Action0_ctor(&self->action, &self->super); - Action0_ctor(&self->send_action, &self->super); - Startup0_ctor(&self->startup, &self->super); - In_ctor(&self->in, &self->super); - Out_ctor(&self->out, &self->super, conn_out, 1); - - ACTION_REGISTER_EFFECT(self->action, self->reaction1); - ACTION_REGISTER_EFFECT(self->send_action, self->reaction3); - BUILTIN_REGISTER_EFFECT(self->startup, self->reaction0); - INPUT_REGISTER_EFFECT(self->in, self->reaction2); - OUTPUT_REGISTER_SOURCE(self->out, self->reaction1); - OUTPUT_REGISTER_SOURCE(self->out, self->reaction2); - ACTION_REGISTER_SOURCE(self->action, self->reaction1); - REACTION_REGISTER_EFFECT(self->reaction0, self->action); - REACTION_REGISTER_EFFECT(self->reaction1, self->action); - REACTION_REGISTER_EFFECT(self->reaction1, self->send_action); - REACTION_REGISTER_EFFECT(self->reaction2, self->send_action); - REACTION_REGISTER_EFFECT(self->reaction3, self->out); -} +void ClockMaster_ctor(ClockMaster *self, Environment *env, Connection **conn_out, interval_t period); #endif diff --git a/lib/clock-sync/clock-slave.c b/lib/clock-sync/clock-slave.c index 2f79cdf19..bb6cb22b3 100644 --- a/lib/clock-sync/clock-slave.c +++ b/lib/clock-sync/clock-slave.c @@ -1,10 +1,10 @@ #include "clock-slave.h" -DEFINE_OUTPUT_PORT_CTOR(Out, 2); +DEFINE_OUTPUT_CTOR(Out, 2); DEFINE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); -DEFINE_OUTPUT_PORT_CTOR(Out, 1); -DEFINE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); +DEFINE_OUTPUT_CTOR(Out, 1); +DEFINE_INPUT_CTOR(In, 1, ClockSyncMessage, 1); // TODO: Make sure that we dont overwrite timestamps before we have calculated the offset. // maybe the slave should request this whole thing, and not the master? @@ -51,4 +51,33 @@ DEFINE_REACTION_BODY(ClockSlave, 2) { assert(0); } } -DEFINE_REACTION_CTOR(ClockSlave, 2); \ No newline at end of file +DEFINE_REACTION_CTOR(ClockSlave, 2); + +void ClockSlave_ctor(ClockSlave *self, Environment *env, Connection **conn_out) { + self->_reactions[0] = (Reaction *)&self->reaction0; + self->_reactions[1] = (Reaction *)&self->reaction1; + self->_reactions[2] = (Reaction *)&self->reaction2; + self->_triggers[0] = (Trigger *)&self->startup; + self->_triggers[1] = (Trigger *)&self->send_action; + self->_triggers[2] = (Trigger *)&self->out; + self->_triggers[3] = (Trigger *)&self->in; + + Reactor_ctor(&self->super, "ClockSlave", env, NULL, NULL, 0, self->_reactions, CLOCK_SLAVE_NUM_REACTIONS, + self->_triggers, CLOCK_SLAVE_NUM_TRIGGERS); + + ClockSlave_Reaction0_ctor(&self->reaction0, &self->super); + ClockSlave_Reaction1_ctor(&self->reaction1, &self->super); + ClockSlave_Reaction2_ctor(&self->reaction2, &self->super); + + Action0_ctor(&self->send_action, &self->super); + Startup0_ctor(&self->startup, &self->super); + In_ctor(&self->in, &self->super); + Out_ctor(&self->out, &self->super, conn_out, 1); + + BUILTIN_REGISTER_EFFECT(self->startup, self->reaction0); + ACTION_REGISTER_EFFECT(self->send_action, self->reaction1); + INPUT_REGISTER_EFFECT(self->in, self->reaction2); + OUTPUT_REGISTER_SOURCE(self->out, self->reaction1); + REACTION_REGISTER_EFFECT(self->reaction2, self->send_action); + REACTION_REGISTER_EFFECT(self->reaction1, self->out); +} \ No newline at end of file diff --git a/lib/clock-sync/clock-slave.h b/lib/clock-sync/clock-slave.h index 4af97a0cb..be4fc172a 100644 --- a/lib/clock-sync/clock-slave.h +++ b/lib/clock-sync/clock-slave.h @@ -5,22 +5,14 @@ #include "clock-sync.h" DEFINE_ACTION_STRUCT(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1); -DECLARE_ACTION_CTOR_FIXED(Action0, LOGICAL_ACTION, 1, 1, ClockSyncMessageType, 1, MSEC(0)); DEFINE_STARTUP_STRUCT(Startup0, 1); -DECLARE_STARTUP_CTOR(Startup0, 1); -DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 1); -DECLARE_OUTPUT_PORT_CTOR(Out, 1); -DEFINE_INPUT_PORT_STRUCT(In, 1, ClockSyncMessage, 1); -DECLARE_INPUT_PORT_CTOR(In, 1, ClockSyncMessage, 1); +DEFINE_OUTPUT_STRUCT(Out, 1, 1); +DEFINE_INPUT_STRUCT(In, 1, ClockSyncMessage, 1); DEFINE_REACTION_STRUCT(ClockSlave, 0, 0); DEFINE_REACTION_STRUCT(ClockSlave, 1, 1); DEFINE_REACTION_STRUCT(ClockSlave, 2, 1); -DECLARE_REACTION_CTOR(ClockSlave, 0); -DECLARE_REACTION_CTOR(ClockSlave, 1); -DECLARE_REACTION_CTOR(ClockSlave, 2); - #define CLOCK_SLAVE_NUM_REACTIONS 3 #define CLOCK_SLAVE_NUM_TRIGGERS 4 @@ -33,41 +25,12 @@ typedef struct { Startup0 startup; Out out; In in; - Reaction *_reactions[CLOCK_SLAVE_NUM_REACTIONS]; - Trigger *_triggers[CLOCK_SLAVE_NUM_TRIGGERS]; instant_t t1; instant_t t2; instant_t t3; instant_t t4; + Reaction *_reactions[CLOCK_SLAVE_NUM_REACTIONS]; + Trigger *_triggers[CLOCK_SLAVE_NUM_TRIGGERS]; } ClockSlave; -void ClockSlave_ctor(ClockSlave *self, Environment *env, Connection **conn_out) { - self->_reactions[0] = (Reaction *)&self->reaction0; - self->_reactions[1] = (Reaction *)&self->reaction1; - self->_reactions[2] = (Reaction *)&self->reaction2; - self->_triggers[0] = (Trigger *)&self->startup; - self->_triggers[1] = (Trigger *)&self->send_action; - self->_triggers[2] = (Trigger *)&self->out; - self->_triggers[3] = (Trigger *)&self->in; - - Reactor_ctor(&self->super, "ClockSlave", env, NULL, NULL, 0, self->_reactions, CLOCK_SLAVE_NUM_REACTIONS, - self->_triggers, CLOCK_SLAVE_NUM_TRIGGERS); - - ClockSlave_Reaction0_ctor(&self->reaction0, &self->super); - ClockSlave_Reaction1_ctor(&self->reaction1, &self->super); - ClockSlave_Reaction2_ctor(&self->reaction2, &self->super); - - Action0_ctor(&self->send_action, &self->super); - Startup0_ctor(&self->startup, &self->super); - In_ctor(&self->in, &self->super); - Out_ctor(&self->out, &self->super, conn_out, 1); - - BUILTIN_REGISTER_EFFECT(self->startup, self->reaction0); - ACTION_REGISTER_EFFECT(self->send_action, self->reaction1); - INPUT_REGISTER_EFFECT(self->in, self->reaction2); - OUTPUT_REGISTER_SOURCE(self->out, self->reaction1); - REACTION_REGISTER_EFFECT(self->reaction2, self->send_action); - REACTION_REGISTER_EFFECT(self->reaction1, self->out); -} - #endif diff --git a/src/action.c b/src/action.c index de8c33747..cb9086ecd 100644 --- a/src/action.c +++ b/src/action.c @@ -76,18 +76,12 @@ void Action_ctor(Action *self, ActionType type, interval_t min_offset, Reactor * size_t sources_size, Reaction **effects, size_t effects_size, void *value_ptr, size_t value_size, void *payload_buf, bool *payload_used_buf, size_t payload_buf_capacity) { EventPayloadPool_ctor(&self->payload_pool, payload_buf, payload_used_buf, value_size, payload_buf_capacity); - Trigger_ctor(&self->super, TRIG_ACTION, parent, &self->payload_pool, Action_prepare, Action_cleanup); + Trigger_ctor(&self->super, TRIG_ACTION, parent, &self->payload_pool, effects, effects_size, sources, sources_size, + Action_prepare, Action_cleanup); self->type = type; self->value_ptr = value_ptr; self->min_offset = min_offset; self->schedule = Action_schedule; - self->sources.reactions = sources; - self->sources.num_registered = 0; - self->sources.size = sources_size; - self->effects.reactions = effects; - self->effects.size = effects_size; - self->effects.num_registered = 0; - if (type == PHYSICAL_ACTION) { self->super.parent->env->has_async_events = true; } diff --git a/src/builtin_triggers.c b/src/builtin_triggers.c index 87dc54453..26f1268aa 100644 --- a/src/builtin_triggers.c +++ b/src/builtin_triggers.c @@ -26,10 +26,7 @@ void Builtin_cleanup(Trigger *self) { void BuiltinTrigger_ctor(BuiltinTrigger *self, TriggerType type, Reactor *parent, Reaction **effects, size_t effects_size) { - Trigger_ctor(&self->super, type, parent, NULL, Builtin_prepare, Builtin_cleanup); - self->effects.reactions = effects; - self->effects.num_registered = 0; - self->effects.size = effects_size; + Trigger_ctor(&self->super, type, parent, NULL, NULL, 0, effects, effects_size, Builtin_prepare, Builtin_cleanup); self->next = NULL; if (type == TRIG_STARTUP) { diff --git a/src/connection.c b/src/connection.c index 6b5b6a524..7f113c341 100644 --- a/src/connection.c +++ b/src/connection.c @@ -73,7 +73,7 @@ void Connection_ctor(Connection *self, TriggerType type, Reactor *parent, Port * self->get_final_upstream = Connection_get_final_upstream; self->trigger_downstreams = trigger_downstreams; - Trigger_ctor(&self->super, type, parent, payload_pool, prepare, cleanup); + Trigger_ctor(&self->super, type, parent, NULL, 0, NULL, 0, payload_pool, prepare, cleanup); } void LogicalConnection_ctor(LogicalConnection *self, Reactor *parent, Port **downstreams, size_t num_downstreams) { diff --git a/src/port.c b/src/port.c index 932bcc117..4d34c61c0 100644 --- a/src/port.c +++ b/src/port.c @@ -29,10 +29,8 @@ void Input_cleanup(Trigger *_self) { void Input_ctor(Input *self, Reactor *parent, Reaction **effects, size_t effects_size, Connection **conns_out, size_t conns_out_size, void *value_ptr, size_t value_size) { - Port_ctor(&self->super, TRIG_INPUT, parent, conns_out, conns_out_size, Input_prepare, Input_cleanup); - self->effects.reactions = effects; - self->effects.num_registered = 0; - self->effects.size = effects_size; + Port_ctor(&self->super, TRIG_INPUT, parent, conns_out, conns_out_size, NULL, 0, effects, effects_size, Input_prepare, + Input_cleanup); self->value_ptr = value_ptr; self->value_size = value_size; } @@ -40,15 +38,13 @@ void Input_ctor(Input *self, Reactor *parent, Reaction **effects, size_t effects void Output_ctor(Output *self, Reactor *parent, Reaction **sources, size_t sources_size, Connection **conns_out, size_t conns_out_size) { - Port_ctor(&self->super, TRIG_OUTPUT, parent, conns_out, conns_out_size, NULL, NULL); - self->sources.reactions = sources; - self->sources.size = sources_size; - self->sources.num_registered = 0; + Port_ctor(&self->super, TRIG_OUTPUT, parent, conns_out, conns_out_size, sources, sources_size, NULL, 0, NULL, NULL); } void Port_ctor(Port *self, TriggerType type, Reactor *parent, Connection **conns_out, size_t conns_out_size, + Reaction **sources, size_t sources_size, Reaction **effects, size_t effects_size, void (*prepare)(Trigger *, Event *), void (*cleanup)(Trigger *)) { - Trigger_ctor(&self->super, type, parent, NULL, prepare, cleanup); + Trigger_ctor(&self->super, type, parent, NULL, sources, sources_size, effects, effects_size, prepare, cleanup); self->conn_in = NULL; self->conns_out = conns_out; self->conns_out_size = conns_out_size; diff --git a/src/timer.c b/src/timer.c index 1ce5b983b..589a508c0 100644 --- a/src/timer.c +++ b/src/timer.c @@ -33,9 +33,6 @@ void Timer_ctor(Timer *self, Reactor *parent, instant_t offset, interval_t perio size_t effects_size) { self->offset = offset; self->period = period; - self->effects.reactions = effects; - self->effects.size = effects_size; - self->effects.num_registered = 0; - Trigger_ctor(&self->super, TRIG_TIMER, parent, NULL, Timer_prepare, Timer_cleanup); + Trigger_ctor(&self->super, TRIG_TIMER, parent, NULL, NULL, 0, effects, effects_size, Timer_prepare, Timer_cleanup); } diff --git a/src/trigger.c b/src/trigger.c index 395d135d7..938009513 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -1,13 +1,20 @@ #include "reactor-uc/trigger.h" #include "reactor-uc/environment.h" -void Trigger_ctor(Trigger *self, TriggerType type, Reactor *parent, EventPayloadPool *payload_pool, - void (*prepare)(Trigger *, Event *), void (*cleanup)(Trigger *)) { +void Trigger_ctor(Trigger *self, TriggerType type, Reactor *parent, EventPayloadPool *payload_pool, Reaction **sources, + size_t sources_size, Reaction **effects, size_t effects_size, void (*prepare)(Trigger *, Event *), + void (*cleanup)(Trigger *)) { self->type = type; self->parent = parent; self->next = NULL; self->is_present = false; self->is_registered_for_cleanup = false; + self->sources.reactions = sources; + self->sources.size = sources_size; + self->sources.num_registered = 0; + self->effects.reactions = effects; + self->effects.size = effects_size; + self->effects.num_registered = 0; self->prepare = prepare; self->cleanup = cleanup; self->payload_pool = payload_pool; diff --git a/test/unit/delayed_conn_test.c b/test/unit/delayed_conn_test.c index b16c86c65..88f424911 100644 --- a/test/unit/delayed_conn_test.c +++ b/test/unit/delayed_conn_test.c @@ -5,8 +5,8 @@ DEFINE_TIMER_STRUCT(Timer1, 1) DEFINE_TIMER_CTOR_FIXED(Timer1, 1, 0, MSEC(10)) DEFINE_REACTION_STRUCT(Sender, 0, 0); -DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 1) -DEFINE_OUTPUT_PORT_CTOR(Out, 1) +DEFINE_OUTPUT_STRUCT(Out, 1, 1) +DEFINE_OUTPUT_CTOR(Out, 1) typedef struct { Reactor super; @@ -43,8 +43,8 @@ void Sender_ctor(Sender *self, Reactor *parent, Environment *env, Connection **c // Reactor Receiver DEFINE_REACTION_STRUCT(Receiver, 0, 0) -DEFINE_INPUT_PORT_STRUCT(In, 1, interval_t, 1) -DEFINE_INPUT_PORT_CTOR(In, 1, interval_t, 1) +DEFINE_INPUT_STRUCT(In, 1, interval_t, 1) +DEFINE_INPUT_CTOR(In, 1, interval_t, 1) typedef struct { Reactor super; diff --git a/test/unit/port_test.c b/test/unit/port_test.c index 2c7d7cc91..37361058b 100644 --- a/test/unit/port_test.c +++ b/test/unit/port_test.c @@ -5,8 +5,8 @@ DEFINE_TIMER_STRUCT(Timer1, 1) DEFINE_TIMER_CTOR_FIXED(Timer1, 1, 0, SEC(1)) DEFINE_REACTION_STRUCT(Sender, 0, 0) -DEFINE_OUTPUT_PORT_STRUCT(Out, 1, 1) -DEFINE_OUTPUT_PORT_CTOR(Out, 1) +DEFINE_OUTPUT_STRUCT(Out, 1, 1) +DEFINE_OUTPUT_CTOR(Out, 1) typedef struct { Reactor super; @@ -41,8 +41,8 @@ void Sender_ctor(Sender *self, Reactor *parent, Environment *env, Connection **c // Reactor Receiver DEFINE_REACTION_STRUCT(Receiver, 0, 0) -DEFINE_INPUT_PORT_STRUCT(In, 1, instant_t, 1) -DEFINE_INPUT_PORT_CTOR(In, 1, instant_t, 1) +DEFINE_INPUT_STRUCT(In, 1, instant_t, 1) +DEFINE_INPUT_CTOR(In, 1, instant_t, 1) typedef struct { Reactor super;