diff options
author | Mark Stapp <mjs@voltanet.io> | 2021-02-18 15:37:09 +0100 |
---|---|---|
committer | Mark Stapp <mjs@voltanet.io> | 2021-02-18 15:42:03 +0100 |
commit | 96fe578a643bf78866d34281d4baf59ac9dd840a (patch) | |
tree | 50d438a44ae7f9fe2bedd0062971aa16ab4bcc13 /lib/thread.c | |
parent | lib: remove unneeded arg from timer api (diff) | |
download | frr-96fe578a643bf78866d34281d4baf59ac9dd840a.tar.xz frr-96fe578a643bf78866d34281d4baf59ac9dd840a.zip |
lib: don't awaken from poll for every timer
Only ask the event-loop poll() to awaken if a newly-added timer
actually might have changed the required timeout. Also compute
timer deadline outside of mutex locks.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to '')
-rw-r--r-- | lib/thread.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/lib/thread.c b/lib/thread.c index bd1ed8cd3..47f0fdfb7 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -913,6 +913,7 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref, struct thread **t_ptr) { struct thread *thread; + struct timeval t; assert(m != NULL); @@ -922,6 +923,10 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref, xref->funcname, xref->xref.file, xref->xref.line, t_ptr, 0, 0, arg, (long)time_relative->tv_sec); + /* Compute expiration/deadline time. */ + monotime(&t); + timeradd(&t, time_relative, &t); + frr_with_mutex(&m->mtx) { if (t_ptr && *t_ptr) /* thread is already scheduled; don't reschedule */ @@ -930,9 +935,7 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref, thread = thread_get(m, THREAD_TIMER, func, arg, xref); frr_with_mutex(&thread->mtx) { - monotime(&thread->u.sands); - timeradd(&thread->u.sands, time_relative, - &thread->u.sands); + thread->u.sands = t; thread_timer_list_add(&m->timer, thread); if (t_ptr) { *t_ptr = thread; @@ -940,7 +943,12 @@ _thread_add_timer_timeval(const struct xref_threadsched *xref, } } - AWAKEN(m); + /* The timer list is sorted - if this new timer + * might change the time we'll wait for, give the pthread + * a chance to re-compute. + */ + if (thread_timer_list_first(&m->timer) == thread) + AWAKEN(m); } return thread; |