]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: fix thread scheduling weirdness
authorQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 29 Aug 2017 18:58:43 +0000 (14:58 -0400)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 31 Aug 2017 23:00:00 +0000 (19:00 -0400)
Restores 3.0 behavior in terms of thread scheduling & prioritization.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/thread.c
lib/thread.h

index 4a5c61d036f610d8753feb624c7ce2470a640d1e..b39f2d55c2cead518119c218d7120b0a77e2b20b 100644 (file)
@@ -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);
index 86bf4df7c0c5facb96b091b86dc0de5de682799f..c830446e10209f4ead167c06729fae3d757eef41 100644 (file)
@@ -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;