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

Increment microstep when scheduling action with 0 delay #67

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions src/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ void Action_ctor(Action *self, TriggerType type, interval_t min_offset, interval
lf_ret_t LogicalAction_schedule(Action *self, interval_t offset, const void *value) {
Environment *env = self->super.parent->env;
Scheduler *sched = &env->scheduler;
tag_t tag = {.time = env->current_tag.time + self->min_offset + offset, .microstep = 0};
tag_t proposed_tag = lf_delay_tag(env->current_tag, offset);
tag_t earliest_allowed = lf_delay_tag(self->previous_event, self->min_spacing);
if (lf_tag_compare(tag, earliest_allowed) < 0) {
if (lf_tag_compare(proposed_tag, earliest_allowed) < 0) {
return LF_INVALID_TAG;
}

Expand All @@ -59,9 +59,9 @@ lf_ret_t LogicalAction_schedule(Action *self, interval_t offset, const void *val
return LF_INVALID_VALUE;
}

int ret = sched->schedule_at(sched, (Trigger *)self, tag);
int ret = sched->schedule_at(sched, (Trigger *)self, proposed_tag);
if (ret == 0) {
self->previous_event = tag;
self->previous_event = proposed_tag;
}
return ret;
}
Expand Down
142 changes: 1 addition & 141 deletions src/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,144 +100,4 @@ tag_t lf_delay_strict(tag_t tag, interval_t interval) {
result.microstep = UINT_MAX;
}
return result;
}

// instant_t lf_time_logical(void *env) { return ((Environment *)env)->current_tag.time; }

// interval_t lf_time_logical_elapsed(void *env) { return lf_time_logical(env) - start_time; }

// instant_t lf_time_physical(void) {
// instant_t now = MSEC(0);
// // Get the current clock value
// return now;
// }

// instant_t lf_time_physical_elapsed(void) { return lf_time_physical() - start_time; }

// instant_t lf_time_start(void) { return start_time; }

// size_t lf_readable_time(char *buffer, instant_t time) {
// if (time <= (instant_t)0) {
// snprintf(buffer, 2, "0");
// return 1;
// }
// char *original_buffer = buffer;
// bool lead = false; // Set to true when first clause has been printed.
// if (time > WEEKS(1)) {
// lead = true;
// size_t printed = lf_comma_separated_time(buffer, time / WEEKS(1));
// time = time % WEEKS(1);
// buffer += printed;
// snprintf(buffer, 7, " weeks");
// buffer += 6;
// }
// if (time > DAYS(1)) {
// if (lead == true) {
// snprintf(buffer, 3, ", ");
// buffer += 2;
// }
// lead = true;
// size_t printed = lf_comma_separated_time(buffer, time / DAYS(1));
// time = time % DAYS(1);
// buffer += printed;
// snprintf(buffer, 3, " d");
// buffer += 2;
// }
// if (time > HOURS(1)) {
// if (lead == true) {
// snprintf(buffer, 3, ", ");
// buffer += 2;
// }
// lead = true;
// size_t printed = lf_comma_separated_time(buffer, time / HOURS(1));
// time = time % HOURS(1);
// buffer += printed;
// snprintf(buffer, 3, " h");
// buffer += 2;
// }
// if (time > MINUTES(1)) {
// if (lead == true) {
// snprintf(buffer, 3, ", ");
// buffer += 2;
// }
// lead = true;
// size_t printed = lf_comma_separated_time(buffer, time / MINUTES(1));
// time = time % MINUTES(1);
// buffer += printed;
// snprintf(buffer, 5, " min");
// buffer += 4;
// }
// if (time > SECONDS(1)) {
// if (lead == true) {
// snprintf(buffer, 3, ", ");
// buffer += 2;
// }
// lead = true;
// size_t printed = lf_comma_separated_time(buffer, time / SECONDS(1));
// time = time % SECONDS(1);
// buffer += printed;
// snprintf(buffer, 3, " s");
// buffer += 2;
// }
// if (time > (instant_t)0) {
// if (lead == true) {
// snprintf(buffer, 3, ", ");
// buffer += 2;
// }
// const char *units = "ns";
// if (time % MSEC(1) == (instant_t)0) {
// units = "ms";
// time = time / MSEC(1);
// } else if (time % USEC(1) == (instant_t)0) {
// units = "us";
// time = time / USEC(1);
// }
// size_t printed = lf_comma_separated_time(buffer, time);
// buffer += printed;
// snprintf(buffer, 4, " %s", units);
// buffer += strlen(units) + 1;
// }
// return (buffer - original_buffer);
// }

// size_t lf_comma_separated_time(char *buffer, instant_t time) {
// size_t result = 0; // The number of characters printed.
// // If the number is zero, print it and return.
// if (time == (instant_t)0) {
// snprintf(buffer, 2, "0");
// return 1;
// }
// // If the number is negative, print a minus sign.
// if (time < (instant_t)0) {
// snprintf(buffer, 2, "-");
// buffer++;
// result++;
// }
// int count = 0;
// // Assume the time value is no larger than 64 bits.
// instant_t clauses[7];
// while (time > (instant_t)0) {
// clauses[count++] = time;
// time = time / 1000;
// }
// // Highest order clause should not be filled with zeros.
// instant_t to_print = clauses[--count] % 1000;
// snprintf(buffer, 5, "%lld", (long long)to_print);
// if (to_print >= 100LL) {
// buffer += 3;
// result += 3;
// } else if (to_print >= 10LL) {
// buffer += 2;
// result += 2;
// } else {
// buffer += 1;
// result += 1;
// }
// while (count-- > 0) {
// to_print = clauses[count] % 1000LL;
// snprintf(buffer, 8, ",%03lld", (long long)to_print);
// buffer += 4;
// result += 4;
// }
// return result;
// }
}
103 changes: 103 additions & 0 deletions test/unit/action_microstep_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "reactor-uc/reactor-uc.h"
#include "unity.h"

