universalisos/kernel/src/core/sched.h

369 lines
8 KiB
C

#ifndef UOS_SCHED_H
#define UOS_SCHED_H
/* -------------------------- FILE PROLOGUE -------------------------------- */
/**
* @file
* uos_sched.h
*
* @purpose
* The scheduler module implements the scheduling concepts time partitioning
* and preemptive priority scheduling.
*
* Based on PikeOS sched.h architecture.
*/
/* ------------------------- FILE INCLUSION -------------------------------- */
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
/** Maximum number of CPUs */
#define UOS_MAX_CPUS 4
/** Maximum number of time partitions */
#define UOS_MAX_TIMEPARTS 8
/** Maximum number of priorities */
#define UOS_MAX_PRIORITIES 256
/** Thread states */
#define UOS_THR_STATE_READY 0
#define UOS_THR_STATE_RUNNING 1
#define UOS_THR_STATE_BLOCKED 2
#define UOS_THR_STATE_WAITING 3
#define UOS_THR_STATE_ZOMBIE 4
/** Scheduler flags */
#define UOS_SCHEDFLAG_YIELD (1<<0)
#define UOS_SCHEDFLAG_TIMEOUT (1<<1)
#define UOS_SCHEDFLAG_TP_ALL (1<<2)
#define UOS_SCHEDFLAG_TP_PERIOD (1<<3)
#define UOS_SCHEDFLAG_TP_MAJOR (1<<4)
#define UOS_SCHEDFLAG_TP_CHANGE (1<<5)
#define UOS_SCHEDFLAG_DEADLINE (1<<8)
#define UOS_SCHEDFLAG_OVERDUE (1<<9)
#define UOS_SCHEDFLAG_IDLE (1<<11)
#define UOS_SCHEDFLAG_FREE_THREAD (1<<12)
#define UOS_SCHEDFLAG_BOOST (1<<13)
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
/**
* @brief Priority type
*/
typedef uint32_t uos_prio_t;
/**
* @brief CPU ID type
*/
typedef uint32_t uos_cpuid_t;
/**
* @brief Time type
*/
typedef uint64_t uos_time_t;
/**
* @brief CPU mask type
*/
typedef uint32_t uos_cpumask_t;
/**
* @brief Thread state type
*/
typedef uint32_t uos_thr_state_t;
/**
* @brief List node structure
*/
typedef struct uos_list_node_str {
struct uos_list_node_str* next;
struct uos_list_node_str* prev;
} uos_list_node_t;
/**
* @brief List head structure
*/
typedef struct uos_list_str {
uos_list_node_t head;
} uos_list_t;
/**
* @brief Thread scheduling state
*
* This structure is part of the thread descriptor.
*/
typedef struct uos_sched_state_str {
/** Priority of the thread */
uos_prio_t base_prio;
/** Boosted priority of the thread */
uos_prio_t boost_prio;
/** Assigned CPU */
uos_cpuid_t cpu;
/** MCP */
uos_prio_t mcprio;
/** Preemption threshold priority */
uos_prio_t preempt_prio;
/** Thread's associated time partition */
struct uos_timepart_str* base_tau;
/** Thread's boosted time partition */
struct uos_timepart_str* boost_tau;
/** List link into the ready queue */
uos_list_node_t readyql;
/** Time the thread was selected by the scheduler */
uos_time_t last_start_time;
/** Accumulated execution time */
uos_time_t overall_exec_time;
/** Timeout expiration time */
uos_time_t expiry_time;
/** Timeout related flags */
uint32_t tpflags;
/** List link into the normal timeout tree */
uos_list_node_t timeql_time;
/** List link into the time partition timeout queue */
uos_list_node_t timeql_tp;
/** Absolute deadline expiration time */
uos_time_t deadline;
/** Node link in the deadline tree */
uos_list_node_t deadline_node;
/** Wake up cause */
uint32_t wakeup_cause;
/** Indicator that a wait operation is going to start */
uos_thr_state_t wait_indicated;
/** Indicator that the wakeup operation is completed */
bool wakeup_completed;
/** Bitmask of CPUs on which thread may be scheduled */
uos_cpumask_t affinity_mask;
/** CPU to migrate to */
uos_cpuid_t migrate_cpu;
} uos_sched_state_t;
/**
* @brief Thread information structure
*/
typedef struct uos_thrinfo_str {
/** Thread ID */
uint32_t tid;
/** Thread state */
uos_thr_state_t state;
/** Scheduling state */
uos_sched_state_t sched;
/** Thread entry point */
void (*entry)(void* arg);
/** Thread argument */
void* arg;
/** Thread stack */
void* stack;
/** Thread stack size */
uint32_t stack_size;
/** Thread flags */
uint32_t flags;
/** Thread lock */
uint32_t lock;
} uos_thrinfo_t;
/**
* @brief Ready queue structure
*/
typedef struct uos_readyq_str {
/** Ready queues for each priority */
uos_list_t queues[UOS_MAX_PRIORITIES];
/** Priority tracking bitmap */
uint32_t prio_bitmap[UOS_MAX_PRIORITIES / 32];
/** Highest priority with non-empty queue */
uos_prio_t maxprio;
} uos_readyq_t;
/**
* @brief Time partition structure
*/
typedef struct uos_timepart_str {
/** Time partition ID */
uint32_t id;
/** Ready queue */
uos_readyq_t readyq;
/** Overall execution time */
uos_time_t overall_exec_time;
/** Time partition lock */
uint32_t lock;
} uos_timepart_t;
/**
* @brief Per-CPU scheduler state
*/
typedef struct uos_sched_cpu_str {
/** Current thread */
uos_thrinfo_t* current;
/** Idle thread */
uos_thrinfo_t* idle;
/** Switcher thread */
uos_thrinfo_t* switcher;
/** Active time partition */
uos_timepart_t* active_tau;
/** Scheduler lock */
uint32_t lock;
/** Preemption pending flag */
bool preempt_pending;
} uos_sched_cpu_t;
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
/**
* @purpose
* Initialize the scheduling module.
*
* @param num_timepart
* IN: number of time partitions
* @param num_prio
* IN: number of priorities
*/
void uos_sched_init(uint32_t num_timepart, uos_prio_t num_prio);
/**
* @purpose
* Return pointer to thread object of currently running thread.
*
* @returns
* Pointer to thread object, always succeeds.
*/
uos_thrinfo_t* uos_sched_current(void);
/**
* @purpose
* Registers the current thread as idle thread.
*
* @param cpuid
* IN: current CPU
*/
void uos_sched_register_idle(uos_cpuid_t cpuid);
/**
* @purpose
* Register a kernel thread with entry point.
*
* @param thr
* IN: thread to register
* @param kentry
* IN: kernel entry point
*/
void uos_sched_register_kthread(uos_thrinfo_t* thr, void (*kentry)(void*));
/**
* @purpose
* Make a thread ready.
*
* @param thr
* IN: thread to make ready
*/
void uos_sched_make_ready(uos_thrinfo_t* thr);
/**
* @purpose
* Schedule the next thread.
*/
void uos_sched_schedule(void);
/**
* @purpose
* Yield the current thread.
*/
void uos_sched_yield(void);
/**
* @purpose
* Block the current thread.
*/
void uos_sched_block(void);
/**
* @purpose
* Wake up a thread.
*
* @param thr
* IN: thread to wake up
*/
void uos_sched_wakeup(uos_thrinfo_t* thr);
/**
* @purpose
* Set timeout for the current thread.
*
* @param timeout
* IN: timeout in milliseconds
*/
void uos_sched_timeout_set(uos_time_t timeout);
/**
* @purpose
* Set infinite timeout for the current thread.
*/
void uos_sched_timeout_set_infinite(void);
/**
* @purpose
* Start waiting in the scheduler.
*
* @param state
* IN: state to wait in
*/
void uos_sched_wait_start(uos_thr_state_t state);
/**
* @purpose
* Wait in the scheduler.
*
* @returns
* Wakeup cause
*/
uint32_t uos_sched_wait(void);
/**
* @purpose
* Complete waiting in the scheduler.
*
* @returns
* Wakeup cause
*/
uint32_t uos_sched_wait_complete(void);
/**
* @purpose
* Start wakeup of a thread.
*
* @param thr
* IN: thread to wake up
* @param cause
* IN: wakeup cause
*/
void uos_sched_wakeup_start(uos_thrinfo_t* thr, uint32_t cause);
/**
* @purpose
* Complete wakeup of a thread.
*
* @param thr
* IN: thread to wake up
*/
void uos_sched_wakeup_complete(uos_thrinfo_t* thr);
/**
* @purpose
* Check if preemption is pending.
*
* @returns
* true if preemption is pending, false otherwise
*/
bool uos_sched_preempt_pending(void);
/**
* @purpose
* Preemption point.
*/
void uos_sched_preempt_point(void);
#endif /* UOS_SCHED_H */