Background seL4 organizes threads into ready queues, of which there is one for each domain, for each priority level. The ready queue for a given domain/priority combination can be found by indexing the array `ksReadyQueues` with "domain*num_priorities + priority". Current scheduler implementation To find the non-empty ready queue with the maximum priority for the current domain, seL4 iterates through `ksReadyQueues`, starting with the element corresponding to the current domain and maximum possible priority, and decrementing the priority until a non-empty queue is found. This is problematic in cases where the only ready threads have low priorities, as iterating through many elements of an array effectively flushes the cache. Changes in this patch This patch replaces the iteration with a lookup into a table of bitfields per domain. Using bitfields allows the kernel to determine the highest priority level with a non-empty ready queue for the current domain by counting the leading zeroes in bitfields. This removes the negative cache effects of iterating through an array. Implementation details For each domain, a multilevel table of bitfields is maintained which stores the priority levels within that domain for which there exist ready threads. On a 32-bit architecture, the top level of the table is a 32-bit bitfield where if the ith bit is set, there is at least 1 priority level in [i*32..i*32+31] with a non-empty ready queue. The positions of bits in this bitfield are used as indices into the second level table, which is an array of 32-bit bitfields. The ith bit of the jth bitfield in this array set to 1, indicates that priority level j*32+i has a non-empty ready queue.
39 lines
1.2 KiB
C
39 lines
1.2 KiB
C
/*
|
|
* Copyright 2014, General Dynamics C4 Systems
|
|
*
|
|
* This software may be distributed and modified according to the terms of
|
|
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
|
* See "LICENSE_GPLv2.txt" for details.
|
|
*
|
|
* @TAG(GD_GPL)
|
|
*/
|
|
|
|
#ifndef __MODEL_STATEDATA_H
|
|
#define __MODEL_STATEDATA_H
|
|
|
|
#include <types.h>
|
|
#include <object/structures.h>
|
|
#include <object/tcb.h>
|
|
#include <arch/model/statedata.h>
|
|
|
|
extern tcb_queue_t ksReadyQueues[] VISIBLE;
|
|
extern word_t ksReadyQueuesL1Bitmap[CONFIG_NUM_DOMAINS] VISIBLE;
|
|
extern word_t ksReadyQueuesL2Bitmap[CONFIG_NUM_DOMAINS][(CONFIG_NUM_PRIORITIES / wordBits) + 1] VISIBLE;
|
|
extern tcb_t *ksCurThread VISIBLE;
|
|
extern tcb_t *ksIdleThread VISIBLE;
|
|
extern tcb_t *ksSchedulerAction VISIBLE;
|
|
extern word_t ksWorkUnitsCompleted;
|
|
extern irq_state_t intStateIRQTable[] VISIBLE;
|
|
extern cte_t *intStateIRQNode VISIBLE;
|
|
extern const dschedule_t ksDomSchedule[];
|
|
extern const unsigned int ksDomScheduleLength;
|
|
extern uint32_t ksDomScheduleIdx;
|
|
extern dom_t ksCurDomain;
|
|
extern word_t ksDomainTime;
|
|
|
|
#define SchedulerAction_ResumeCurrentThread ((tcb_t*)0)
|
|
#define SchedulerAction_ChooseNewThread ((tcb_t*)~0)
|
|
|
|
#define NUM_READY_QUEUES (CONFIG_NUM_DOMAINS * CONFIG_NUM_PRIORITIES)
|
|
|
|
#endif
|