Skip to content

Commit

Permalink
more generic bounds checks for actions
Browse files Browse the repository at this point in the history
  • Loading branch information
tanneberger committed Nov 5, 2024
1 parent 41ddf4e commit 0f012a2
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 12 deletions.
2 changes: 2 additions & 0 deletions include/reactor-uc/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct Action {
TriggerEffects effects; // The reactions triggered by this Action.
TriggerSources sources; // The reactions that can write to this Action.
EventPayloadPool payload_pool; // Pool of memory for the data associated with the events scheduled on this action.
size_t event_bound;
size_t events_scheduled;
/**
* @brief Schedule an event on this action.
*/
Expand Down
14 changes: 7 additions & 7 deletions include/reactor-uc/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,21 +220,21 @@

#define DEFINE_ACTION_STRUCT(...) DEFINE_ACTION_STRUCT_CHOOSER(__VA_ARGS__)(__VA_ARGS__)

#define DEFINE_ACTION_CTOR_WITH_VALUE(ActionName, ActionType, MinDelay, EffectSize, SourceSize, BufferType, \
BufferSize) \
void ActionName##_ctor(ActionName *self, Reactor *parent) { \
#define DEFINE_ACTION_CTOR_WITH_VALUE(ActionName, ActionType, MinDelay, EffectSize, SourceSize, EventBound, \
BufferType) \
\ 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)); \
&self->value, sizeof(BufferType), (void *)&self->payload_buf, self->payload_used_buf, (EventBound)); \
}

#define DEFINE_ACTION_CTOR_WITHOUT_VALUE(ActionName, ActionType, MinDelay, EffectSize, SourceSize) \
#define DEFINE_ACTION_CTOR_WITHOUT_VALUE(ActionName, ActionType, MinDelay, EffectSize, SourceSize, EventBound) \
void ActionName##_ctor(ActionName *self, Reactor *parent) { \
Action_ctor(&self->super, ActionType, (MinDelay), parent, self->sources, (SourceSize), self->effects, \
(EffectSize), NULL, 0, NULL, NULL, 0); \
(EffectSize), NULL, 0, NULL, NULL, (EventBound)); \
}

#define DEFINE_ACTION_CTOR_CHOOSER(...) \
GET_ARG8(__VA_ARGS__, DEFINE_ACTION_CTOR_WITH_VALUE, NULL, DEFINE_ACTION_CTOR_WITHOUT_VALUE)
GET_ARG8(__VA_ARGS__, DEFINE_ACTION_CTOR_WITH_VALUE, DEFINE_ACTION_CTOR_WITHOUT_VALUE)

#define DEFINE_ACTION_CTOR(...) DEFINE_ACTION_CTOR_CHOOSER(__VA_ARGS__)(__VA_ARGS__)

Expand Down
18 changes: 16 additions & 2 deletions src/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ void Action_prepare(Trigger *self, Event *event) {
self->is_present = true;
memcpy(act->value_ptr, event->payload, act->payload_pool.size);

act->events_scheduled--;

sched->register_for_cleanup(sched, self);

for (size_t i = 0; i < act->effects.size; i++) {
Expand Down Expand Up @@ -49,6 +51,11 @@ lf_ret_t Action_schedule(Action *self, interval_t offset, const void *value) {
return LF_ERR;
}

if (self->events_scheduled >= self->event_bound) {
LF_ERR(TRIG, "Scheduled action to often bound: %i", self->event_bound);
return LF_ERR;
}

if (value != NULL) {
ret = self->super.payload_pool->allocate(self->super.payload_pool, &payload);
if (ret != LF_OK) {
Expand All @@ -71,6 +78,7 @@ lf_ret_t Action_schedule(Action *self, interval_t offset, const void *value) {
Event event = EVENT_INIT(tag, (Trigger *)self, payload);

ret = sched->schedule_at_locked(sched, &event);
self->events_scheduled++;

if (self->type == PHYSICAL_ACTION) {
env->platform->new_async_event(env->platform);
Expand All @@ -83,12 +91,18 @@ lf_ret_t Action_schedule(Action *self, interval_t offset, const void *value) {

void Action_ctor(Action *self, ActionType type, interval_t min_offset, Reactor *parent, Reaction **sources,
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);
void *payload_buf, bool *payload_used_buf, size_t event_bound) {
int capacity = 0;
if (payload_buf != NULL) {
capacity = event_bound;
}
EventPayloadPool_ctor(&self->payload_pool, payload_buf, payload_used_buf, value_size, capacity);
Trigger_ctor(&self->super, TRIG_ACTION, parent, &self->payload_pool, Action_prepare, Action_cleanup);
self->type = type;
self->value_ptr = value_ptr;
self->min_offset = min_offset;
self->event_bound = event_bound;
self->events_scheduled = 0;
self->schedule = Action_schedule;
self->sources.reactions = sources;
self->sources.num_registered = 0;
Expand Down
8 changes: 6 additions & 2 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ void EventPayloadPool_ctor(EventPayloadPool *self, char *buffer, bool *used, siz
self->used = used;
self->capacity = capacity;
self->size = size;
for (size_t i = 0; i < capacity; i++) {
self->used[i] = false;

if (self->used != NULL) {
for (size_t i = 0; i < capacity; i++) {
self->used[i] = false;
}
}

self->allocate = EventPayloadPool_allocate;
self->free = EventPayloadPool_free;
}
2 changes: 1 addition & 1 deletion test/unit/empty_action_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "unity.h"

DEFINE_ACTION_STRUCT(MyAction, LOGICAL_ACTION, 1, 1);
DEFINE_ACTION_CTOR(MyAction, LOGICAL_ACTION, MSEC(0), 1, 1);
DEFINE_ACTION_CTOR(MyAction, PHYSICAL_ACTION, MSEC(0), 1, 1, 6);
DEFINE_STARTUP_STRUCT(MyStartup, 1);
DEFINE_STARTUP_CTOR(MyStartup, 1)
DEFINE_REACTION_STRUCT(MyReactor, 0, 1);
Expand Down

0 comments on commit 0f012a2

Please sign in to comment.