summaryrefslogtreecommitdiffstats
path: root/lib/thread.c
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-02-18 15:37:09 +0100
committerMark Stapp <mjs@voltanet.io>2021-02-18 15:42:03 +0100
commit96fe578a643bf78866d34281d4baf59ac9dd840a (patch)
tree50d438a44ae7f9fe2bedd0062971aa16ab4bcc13 /lib/thread.c
parentlib: remove unneeded arg from timer api (diff)
downloadfrr-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.c16
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;