Skip to content

Commit 3a413bd

Browse files
author
Hans Heirman
committed
Handle possible counter overflow cases in scheduler tick
1 parent 27049da commit 3a413bd

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/common/pf_scheduler.c

+26-5
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ void pf_scheduler_init (pnet_t * net, uint32_t tick_interval)
273273

274274
net->scheduler_timeout_first = PF_MAX_TIMEOUTS; /* Nothing in queue */
275275
net->scheduler_timeout_free = PF_MAX_TIMEOUTS; /* Nothing in queue. */
276+
net->scheduler_previous_time = os_get_current_time_us();
276277

277278
if (net->scheduler_timeout_mutex == NULL)
278279
{
@@ -443,20 +444,40 @@ void pf_scheduler_remove (pnet_t * net, pf_scheduler_handle_t * handle)
443444
void pf_scheduler_tick (pnet_t * net)
444445
{
445446
uint32_t ix;
447+
uint32_t when;
446448
pf_scheduler_timeout_ftn_t ftn;
447449
void * arg;
448450
uint32_t pf_current_time = os_get_current_time_us();
451+
uint32_t pf_previous_time = net->scheduler_previous_time;
452+
net->scheduler_previous_time = pf_current_time;
449453

450454
os_mutex_lock (net->scheduler_timeout_mutex);
451455

452456
/* Send event to all expired delay entries. */
453-
while ((net->scheduler_timeout_first < PF_MAX_TIMEOUTS) &&
454-
((int32_t) (
455-
pf_current_time -
456-
net->scheduler_timeouts[net->scheduler_timeout_first].when) >= 0))
457+
while (net->scheduler_timeout_first < PF_MAX_TIMEOUTS)
457458
{
458-
/* Unlink from busy list */
459459
ix = net->scheduler_timeout_first;
460+
when = net->scheduler_timeouts[ix].when;
461+
462+
/* Exit loop if not yet expired */
463+
if (pf_current_time < when) {
464+
if (pf_previous_time <= pf_current_time) {
465+
/* Most common case; |--------PCW--------| */
466+
break;
467+
} else if (pf_previous_time > when) {
468+
/* Overflow of both current time and when; |CW----------------P| */
469+
break;
470+
}
471+
/* Else overflow of current time; |C-----------------PW| */
472+
} else if (
473+
pf_current_time > when &&
474+
pf_previous_time > when &&
475+
pf_previous_time <= pf_current_time) {
476+
/* Overflow of when; |W-----------------PC| */
477+
break;
478+
}
479+
480+
/* Unlink from busy list */
460481
pf_scheduler_unlink (net, &net->scheduler_timeout_first, ix);
461482

462483
ftn = net->scheduler_timeouts[ix].cb;

src/pf_types.h

+1
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,7 @@ struct pnet
26142614
volatile uint32_t scheduler_timeout_free;
26152615
os_mutex_t * scheduler_timeout_mutex;
26162616
uint32_t scheduler_tick_interval; /* microseconds */
2617+
uint32_t scheduler_previous_time;
26172618
bool cmdev_initialized;
26182619
pf_device_t cmdev_device; /* APIs and diag items */
26192620
pf_cmina_dcp_ase_t cmina_nonvolatile_dcp_ase; /* Reflects what is/should be

0 commit comments

Comments
 (0)