Skip to content

Commit

Permalink
Macro Reactions
Browse files Browse the repository at this point in the history
  • Loading branch information
tanneberger committed Oct 17, 2024
1 parent 2975a7f commit 5488eb8
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 100 deletions.
78 changes: 54 additions & 24 deletions include/reactor-uc/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,28 @@
((Connection *)&(conn))->upstream = (Port *)&(up); \
} while (0)


typedef struct Output Output;

#define DEFINE_OUTPUT_PORT(PortName, SourceSize) \
typedef struct {Output super; Reaction *sources[SourceSize];} PortName;
typedef struct { \
Output super; \
Reaction *sources[SourceSize]; \
} PortName;

#define CONSTRUCT_OUTPUT_PORT(PortName, ReactorType) \
#define CONSTRUCT_OUTPUT_PORT(PortName, ReactorType) \
void PortName##_ctor(PortName *self, ReactorType *parent) { \
Output_ctor(&self->super, &parent->super, self->sources, sizeof(self->sources) / sizeof(typeof(self->sources[0]))); \
Output_ctor(&self->super, &parent->super, self->sources, \
sizeof(self->sources) / sizeof(typeof(self->sources[0]))); \
}

typedef struct Input Input;

#define DEFINE_INPUT_PORT(PortName, EffectSize, BufferType, BufferSize) \
typedef struct {Input super; Reaction *effects[EffectSize]; BufferType buffer[BufferSize];} PortName;

typedef struct { \
Input super; \
Reaction *effects[EffectSize]; \
BufferType buffer[BufferSize]; \
} PortName;

#define CONSTRUCT_INPUT_PORT(PortName, ReactorName) \
void PortName##_ctor(PortName *self, ReactorName *parent) { \
Expand All @@ -115,52 +121,76 @@ typedef struct Input Input;

typedef struct Timer Timer;

#define DEFINE_TIMER(TimerName, EffectSize) \
typedef struct {Timer super; Reaction *effects[EffectSize]; } TimerName;
#define DEFINE_TIMER(TimerName, EffectSize) \
typedef struct { \
Timer super; \
Reaction *effects[EffectSize]; \
} TimerName;

typedef struct Reaction Reaction;

#define DEFINE_REACTION(ReactionName, EffectSize) \
typedef struct {Reaction super; Trigger *effects[EffectSize];} ReactionName;

#define CONSTRUCT_REACTION(ReactionName, ReactorName, ReactionBody, ReactionIndex) \
typedef struct { \
Reaction super; \
Trigger *effects[EffectSize]; \
} ReactionName;

#define CONSTRUCT_REACTION(ReactionName, ReactorName, ReactionIndex, ReactionBody) \
void ReactionName##_##ReactionIndex(Reaction *_self) { \
ReactorName *self = (ReactorName *)_self->parent; \
Environment *env = self->super.env; \
ReactionBody \
} \
void ReactionName##_ctor(ReactionName *self, ReactorName *parent) { \
Reaction_ctor(&self->super, &parent->super, ReactionBody, self->effects, \
Reaction_ctor(&self->super, &parent->super, ReactionName##_##ReactionIndex, self->effects, \
sizeof(self->effects) / sizeof(self->effects[0]), ReactionIndex); \
}

typedef struct Startup Startup;

#define DEFINE_STARTUP(StartupName, EffectSize) \
typedef struct {Startup super; Reaction *effects[EffectSize];} StartupName;
typedef struct { \
Startup super; \
Reaction *effects[EffectSize]; \
} StartupName;

#define CONSTRUCT_STARTUP(StartupName, ReactorName) \
#define CONSTRUCT_STARTUP(StartupName, ReactorName) \
void StartupName##_ctor(StartupName *self, ReactorName *parent) { \
Startup_ctor(&self->super, &parent->super, self->effects, sizeof(self->effects) / sizeof(self->effects[0])); \
Startup_ctor(&self->super, &parent->super, self->effects, sizeof(self->effects) / sizeof(self->effects[0])); \
}

typedef struct Shutdown Shutdown;

#define DEFINE_SHUTDOWN(ShutdownName, EffectSize) \
typedef struct {Shutdown super; Reaction *effects[EffectSize]; } ShutdownName;
typedef struct { \
Shutdown super; \
Reaction *effects[EffectSize]; \
} ShutdownName;

#define CONSTRUCT_SHUTDOWN(ShutdownName, ReactorName) \
#define CONSTRUCT_SHUTDOWN(ShutdownName, ReactorName) \
void ShutdownName##_ctor(ShutdownName *self, ReactorName *parent) { \
Shutdown_ctor(&self->super, &parent->super, self->effects, sizeof(self->effects) / sizeof(self->effects[0])); \
}

typedef struct LogicalAction LogicalAction;

