From: Thomas Veerman Date: Tue, 11 Dec 2012 19:53:08 +0000 (+0000) Subject: libmthread: add possibility to randomize scheduler X-Git-Tag: v3.2.1~126 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/expt.png?a=commitdiff_plain;h=93103f497f36ca5ce66d8334a1dac2a364ad0b14;p=minix.git libmthread: add possibility to randomize scheduler --- diff --git a/lib/libmthread/global.h b/lib/libmthread/global.h index 4488713d6..1554e8935 100644 --- a/lib/libmthread/global.h +++ b/lib/libmthread/global.h @@ -8,7 +8,7 @@ #include #include - +#define MTHREAD_RND_SCHED 0 /* Enable/disable random scheduling */ #define NO_THREADS 4 #define MAX_THREAD_POOL 1024 #define STACKSZ 4096 diff --git a/lib/libmthread/queue.c b/lib/libmthread/queue.c index 333d5458e..92379c443 100644 --- a/lib/libmthread/queue.c +++ b/lib/libmthread/queue.c @@ -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); }