thread->arg = arg;
thread->yield = THREAD_YIELD_TIME_SLOT; /* default */
thread->ref = NULL;
+ thread->ignore_timer_late = false;
/*
* So if the passed in funcname is not what we have
* really getting behind on handling of events.
* Let's log it and do the right thing with it.
*/
- if (timercmp(timenow, &prev, >)) {
- if (!displayed)
- flog_warn(
- EC_LIB_STARVE_THREAD,
- "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago",
- thread);
+ if (!displayed && !thread->ignore_timer_late &&
+ timercmp(timenow, &prev, >)) {
+ flog_warn(
+ EC_LIB_STARVE_THREAD,
+ "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago",
+ thread);
displayed = true;
}
unsigned long yield; /* yield time in microseconds */
const struct xref_threadsched *xref; /* origin location */
pthread_mutex_t mtx; /* mutex for thread.c functions */
+ bool ignore_timer_late;
};
#ifdef _FRR_ATTRIBUTE_PRINTFRR
/* Debug signal mask */
void debug_signals(const sigset_t *sigs);
+static inline void thread_ignore_late_timer(struct thread *thread)
+{
+ thread->ignore_timer_late = true;
+}
+
#ifdef __cplusplus
}
#endif
/* Schedule timer if there's a delay, otherwise just schedule
* as an 'event'
*/
- if (delay > 0)
+ if (delay > 0) {
thread_add_timer_msec(wq->master, work_queue_run, wq,
delay, &wq->thread);
- else
+ thread_ignore_late_timer(wq->thread);
+ } else
thread_add_event(wq->master, work_queue_run, wq, 0,
&wq->thread);
changed = true;
}
- if (changed || new_speed == UINT32_MAX)
+ if (changed || new_speed == UINT32_MAX) {
thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 5,
&zif->speed_update);
+ thread_ignore_late_timer(zif->speed_update);
+ }
+
return 1;
}
*/
thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
&zebra_if->speed_update);
+ thread_ignore_late_timer(zebra_if->speed_update);
+
return 0;
}
thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
&zif->speed_update);
+ thread_ignore_late_timer(zif->speed_update);
}
/* Interface goes down. We have to manage different behavior of based