]> Zhao Yanbai Git Server - minix.git/commitdiff
libmthread: add possibility to randomize scheduler
authorThomas Veerman <thomas@minix3.org>
Tue, 11 Dec 2012 19:53:08 +0000 (19:53 +0000)
committerThomas Veerman <thomas@minix3.org>
Fri, 11 Jan 2013 09:18:35 +0000 (09:18 +0000)
lib/libmthread/global.h
lib/libmthread/queue.c

index 4488713d63bbe1d7c92c70335e51eef642f4b417..1554e893542aa72fc1c1f430e28880d80ddb86a0 100644 (file)
@@ -8,7 +8,7 @@
 #include <sys/types.h>
 #include <sys/signal.h>
 
-
+#define MTHREAD_RND_SCHED      0       /* Enable/disable random scheduling */
 #define NO_THREADS 4 
 #define MAX_THREAD_POOL 1024
 #define STACKSZ 4096
index 333d5458e65e7975be930b2c7abf40d62ed7b3fe..92379c4433daeea0f36989fb2f04c73e35e1ecc7 100644 (file)
@@ -95,14 +95,55 @@ mthread_queue_t *queue;             /* Queue we want a thread from */
 {
 /* Get the first thread in this queue, if there is one. */
   mthread_thread_t thread;
-  mthread_tcb_t *tcb;
+  mthread_tcb_t *tcb, *random_tcb, *prev;
+  int count = 0, offset_id = 0, picked_random = 0;
+
+  tcb = queue->mq_head;
+
+  if (MTHREAD_RND_SCHED) {
+       /* Count items on queue */
+       random_tcb = queue->mq_head;
+       if (random_tcb != NULL) {
+               do {
+                       count++;
+                       random_tcb = random_tcb->m_next;
+               } while (random_tcb != NULL);
+       }
+
+       if (count > 1) {
+               picked_random = 1;
+
+               /* Get random offset */
+               offset_id = random() % count;
 
-  /* Calculate thread id from queue head */
-  if (queue->mq_head == NULL) thread = NO_THREAD;
-  else if (queue->mq_head == &mainthread) thread = MAIN_THREAD;
-  else thread = (queue->mq_head->m_tid);
+               /* Find offset in queue */
+               random_tcb = queue->mq_head;
+               prev = random_tcb;
+               while (--offset_id > 0) {
+                       prev = random_tcb;
+                       random_tcb = random_tcb->m_next;
+               }
 
-  if (thread != NO_THREAD) { /* i.e., this queue is not empty */
+               /* Stitch head and tail together */
+               prev->m_next = random_tcb->m_next;
+
+               /* Fix head and tail */
+               if (queue->mq_head == random_tcb)
+                       queue->mq_head = random_tcb->m_next;
+               if (queue->mq_tail == random_tcb)
+                       queue->mq_tail = prev;
+
+               tcb = random_tcb;
+       }
+  }
+
+  /* Retrieve thread id from tcb */
+  if (tcb == NULL) thread = NO_THREAD;
+  else if (tcb == &mainthread) thread = MAIN_THREAD;
+  else thread = (tcb->m_tid);
+
+  /* If we didn't pick a random thread and queue is not empty... */
+  if (!picked_random && thread != NO_THREAD) {
        tcb = queue->mq_head;
        if (queue->mq_head == queue->mq_tail) {
                /* Queue holds only one thread */
@@ -111,9 +152,10 @@ mthread_queue_t *queue;            /* Queue we want a thread from */
                /* Second thread in line is the new first */
                queue->mq_head = queue->mq_head->m_next;
        }
+  }
 
+  if (tcb != NULL)
        tcb->m_next = NULL; /* This thread is no longer part of a queue */
-  }
 
   return(thread);
 }