Data structure:
/*
* Head of run queues.
*/
TAILQ_HEAD(rqhead, thread);
/*
* Bit array which maintains the status of a run queue. When a queue is
* non-empty the bit corresponding to the queue number will be set.
*/
struct rqbits {
rqb_word_t rqb_bits[RQB_LEN];
};
/*
* Run queue structure. Contains an array of run queues on which processes
* are placed, and a structure to maintain the status of each queue.
*/
struct runq {
struct rqbits rq_status;
struct rqhead rq_queues[RQ_NQS];
};
Data macros and variables:
#define RQ_NQS (64) /* Number of run queues. */
#define RQ_PPQ (4) /* Priorities per queue. */
for amd6:
#define RQB_LEN (1) /* Number of priority status words. */
#define RQB_L2BPW (6) /* Log2(sizeof(rqb_word_t) * NBBY)). */
#define RQB_BPW (1<<RQB_L2BPW) /* Bits in an rqb_word_t. */
#define RQB_BIT(pri) (1ul << ((pri) & (RQB_BPW - 1)))
#define RQB_WORD(pri) ((pri) >> RQB_L2BPW)
#define RQB_FFS(word) (bsfq(word))
/*
* Type of run queue status word.
*/
typedef u_int64_t rqb_word_t;
for arm:
#define RQB_LEN (2) /* Number of priority status words. */
#define RQB_L2BPW (5) /* Log2(sizeof(rqb_word_t) * NBBY)). */
#define RQB_BPW (1<<RQB_L2BPW) /* Bits in an rqb_word_t. */
#define RQB_BIT(pri) (1 << ((pri) & (RQB_BPW - 1)))
#define RQB_WORD(pri) ((pri) >> RQB_L2BPW)
#define RQB_FFS(word) (ffs(word) - 1)
/*
* Type of run queue status word.
*/
typedef u_int32_t rqb_word_t;
for other arches ….
API functions:
void runq_add(struct runq *, struct thread *, int);
void runq_add_pri(struct runq *, struct thread *, u_char, int);
int runq_check(struct runq *);
struct thread *runq_choose(struct runq *);
struct thread *runq_choose_from(struct runq *, u_char);
struct thread *runq_choose_fuzz(struct runq *, int);
void runq_init(struct runq *);
void runq_remove(struct runq *, struct thread *);
void runq_remove_idx(struct runq *, struct thread *, u_char *);
Summary:
Thread’s priority level is from 0 to 255. And there are only 64 queues. Then thread which priority level 0 to 3 are put into first queue and 4-7 are put into second queue and so on.
There are 64 status bits in rqb_bits to flag whether queue is empty.