From: Quentin Young Date: Tue, 29 Aug 2017 18:58:43 +0000 (-0400) Subject: lib: fix thread scheduling weirdness X-Git-Tag: frr-4.0-dev~337^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F1087%2Fhead;p=mirror%2Ffrr.git lib: fix thread scheduling weirdness Restores 3.0 behavior in terms of thread scheduling & prioritization. Signed-off-by: Quentin Young --- diff --git a/lib/thread.c b/lib/thread.c index 4a5c61d036..b39f2d55c2 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -47,9 +47,6 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") write(m->io_pipe[1], &wakebyte, 1); \ } while (0); -/* max # of thread_fetch() calls before we force a poll() */ -#define MAX_TICK_IO 1000 - /* control variable for initializer */ pthread_once_t init_once = PTHREAD_ONCE_INIT; pthread_key_t thread_current; @@ -552,7 +549,7 @@ void thread_master_free(struct thread_master *m) { listnode_delete(masters, m); if (masters->count == 0) { - list_free (masters); + list_free(masters); masters = NULL; } } @@ -1319,6 +1316,20 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) /* Process any pending cancellation requests */ do_thread_cancel(m); + /* + * Attempt to flush ready queue before going into poll(). + * This is performance-critical. Think twice before modifying. + */ + if ((thread = thread_trim_head(&m->ready))) { + fetch = thread_run(m, thread, fetch); + if (fetch->ref) + *fetch->ref = NULL; + pthread_mutex_unlock(&m->mtx); + break; + } + + /* otherwise, tick through scheduling sequence */ + /* * Post events to ready queue. This must come before the * following block since events should occur immediately @@ -1362,44 +1373,26 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) memcpy(m->handler.copy, m->handler.pfds, m->handler.copycount * sizeof(struct pollfd)); - /* - * Attempt to flush ready queue before going into poll(). - * This is performance-critical. Think twice before modifying. - */ - if (m->ready.count == 0 || m->tick_since_io >= MAX_TICK_IO) { - pthread_mutex_unlock(&m->mtx); - { - m->tick_since_io = 0; - num = fd_poll(m, m->handler.copy, - m->handler.pfdsize, - m->handler.copycount, tw); - } - pthread_mutex_lock(&m->mtx); - - /* Handle any errors received in poll() */ - if (num < 0) { - if (errno == EINTR) { - pthread_mutex_unlock(&m->mtx); - /* loop around to signal handler */ - continue; - } + pthread_mutex_unlock(&m->mtx); + { + num = fd_poll(m, m->handler.copy, m->handler.pfdsize, + m->handler.copycount, tw); + } + pthread_mutex_lock(&m->mtx); - /* else die */ - zlog_warn("poll() error: %s", - safe_strerror(errno)); + /* Handle any errors received in poll() */ + if (num < 0) { + if (errno == EINTR) { pthread_mutex_unlock(&m->mtx); - fetch = NULL; - break; + /* loop around to signal handler */ + continue; } - /* - * Since we could have received more cancellation - * requests during poll(), process those - */ - do_thread_cancel(m); - - } else { - m->tick_since_io++; + /* else die */ + zlog_warn("poll() error: %s", safe_strerror(errno)); + pthread_mutex_unlock(&m->mtx); + fetch = NULL; + break; } /* Post timers to ready queue. */ @@ -1410,13 +1403,6 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) if (num > 0) thread_process_io(m, num); - /* have a ready task ==> return it to caller */ - if ((thread = thread_trim_head(&m->ready))) { - fetch = thread_run(m, thread, fetch); - if (fetch->ref) - *fetch->ref = NULL; - } - pthread_mutex_unlock(&m->mtx); } while (!thread && m->spin); diff --git a/lib/thread.h b/lib/thread.h index 86bf4df7c0..c830446e10 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -70,7 +70,6 @@ struct cancel_req { struct thread_master { char *name; - int tick_since_io; struct thread **read; struct thread **write; struct pqueue *timer;