#define DEFINE_LOGICAL_ACTION(TypeName, EffectSize, SourceSize, BufferTyp, BufferSize) \
typedef struct {LogicalAction super; BufferTyp buffer[BufferSize]; \
Reaction *sources[SourceSize]; Reaction *effects[EffectSize];} TypeName;
#define DEFINE_LOGICAL_ACTION(TypeName, EffectSize, SourceSize, BufferTyp, BufferSize) \
typedef struct { \
LogicalAction super; \
BufferTyp buffer[BufferSize]; \
Reaction *sources[SourceSize]; \
Reaction *effects[EffectSize]; \
} TypeName;

typedef struct PhysicalAction PhysicalAction;

#define DEFINE_PHYSICAL_ACTION(TypeName, EffectSize, SourceSize, BufferTyp, BufferSize) \
typedef struct {PhysicalAction super; BufferTyp buffer[BufferSize]; \
Reaction *sources[SourceSize]; Reaction *effects[EffectSize];} TypeName;

#define DEFINE_PHYSICAL_ACTION(TypeName, EffectSize, SourceSize, BufferTyp, BufferSize) \
typedef struct { \
PhysicalAction super; \
BufferTyp buffer[BufferSize]; \
Reaction *sources[SourceSize]; \
Reaction *effects[EffectSize]; \
} TypeName;

