Skip to content

Commit b0a616e

Browse files
authored
Increment microstep when scheduling action with 0 delay (#67)
1 parent e3f0db1 commit b0a616e

File tree

3 files changed

+108
-145
lines changed

3 files changed

+108
-145
lines changed

src/action.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ void Action_ctor(Action *self, TriggerType type, interval_t min_offset, interval
4646
lf_ret_t LogicalAction_schedule(Action *self, interval_t offset, const void *value) {
4747
Environment *env = self->super.parent->env;
4848
Scheduler *sched = &env->scheduler;
49-
tag_t tag = {.time = env->current_tag.time + self->min_offset + offset, .microstep = 0};
49+
tag_t proposed_tag = lf_delay_tag(env->current_tag, offset);
5050
tag_t earliest_allowed = lf_delay_tag(self->previous_event, self->min_spacing);
51-
if (lf_tag_compare(tag, earliest_allowed) < 0) {
51+
if (lf_tag_compare(proposed_tag, earliest_allowed) < 0) {
5252
return LF_INVALID_TAG;
5353
}
5454

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

62-
int ret = sched->schedule_at(sched, (Trigger *)self, tag);
62+
int ret = sched->schedule_at(sched, (Trigger *)self, proposed_tag);
6363
if (ret == 0) {
64-
self->previous_event = tag;
64+
self->previous_event = proposed_tag;
6565
}
6666
return ret;
6767
}

src/tag.c

Lines changed: 1 addition & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -100,144 +100,4 @@ tag_t lf_delay_strict(tag_t tag, interval_t interval) {
100100
result.microstep = UINT_MAX;
101101
}
102102
return result;
103-
}
104-
105-
// instant_t lf_time_logical(void *env) { return ((Environment *)env)->current_tag.time; }
106-
107-
// interval_t lf_time_logical_elapsed(void *env) { return lf_time_logical(env) - start_time; }
108-
109-
// instant_t lf_time_physical(void) {
110-
// instant_t now = MSEC(0);
111-
// // Get the current clock value
112-
// return now;
113-
// }
114-
115-
// instant_t lf_time_physical_elapsed(void) { return lf_time_physical() - start_time; }
116-
117-
// instant_t lf_time_start(void) { return start_time; }
118-
119-
// size_t lf_readable_time(char *buffer, instant_t time) {
120-
// if (time <= (instant_t)0) {
121-
// snprintf(buffer, 2, "0");
122-
// return 1;
123-
// }
124-
// char *original_buffer = buffer;
125-
// bool lead = false; // Set to true when first clause has been printed.
126-
// if (time > WEEKS(1)) {
127-
// lead = true;
128-
// size_t printed = lf_comma_separated_time(buffer, time / WEEKS(1));
129-
// time = time % WEEKS(1);
130-
// buffer += printed;
131-
// snprintf(buffer, 7, " weeks");
132-
// buffer += 6;
133-
// }
134-
// if (time > DAYS(1)) {
135-
// if (lead == true) {
136-
// snprintf(buffer, 3, ", ");
137-
// buffer += 2;
138-
// }
139-
// lead = true;
140-
// size_t printed = lf_comma_separated_time(buffer, time / DAYS(1));
141-
// time = time % DAYS(1);
142-
// buffer += printed;
143-
// snprintf(buffer, 3, " d");
144-
// buffer += 2;
145-
// }
146-
// if (time > HOURS(1)) {
147-
// if (lead == true) {
148-
// snprintf(buffer, 3, ", ");
149-
// buffer += 2;
150-
// }
151-
// lead = true;
152-
// size_t printed = lf_comma_separated_time(buffer, time / HOURS(1));
153-
// time = time % HOURS(1);
154-
// buffer += printed;
155-
// snprintf(buffer, 3, " h");
156-
// buffer += 2;
157-
// }
158-
// if (time > MINUTES(1)) {
159-
// if (lead == true) {
160-
// snprintf(buffer, 3, ", ");
161-
// buffer += 2;
162-
// }
163-
// lead = true;
164-
// size_t printed = lf_comma_separated_time(buffer, time / MINUTES(1));
165-
// time = time % MINUTES(1);
166-
// buffer += printed;
167-
// snprintf(buffer, 5, " min");
168-
// buffer += 4;
169-
// }
170-
// if (time > SECONDS(1)) {
171-
// if (lead == true) {
172-
// snprintf(buffer, 3, ", ");
173-
// buffer += 2;
174-
// }
175-
// lead = true;
176-
// size_t printed = lf_comma_separated_time(buffer, time / SECONDS(1));
177-
// time = time % SECONDS(1);
178-
// buffer += printed;
179-
// snprintf(buffer, 3, " s");
180-
// buffer += 2;
181-
// }
182-
// if (time > (instant_t)0) {
183-
// if (lead == true) {
184-
// snprintf(buffer, 3, ", ");
185-
// buffer += 2;
186-
// }
187-
// const char *units = "ns";
188-
// if (time % MSEC(1) == (instant_t)0) {
189-
// units = "ms";
190-
// time = time / MSEC(1);
191-
// } else if (time % USEC(1) == (instant_t)0) {
192-
// units = "us";
193-
// time = time / USEC(1);
194-
// }
195-
// size_t printed = lf_comma_separated_time(buffer, time);
196-
// buffer += printed;
197-
// snprintf(buffer, 4, " %s", units);
198-
// buffer += strlen(units) + 1;
199-
// }
200-
// return (buffer - original_buffer);
201-
// }
202-
203-
// size_t lf_comma_separated_time(char *buffer, instant_t time) {
204-
// size_t result = 0; // The number of characters printed.
205-
// // If the number is zero, print it and return.
206-
// if (time == (instant_t)0) {
207-
// snprintf(buffer, 2, "0");
208-
// return 1;
209-
// }
210-
// // If the number is negative, print a minus sign.
211-
// if (time < (instant_t)0) {
212-
// snprintf(buffer, 2, "-");
213-
// buffer++;
214-
// result++;
215-
// }
216-
// int count = 0;
217-
// // Assume the time value is no larger than 64 bits.
218-
// instant_t clauses[7];
219-
// while (time > (instant_t)0) {
220-
// clauses[count++] = time;
221-
// time = time / 1000;
222-
// }
223-
// // Highest order clause should not be filled with zeros.
224-
// instant_t to_print = clauses[--count] % 1000;
225-
// snprintf(buffer, 5, "%lld", (long long)to_print);
226-
// if (to_print >= 100LL) {
227-
// buffer += 3;
228-
// result += 3;
229-
// } else if (to_print >= 10LL) {
230-
// buffer += 2;
231-
// result += 2;
232-
// } else {
233-
// buffer += 1;
234-
// result += 1;
235-
// }
236-
// while (count-- > 0) {
237-
// to_print = clauses[count] % 1000LL;
238-
// snprintf(buffer, 8, ",%03lld", (long long)to_print);
239-
// buffer += 4;
240-
// result += 4;
241-
// }
242-
// return result;
243-
// }
103+
}

test/unit/action_microstep_test.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "reactor-uc/reactor-uc.h"
2+
#include "unity.h"
3+
4+
typedef struct {
5+
LogicalAction super;
6+
int buffer[1];
7+
8+
Reaction *sources[1];
9+
Reaction *effects[1];
10+
} MyAction;
11+
12+
typedef struct MyStartup MyStartup;
13+
14+
struct MyStartup {
15+
Startup super;
16+
Reaction *effects_[1];
17+
};
18+
19+
typedef struct {
20+
Reaction super;
21+
Trigger *effects[1];
22+
} MyReaction;
23+
24+
struct MyReactor {
25+
Reactor super;
26+
MyReaction my_reaction;
27+
MyAction my_action;
28+
MyStartup startup;
29+
Reaction *_reactions[1];
30+
Trigger *_triggers[2];
31+
int cnt;
32+
};
33+
34+
void MyAction_ctor(MyAction *self, struct MyReactor *parent) {
35+
LogicalAction_ctor(&self->super, MSEC(0), MSEC(0), &parent->super, self->sources, 1, self->effects, 1, &self->buffer,
36+
sizeof(self->buffer[0]), 2);
37+
}
38+
39+
void MyStartup_ctor(struct MyStartup *self, Reactor *parent, Reaction *effects) {
40+
self->effects_[0] = effects;
41+
Startup_ctor(&self->super, parent, self->effects_, 1);
42+
}
43+
44+
void action_handler(Reaction *_self) {
45+
struct MyReactor *self = (struct MyReactor *)_self->parent;
46+
Environment *env = self->super.env;
47+
MyAction *my_action = &self->my_action;
48+
if (self->cnt == 0) {
49+
TEST_ASSERT_EQUAL(lf_is_present(my_action), false);
50+
} else {
51+
TEST_ASSERT_EQUAL(lf_is_present(my_action), true);
52+
}
53+
54+
printf("Hello World\n");
55+
printf("Action = %d\n", lf_get(my_action));
56+
if (self->cnt > 0) {
57+
TEST_ASSERT_EQUAL(self->cnt, lf_get(my_action));
58+
TEST_ASSERT_EQUAL(self->cnt, env->current_tag.microstep);
59+
TEST_ASSERT_EQUAL(true, lf_is_present(my_action));
60+
} else {
61+
TEST_ASSERT_EQUAL(false, lf_is_present(my_action));
62+
}
63+
64+
TEST_ASSERT_EQUAL(0, env->get_elapsed_logical_time(env));
65+
66+
if (self->cnt < 100) {
67+
lf_schedule(my_action, ++self->cnt, 0);
68+
}
69+
}
70+
71+
void MyReaction_ctor(MyReaction *self, Reactor *parent) {
72+
Reaction_ctor(&self->super, parent, action_handler, self->effects, 1, 0);
73+
}
74+
75+
void MyReactor_ctor(struct MyReactor *self, Environment *env) {
76+
self->_reactions[0] = (Reaction *)&self->my_reaction;
77+
self->_triggers[0] = (Trigger *)&self->startup;
78+
self->_triggers[1] = (Trigger *)&self->my_action;
79+
Reactor_ctor(&self->super, "MyReactor", env, NULL, NULL, 0, self->_reactions, 1, self->_triggers, 2);
80+
MyAction_ctor(&self->my_action, self);
81+
MyReaction_ctor(&self->my_reaction, &self->super);
82+
MyStartup_ctor(&self->startup, &self->super, &self->my_reaction.super);
83+
ACTION_REGISTER_EFFECT(self->my_action, self->my_reaction);
84+
REACTION_REGISTER_EFFECT(self->my_reaction, self->my_action);
85+
ACTION_REGISTER_SOURCE(self->my_action, self->my_reaction);
86+
self->cnt = 0;
87+
}
88+
89+
void test_simple() {
90+
struct MyReactor my_reactor;
91+
Environment env;
92+
Environment_ctor(&env, (Reactor *)&my_reactor);
93+
MyReactor_ctor(&my_reactor, &env);
94+
env.set_timeout(&env, SEC(1));
95+
env.assemble(&env);
96+
env.start(&env);
97+
}
98+
99+
int main() {
100+
UNITY_BEGIN();
101+
RUN_TEST(test_simple);
102+
return UNITY_END();
103+
}

0 commit comments

Comments
 (0)