34 bool already_locked) {
41 scheduler[core_id].run_queue_head =
nullptr;
50 if (
scheduler[core_id].run_queue_head == current)
54 if (
scheduler[core_id].current == current)
66 cpu_register_t*
reg) {
90 cpu_register_t*
reg) {
118 const uint16_t core_id = current_core->core_id;
122 if (!
scheduler[core_id].run_queue_head) {
131 if (!current_node || !current_node->
thread) {
138 bool needs_context_switch =
false;
150 VOXIA_MAX_SCHEDULER_TIME_MS) {
151 needs_context_switch =
true;
155 LOG2_DEBUG(
"SCHEDULER",
"core %d terminated thread id %d",
160 needs_context_switch =
true;
162 if (!
scheduler[core_id].run_queue_head) {
171 if (needs_context_switch) {
175 next_node =
scheduler[core_id].run_queue_head;
194 "core %d ready: user mode rip=0x%x", core_id,
206 "core %d ready: kernel mode rip=0x%x",
210 if (needs_context_switch && next_thread !=
thread) {
219 current_core->active_thread = next_thread;
258 queue->prev_queue = last;
280 LOG2_ERROR(
"SCHED",
"error allocate scheduler for thread %d",
285 LOG2_DEBUG(
"SCHED",
"ATTACH thread id %d -> queue 0x%x", new_thread->
id,
288 queue->thread = new_thread;
291#define APIC_TIMER_MASKED (1 << 16)
309 if (!current_node || !current_node->
thread) {
321 if (!
scheduler[core_id].run_queue_head) {
329 next_node =
scheduler[core_id].run_queue_head;
359 next->current_core_id = core_id;
360 current_core->active_thread =
next;
#define APIC_TIMER_PERIOD
void vxAPICCreateTimer(uint32_t type, uint64_t freq_us, uint16_t vector)
each_core_data * get_current_core_data(void)
each_core_data core_data[VOXIA_MAX_CORE]
uint64_t vxHPETGetMainCount()
uint8_t get_current_core_cpuid()
@ THREAD_STATE_TERMINATED
boolean_t g__scheduler__is__running
void irq_register(uint8_t core, int n, void *handler, boolean_t use_default_isr, uint16_t selector, uint8_t ist, uint8_t type_attr)
#define INTERRUPT_ATTR_KERNEL
void serial_printf(const char *fmt,...)
void msrSetFSBase(uint64_t base)
void paging_reload(page_t p)
scheduler_core_t * vxGetSchedulerCore(uint16_t core)
static void vxRestoreRegister(volatile interrupt_stack_frame_t *stack, cpu_register_t *reg)
void attach_to_scheduler(thread_t *new_thread)
static scheduler_core_t scheduler[VOXIA_MAX_CORE]
void vxStartScheduler(void)
static void vxSchedulerTick(volatile interrupt_stack_frame_t *reg)
static void vxDeatachFromScheduler(scheduler_queue_t *current, bool already_locked)
static struct slab_cache * scheduler_cache
void sch_restore_to_next_thread(volatile interrupt_stack_frame_t *rsp, uint16_t core_id)
static scheduler_queue_t * vxAllocScheduler(const uint16_t core)
static void vxSaveRegister(volatile interrupt_stack_frame_t *stack, cpu_register_t *reg)
scheduler_queue_t * vxSchedulerGetCurrentQueue(uint16_t core)
struct scheduler_core scheduler_core_t
struct scheduler_queue scheduler_queue_t
#define LOG2_DEBUG(mod, fmt,...)
#define LOG2_ERROR(mod, fmt,...)
#define LOG_INFO(mod, fmt,...)
void * vxSlabAlloc(struct slab_cache *cache)
void vxCreateSlabCache(struct slab_cache **cache, const char *name, const size_t obj_size, size_t alignment, const uintptr_t virt_addr)
void spin_acquire(spinlock_t *lock)
void spin_release(spinlock_t *lock)
void memset(void *ptr, int value, size_t num)
struct scheduler_queue * next_queue
struct scheduler_queue * prev_queue
boolean_t has_update_run_time
volatile uintptr_t * page