Skip to content

Commit

Permalink
Handle possible counter overflow cases in scheduler tick
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans Heirman committed Jan 3, 2022
1 parent 27049da commit 489ffe3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
27 changes: 22 additions & 5 deletions src/common/pf_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ void pf_scheduler_init (pnet_t * net, uint32_t tick_interval)

net->scheduler_timeout_first = PF_MAX_TIMEOUTS; /* Nothing in queue */
net->scheduler_timeout_free = PF_MAX_TIMEOUTS; /* Nothing in queue. */
net->scheduler_previous_time = os_get_current_time_us();

if (net->scheduler_timeout_mutex == NULL)
{
Expand Down Expand Up @@ -443,20 +444,36 @@ void pf_scheduler_remove (pnet_t * net, pf_scheduler_handle_t * handle)
void pf_scheduler_tick (pnet_t * net)
{
uint32_t ix;
uint32_t when;
pf_scheduler_timeout_ftn_t ftn;
void * arg;
uint32_t pf_current_time = os_get_current_time_us();
uint32_t pf_previous_time = net->scheduler_previous_time;
net->scheduler_previous_time = pf_current_time;

os_mutex_lock (net->scheduler_timeout_mutex);

/* Send event to all expired delay entries. */
while ((net->scheduler_timeout_first < PF_MAX_TIMEOUTS) &&
((int32_t) (
pf_current_time -
net->scheduler_timeouts[net->scheduler_timeout_first].when) >= 0))
while (net->scheduler_timeout_first < PF_MAX_TIMEOUTS)
{
/* Unlink from busy list */
ix = net->scheduler_timeout_first;
when = net->scheduler_timeouts[ix].when;

/* Exit loop if not yet expired */
if (pf_current_time < when) {
if (pf_previous_time <= pf_current_time) {
/* Most common case; |--------PCW--------| */
break;
} /* Else counter overflow of current time; |C-----------------PW| */
} else if (
pf_current_time > when &&
pf_previous_time > when &&
pf_previous_time <= pf_current_time) {
/* Counter overflow of when; |W-----------------PC| */
break;
}

/* Unlink from busy list */
pf_scheduler_unlink (net, &net->scheduler_timeout_first, ix);

ftn = net->scheduler_timeouts[ix].cb;
Expand Down
1 change: 1 addition & 0 deletions src/pf_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2614,6 +2614,7 @@ struct pnet
volatile uint32_t scheduler_timeout_free;
os_mutex_t * scheduler_timeout_mutex;
uint32_t scheduler_tick_interval; /* microseconds */
uint32_t scheduler_previous_time;
bool cmdev_initialized;
pf_device_t cmdev_device; /* APIs and diag items */
pf_cmina_dcp_ase_t cmina_nonvolatile_dcp_ase; /* Reflects what is/should be
Expand Down

0 comments on commit 489ffe3

Please sign in to comment.