Skip to content

Commit d311ad0

Browse files
author
Jonas Berg
committed
Break out helper function to determine which timeout is scheduled first
First step in investigating #455
1 parent 1db5613 commit d311ad0

File tree

3 files changed

+95
-7
lines changed

3 files changed

+95
-7
lines changed

src/common/pf_scheduler.c

+27-7
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,27 @@ static void pf_scheduler_link_before (
274274
}
275275
}
276276

277+
/**
278+
* Check if timeout \a a is scheduled before timeout \a b.
279+
*
280+
*
281+
* @param scheduler_data InOut: Scheduler instance
282+
* @param ix_a In: Index for timeout a
283+
* @param ix_b In: Index for timeout b
284+
* @return true if timeout a is scheduled before timeout b,
285+
* or if they are simultaneous.
286+
*/
287+
bool pf_scheduler_is_time_before (
288+
volatile pf_scheduler_data_t * scheduler_data,
289+
uint32_t ix_a,
290+
uint32_t ix_b)
291+
{
292+
293+
return ((int32_t) (
294+
scheduler_data->timeouts[ix_a].when -
295+
scheduler_data->timeouts[ix_b].when)) <= 0;
296+
}
297+
277298
/****************************** Public functions ***************************/
278299

279300
void pf_scheduler_reset_handle (pf_scheduler_handle_t * handle)
@@ -407,10 +428,11 @@ int pf_scheduler_add (
407428
ix_free,
408429
PF_MAX_TIMEOUTS);
409430
}
410-
else if (
411-
((int32_t) (
412-
scheduler_data->timeouts[ix_free].when -
413-
scheduler_data->timeouts[scheduler_data->busylist_head].when)) <= 0)
431+
else if (pf_scheduler_is_time_before (
432+
scheduler_data,
433+
ix_free,
434+
scheduler_data->busylist_head))
435+
414436
{
415437
/* Put first in non-empty queue */
416438
pf_scheduler_link_before (
@@ -425,9 +447,7 @@ int pf_scheduler_add (
425447
ix_prev = scheduler_data->busylist_head;
426448
ix_this = scheduler_data->timeouts[scheduler_data->busylist_head].next;
427449
while ((ix_this < PF_MAX_TIMEOUTS) &&
428-
(((int32_t) (
429-
scheduler_data->timeouts[ix_free].when -
430-
scheduler_data->timeouts[ix_this].when)) > 0))
450+
pf_scheduler_is_time_before (scheduler_data, ix_this, ix_free))
431451
{
432452
ix_prev = ix_this;
433453
ix_this = scheduler_data->timeouts[ix_this].next;

src/common/pf_scheduler.h

+5
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ uint32_t pf_scheduler_sanitize_delay (
196196
uint32_t stack_cycle_time,
197197
bool schedule_half_tick_in_advance);
198198

199+
bool pf_scheduler_is_time_before (
200+
volatile pf_scheduler_data_t * scheduler_data,
201+
uint32_t ix_a,
202+
uint32_t ix_b);
203+
199204
#ifdef __cplusplus
200205
}
201206
#endif

test/test_scheduler.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,69 @@ TEST_F (SchedulerUnitTest, SchedulerSanitizeDelayTest)
135135
ASSERT_NEAR (result, 1000, margin);
136136
}
137137

138+
TEST_F (SchedulerUnitTest, SchedulerIsTimeBeforeTest)
139+
{
140+
/* Validate that the test case is compiled with enough timeouts */
141+
ASSERT_GE (PF_MAX_TIMEOUTS, 6);
142+
143+
volatile pf_scheduler_data_t scheduler_data;
144+
scheduler_data.mutex = NULL;
145+
146+
pf_scheduler_init (&scheduler_data, TEST_TICK_INTERVAL_US);
147+
148+
scheduler_data.timeouts[0].in_use = true;
149+
scheduler_data.timeouts[0].name = "No_0";
150+
scheduler_data.timeouts[0].when = 100;
151+
scheduler_data.timeouts[0].prev = PF_MAX_TIMEOUTS;
152+
scheduler_data.timeouts[0].next = 1;
153+
154+
scheduler_data.timeouts[1].in_use = true;
155+
scheduler_data.timeouts[1].name = "No_1";
156+
scheduler_data.timeouts[1].when = 200;
157+
scheduler_data.timeouts[1].prev = 0;
158+
scheduler_data.timeouts[1].next = 2;
159+
160+
scheduler_data.timeouts[2].in_use = true;
161+
scheduler_data.timeouts[2].name = "No_2";
162+
scheduler_data.timeouts[2].when = 300;
163+
scheduler_data.timeouts[2].prev = 1;
164+
scheduler_data.timeouts[2].next = 3;
165+
166+
scheduler_data.timeouts[3].in_use = true;
167+
scheduler_data.timeouts[3].name = "No_3";
168+
scheduler_data.timeouts[3].when = 300;
169+
scheduler_data.timeouts[3].prev = 2;
170+
scheduler_data.timeouts[3].next = 4;
171+
172+
scheduler_data.timeouts[4].in_use = true;
173+
scheduler_data.timeouts[4].name = "No_4";
174+
scheduler_data.timeouts[4].when = 400;
175+
scheduler_data.timeouts[4].prev = 3;
176+
scheduler_data.timeouts[4].next = 5;
177+
178+
scheduler_data.timeouts[5].in_use = true;
179+
scheduler_data.timeouts[5].name = "No_5";
180+
scheduler_data.timeouts[5].when = 500;
181+
scheduler_data.timeouts[5].prev = 4;
182+
scheduler_data.timeouts[5].next = PF_MAX_TIMEOUTS;
183+
184+
scheduler_data.busylist_head = 0;
185+
scheduler_data.freelist_head = 6;
186+
187+
pf_scheduler_show (&scheduler_data, 50);
188+
189+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 0, 1));
190+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 1, 2));
191+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 2, 3));
192+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 3, 4));
193+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 4, 5));
194+
195+
ASSERT_TRUE (pf_scheduler_is_time_before (&scheduler_data, 0, 0));
196+
197+
ASSERT_FALSE (pf_scheduler_is_time_before (&scheduler_data, 1, 0));
198+
ASSERT_FALSE (pf_scheduler_is_time_before (&scheduler_data, 2, 1));
199+
}
200+
138201
TEST_F (SchedulerTest, SchedulerAddRemoveInStack)
139202
{
140203
int ret;

0 commit comments

Comments
 (0)