1 #include <minix/mthread.h>
5 /*===========================================================================*
7 *===========================================================================*/
8 void mthread_queue_add(queue
, thread
)
9 mthread_queue_t
*queue
; /* Queue we want thread to append to */
10 mthread_thread_t thread
;
12 /* Append a thread to the tail of the queue. As a process can be present on
13 * only one queue at the same time, we can use the threads array's 'next'
14 * pointer to point to the next thread on the queue.
18 if (!isokthreadid(thread
))
19 mthread_panic("Can't append invalid thread ID to a queue");
21 last
= mthread_find_tcb(thread
);
23 if (mthread_queue_isempty(queue
)) {
24 queue
->mq_head
= queue
->mq_tail
= last
;
26 queue
->mq_tail
->m_next
= last
;
27 queue
->mq_tail
= last
; /* 'last' is the new last in line */
32 /*===========================================================================*
33 * mthread_queue_init *
34 *===========================================================================*/
35 void mthread_queue_init(queue
)
36 mthread_queue_t
*queue
; /* Queue that has to be initialized */
38 /* Initialize queue to a known state */
40 queue
->mq_head
= queue
->mq_tail
= NULL
;
44 /*===========================================================================*
45 * mthread_queue_isempty *
46 *===========================================================================*/
47 int mthread_queue_isempty(queue
)
48 mthread_queue_t
*queue
;
50 return(queue
->mq_head
== NULL
);
54 /*===========================================================================*
55 * mthread_dump_queue *
56 *===========================================================================*/
58 void mthread_dump_queue(queue
)
59 mthread_queue_t
*queue
;
61 int threshold
, count
= 0;
64 threshold
= no_threads
;
65 printf("Dumping queue: ");
67 if(queue
->mq_head
!= NULL
) {
69 if (t
== &mainthread
) tid
= MAIN_THREAD
;
75 if (t
== &mainthread
) tid
= MAIN_THREAD
;
80 if (count
> threshold
) break;
90 /*===========================================================================*
91 * mthread_queue_remove *
92 *===========================================================================*/
93 mthread_thread_t
mthread_queue_remove(queue
)
94 mthread_queue_t
*queue
; /* Queue we want a thread from */
96 /* Get the first thread in this queue, if there is one. */
97 mthread_thread_t thread
;
98 mthread_tcb_t
*tcb
, *random_tcb
, *prev
;
99 int count
= 0, offset_id
= 0, picked_random
= 0;
101 tcb
= queue
->mq_head
;
103 if (MTHREAD_RND_SCHED
) {
104 /* Count items on queue */
105 random_tcb
= queue
->mq_head
;
106 if (random_tcb
!= NULL
) {
109 random_tcb
= random_tcb
->m_next
;
110 } while (random_tcb
!= NULL
);
116 /* Get random offset */
117 offset_id
= random() % count
;
119 /* Find offset in queue */
120 random_tcb
= queue
->mq_head
;
122 while (--offset_id
> 0) {
124 random_tcb
= random_tcb
->m_next
;
127 /* Stitch head and tail together */
128 prev
->m_next
= random_tcb
->m_next
;
130 /* Fix head and tail */
131 if (queue
->mq_head
== random_tcb
)
132 queue
->mq_head
= random_tcb
->m_next
;
133 if (queue
->mq_tail
== random_tcb
)
134 queue
->mq_tail
= prev
;
140 /* Retrieve thread id from tcb */
141 if (tcb
== NULL
) thread
= NO_THREAD
;
142 else if (tcb
== &mainthread
) thread
= MAIN_THREAD
;
143 else thread
= (tcb
->m_tid
);
145 /* If we didn't pick a random thread and queue is not empty... */
146 if (!picked_random
&& thread
!= NO_THREAD
) {
147 tcb
= queue
->mq_head
;
148 if (queue
->mq_head
== queue
->mq_tail
) {
149 /* Queue holds only one thread */
150 queue
->mq_head
= queue
->mq_tail
= NULL
; /* So mark thread empty */
152 /* Second thread in line is the new first */
153 queue
->mq_head
= queue
->mq_head
->m_next
;
158 tcb
->m_next
= NULL
; /* This thread is no longer part of a queue */