typedef struct {
LogicalAction super;
int buffer[1];

Reaction *sources[1];
Reaction *effects[1];
} MyAction;

typedef struct MyStartup MyStartup;

struct MyStartup {
Startup super;
Reaction *effects_[1];
};

typedef struct {
Reaction super;
Trigger *effects[1];
} MyReaction;

struct MyReactor {
Reactor super;
MyReaction my_reaction;
MyAction my_action;
MyStartup startup;
Reaction *_reactions[1];
Trigger *_triggers[2];
int cnt;
};

void MyAction_ctor(MyAction *self, struct MyReactor *parent) {
LogicalAction_ctor(&self->super, MSEC(0), MSEC(0), &parent->super, self->sources, 1, self->effects, 1, &self->buffer,
sizeof(self->buffer[0]), 2);
}

void MyStartup_ctor(struct MyStartup *self, Reactor *parent, Reaction *effects) {
self->effects_[0] = effects;
Startup_ctor(&self->super, parent, self->effects_, 1);
}

void action_handler(Reaction *_self) {
struct MyReactor *self = (struct MyReactor *)_self->parent;
Environment *env = self->super.env;
MyAction *my_action = &self->my_action;
if (self->cnt == 0) {
TEST_ASSERT_EQUAL(lf_is_present(my_action), false);
} else {
TEST_ASSERT_EQUAL(lf_is_present(my_action), true);
}

printf("Hello World\n");
printf("Action = %d\n", lf_get(my_action));
if (self->cnt > 0) {
TEST_ASSERT_EQUAL(self->cnt, lf_get(my_action));
TEST_ASSERT_EQUAL(self->cnt, env->current_tag.microstep);
TEST_ASSERT_EQUAL(true, lf_is_present(my_action));
} else {
TEST_ASSERT_EQUAL(false, lf_is_present(my_action));
}

TEST_ASSERT_EQUAL(0, env->get_elapsed_logical_time(env));

if (self->cnt < 100) {
lf_schedule(my_action, ++self->cnt, 0);
}
}

void MyReaction_ctor(MyReaction *self, Reactor *parent) {
Reaction_ctor(&self->super, parent, action_handler, self->effects, 1, 0);
}

void MyReactor_ctor(struct MyReactor *self, Environment *env) {
self->_reactions[0] = (Reaction *)&self->my_reaction;
self->_triggers[0] = (Trigger *)&self->startup;
self->_triggers[1] = (Trigger *)&self->my_action;
Reactor_ctor(&self->super, "MyReactor", env, NULL, NULL, 0, self->_reactions, 1, self->_triggers, 2);
MyAction_ctor(&self->my_action, self);
MyReaction_ctor(&self->my_reaction, &self->super);
MyStartup_ctor(&self->startup, &self->super, &self->my_reaction.super);
ACTION_REGISTER_EFFECT(self->my_action, self->my_reaction);
REACTION_REGISTER_EFFECT(self->my_reaction, self->my_action);
ACTION_REGISTER_SOURCE(self->my_action, self->my_reaction);
self->cnt = 0;
}

void test_simple() {
struct MyReactor my_reactor;
Environment env;
Environment_ctor(&env, (Reactor *)&my_reactor);
MyReactor_ctor(&my_reactor, &env);
env.set_timeout(&env, SEC(1));
env.assemble(&env);
env.start(&env);
}

int main() {
UNITY_BEGIN();
RUN_TEST(test_simple);
return UNITY_END();
}
Loading