// TODO: The following macro is defined to avoid compiler warnings. Ideally we would
// not have to specify any alignment on any structs. It is a TODO to understand exactly why
Expand Down
8 changes: 2 additions & 6 deletions test/unit/action_microstep_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ void MyAction_ctor(MyAction *self, MyReactor *parent) {

CONSTRUCT_STARTUP(MyStartup, MyReactor);

void action_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_REACTION(MyReaction, MyReactor, 0, {
MyAction *my_action = &self->my_action;
if (self->cnt == 0) {
TEST_ASSERT_EQUAL(lf_is_present(my_action), false);
Expand All @@ -47,9 +45,7 @@ void action_handler(Reaction *_self) {
if (self->cnt < 100) {
lf_schedule(my_action, ++self->cnt, 0);
}
}

CONSTRUCT_REACTION(MyReaction, MyReactor, action_handler, 0);
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
Expand Down
7 changes: 2 additions & 5 deletions test/unit/action_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ void MyAction_ctor(MyAction *self, MyReactor *parent) {

CONSTRUCT_STARTUP(MyStartup, MyReactor)

void action_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
CONSTRUCT_REACTION(MyReaction, MyReactor, 0, {
MyAction *my_action = &self->my_action;
if (self->cnt == 0) {
TEST_ASSERT_EQUAL(lf_is_present(my_action), false);
Expand All @@ -38,9 +37,7 @@ void action_handler(Reaction *_self) {
}

lf_schedule(my_action, ++self->cnt, MSEC(100));
}

CONSTRUCT_REACTION(MyReaction, MyReactor, action_handler, 0);
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
Expand Down
19 changes: 5 additions & 14 deletions test/unit/delayed_conn_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@ typedef struct {
Trigger *_triggers[1];
} Sender;

void timer_handler(Reaction *_self) {
Sender *self = (Sender *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_OUTPUT_PORT(Out, Sender)
CONSTRUCT_REACTION(Reaction1, Sender, 0, {
Out *out = &self->out;

printf("Timer triggered @ %ld\n", env->get_elapsed_logical_time(env));
lf_set(out, env->get_elapsed_logical_time(env));
}

CONSTRUCT_REACTION(Reaction1, Sender, timer_handler, 0);

CONSTRUCT_OUTPUT_PORT(Out, Sender)
});

void Sender_ctor(Sender *self, Reactor *parent, Environment *env) {
self->_reactions[0] = (Reaction *)&self->reaction;
Expand Down Expand Up @@ -57,16 +52,12 @@ typedef struct {

CONSTRUCT_INPUT_PORT(In, Receiver);

void input_handler(Reaction *_self) {
Receiver *self = (Receiver *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_REACTION(Reaction2, Receiver, 0, {
In *inp = &self->inp;

printf("Input triggered @ %ld with %ld\n", env->get_elapsed_logical_time(env), lf_get(inp));
TEST_ASSERT_EQUAL(lf_get(inp) + MSEC(150), env->get_elapsed_logical_time(env));
}

CONSTRUCT_REACTION(Reaction2, Receiver, input_handler, 0);
});

void Receiver_ctor(Receiver *self, Reactor *parent, Environment *env) {
self->_reactions[0] = (Reaction *)&self->reaction;
Expand Down
29 changes: 11 additions & 18 deletions test/unit/physical_action_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,28 @@ void *async_action_scheduler(void *_action) {
}

pthread_t thread;
void startup_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
MyAction *action = &self->my_action;
pthread_create(&thread, NULL, async_action_scheduler, (void *)action);
}

void shutdown_handler(Reaction *_self) {
(void)_self;
run_thread = false;
void *retval;
int ret = pthread_join(thread, &retval);
}

CONSTRUCT_STARTUP(MyStartup, MyReactor);
CONSTRUCT_SHUTDOWN(MyShutdown, MyReactor)

CONSTRUCT_REACTION(StartupReaction, MyReactor, startup_handler, 0);
CONSTRUCT_REACTION(StartupReaction, MyReactor, 0, {
MyAction *action = &self->my_action;
pthread_create(&thread, NULL, async_action_scheduler, (void *)action);
});

void action_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
CONSTRUCT_REACTION(MyReaction, MyReactor, 1, {
MyAction *my_action = &self->my_action;

printf("Hello World\n");
printf("PhysicalAction = %d\n", lf_get(my_action));
TEST_ASSERT_EQUAL(lf_get(my_action), self->cnt++);
}
});

CONSTRUCT_REACTION(MyReaction, MyReactor, action_handler, 1);
CONSTRUCT_REACTION(ShutdownReaction, MyReactor, shutdown_handler, 2);
CONSTRUCT_REACTION(ShutdownReaction, MyReactor, 2, {
run_thread = false;
void *retval;
int ret = pthread_join(thread, &retval);
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[1] = (Reaction *)&self->my_reaction;
Expand Down
18 changes: 4 additions & 14 deletions test/unit/port_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

// Components of Reactor Sender
DEFINE_TIMER(Timer1, 1);

DEFINE_REACTION(Reaction1, 0);

DEFINE_OUTPUT_PORT(Out, 1);

typedef struct {
Expand All @@ -17,16 +15,12 @@ typedef struct {
Trigger *_triggers[1];
} Sender;

void timer_handler(Reaction *_self) {
Sender *self = (Sender *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_REACTION(Reaction1, Sender, 0, {
Out *out = &self->out;

printf("Timer triggered @ %ld\n", env->get_elapsed_logical_time(env));
lf_set(out, env->get_elapsed_logical_time(env));
}

CONSTRUCT_REACTION(Reaction1, Sender, timer_handler, 0);
});

CONSTRUCT_OUTPUT_PORT(Out, Sender)

Expand Down Expand Up @@ -56,16 +50,12 @@ typedef struct {

CONSTRUCT_INPUT_PORT(In, Receiver);

void input_handler(Reaction *_self) {
Receiver *self = (Receiver *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_REACTION(Reaction2, Receiver, 0, {
In *inp = &self->inp;

printf("Input triggered @ %ld with %ld\n", env->get_elapsed_logical_time(env), lf_get(inp));
TEST_ASSERT_EQUAL(lf_get(inp), env->get_elapsed_logical_time(env));
}

CONSTRUCT_REACTION(Reaction2, Receiver, input_handler, 0);
});

void Receiver_ctor(Receiver *self, Reactor *parent, Environment *env) {
self->_reactions[0] = (Reaction *)&self->reaction;
Expand Down
13 changes: 6 additions & 7 deletions test/unit/shutdown_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ typedef struct {

CONSTRUCT_STARTUP(MyStartup, MyReactor)

void Reaction1_body(Reaction *_self) { printf("Startup reaction executing\n"); }

CONSTRUCT_REACTION(Reaction1, MyReactor, Reaction1_body, 0);

CONSTRUCT_REACTION(Reaction1, MyReactor, 0, {
printf("Startup reaction executing\n");
});

CONSTRUCT_SHUTDOWN(MyShutdown, MyReactor)

void Reaction2_body(Reaction *_self) { printf("Shutdown reaction executing\n"); }

CONSTRUCT_REACTION(Reaction2, MyReactor, Reaction2_body, 0);
CONSTRUCT_REACTION(Reaction2, MyReactor, 1, {
printf("Shutdown reaction executing\n");
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->reaction1;
Expand Down
8 changes: 2 additions & 6 deletions test/unit/startup_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@ typedef struct {

CONSTRUCT_STARTUP(MyStartup, MyReactor);

void startup_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
(void)self;
CONSTRUCT_REACTION(MyReaction, MyReactor, 0, {
printf("Hello World\n");
}

CONSTRUCT_REACTION(MyReaction, MyReactor, startup_handler, 0);
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
Expand Down
8 changes: 2 additions & 6 deletions test/unit/timer_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@ typedef struct {
Trigger *_triggers[1];
} MyReactor;

void timer_handler(Reaction *_self) {
MyReactor *self = (MyReactor *)_self->parent;
Environment *env = self->super.env;
CONSTRUCT_REACTION(MyReaction, MyReactor, 0, {
printf("Hello World @ %ld\n", env->get_elapsed_logical_time(env));
}

CONSTRUCT_REACTION(MyReaction, MyReactor, timer_handler, 0);
});

void MyReactor_ctor(MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
Expand Down

0 comments on commit 5488eb8

Please sign in to comment.