seL4/include/kernel/thread.h
Anna Lyons a1421832ac SELFOUR-242: invert bitfield scheduler & optimise
This commit does the following:

* invert the bit field scheduler for better cache performance for high priority threads
* peeks into the bitfield scheduler to allow fastpath to be leveraged when IPC occurs from lo --> hi priority threads if correct
2016-11-15 09:45:48 +11:00

94 lines
2.7 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 __KERNEL_THREAD_H
#define __KERNEL_THREAD_H
#include <types.h>
#include <util.h>
#include <object/structures.h>
#include <arch/machine.h>
static inline CONST word_t
ready_queues_index(word_t dom, word_t prio)
{
if (CONFIG_NUM_DOMAINS > 1) {
return dom * CONFIG_NUM_PRIORITIES + prio;
} else {
assert(dom == 0);
return prio;
}
}
static inline CONST word_t
prio_to_l1index(word_t prio)
{
return (prio >> wordRadix);
}
static inline CONST word_t
l1index_to_prio(word_t l1index)
{
return (l1index << wordRadix);
}
static inline CONST word_t
invert_l1index(word_t l1index)
{
word_t inverted = (L2_BITMAP_SIZE - 1 - l1index);
assert(inverted < L2_BITMAP_SIZE);
return inverted;
}
static inline prio_t
getHighestPrio(word_t dom)
{
word_t l1index;
word_t l2index;
word_t l1index_inverted;
/* it's undefined to call clzl on 0 */
assert(NODE_STATE(ksReadyQueuesL1Bitmap)[dom] != 0);
l1index = wordBits - 1 - clzl(NODE_STATE(ksReadyQueuesL1Bitmap)[dom]);
l1index_inverted = invert_l1index(l1index);
assert(NODE_STATE(ksReadyQueuesL2Bitmap)[dom][l1index_inverted] != 0);
l2index = wordBits - 1 - clzl(NODE_STATE(ksReadyQueuesL2Bitmap)[dom][l1index_inverted]);
return (l1index_to_prio(l1index) | l2index);
}
void configureIdleThread(tcb_t *tcb);
void activateThread(void) VISIBLE;
void suspend(tcb_t *target);
void restart(tcb_t *target);
void doIPCTransfer(tcb_t *sender, endpoint_t *endpoint,
word_t badge, bool_t grant, tcb_t *receiver);
void doReplyTransfer(tcb_t *sender, tcb_t *receiver, cte_t *slot);
void doNormalTransfer(tcb_t *sender, word_t *sendBuffer, endpoint_t *endpoint,
word_t badge, bool_t canGrant, tcb_t *receiver,
word_t *receiveBuffer);
void doFaultTransfer(word_t badge, tcb_t *sender, tcb_t *receiver,
word_t *receiverIPCBuffer);
void doNBRecvFailedTransfer(tcb_t *thread);
void schedule(void);
void chooseThread(void);
void switchToThread(tcb_t *thread) VISIBLE;
void switchToIdleThread(void);
void setDomain(tcb_t *tptr, dom_t dom);
void setPriority(tcb_t *tptr, prio_t prio);
void setMCPriority(tcb_t *tptr, prio_t mcp);
void scheduleTCB(tcb_t *tptr);
void attemptSwitchTo(tcb_t *tptr);
void switchIfRequiredTo(tcb_t *tptr);
void setThreadState(tcb_t *tptr, _thread_state_t ts) VISIBLE;
void timerTick(void);
void rescheduleRequired(void);
#endif