void dispatch_core(int core) { int skip = cpu_threads; int quant = cpu_dispatch_width; int remain; switch (cpu_dispatch_kind) { case cpu_dispatch_kind_shared: do { CORE.dispatch_current = (CORE.dispatch_current + 1) % cpu_threads; remain = dispatch_thread(core, CORE.dispatch_current, 1); skip = remain ? skip - 1 : cpu_threads; quant = remain ? quant : quant - 1; } while (quant && skip); break; case cpu_dispatch_kind_timeslice: do { CORE.dispatch_current = (CORE.dispatch_current + 1) % cpu_threads; skip--; } while (skip && can_dispatch_thread(core, CORE.dispatch_current) != di_stall_used); dispatch_thread(core, CORE.dispatch_current, quant); break; } }
void sys_thread_switch(l4_threadid_t tid) { TRACEPOINT_1PAR(SYS_THREAD_SWITCH, tid.raw); #if defined (CONFIG_DEBUG_TRACE_SYSCALLS) if (tid == L4_NIL_ID) spin1(75); else printf("sys_thread_switch(tid: %x)\n", tid); #endif /* Make sure we are in the ready queue to * find at least ourself and ensure that the thread * is rescheduled */ thread_enqueue_ready(get_current_tcb()); tcb_t * tcb = tid_to_tcb(tid); if (!(!l4_is_nil_id(tid) && (tcb->myself == tid ) && (IS_RUNNING(tcb)))) tcb = find_next_thread(); /* do dispatch only if necessary */ if (tcb != get_current_tcb()) dispatch_thread(tcb); return_thread_switch(); }
/* this function is called from the hardware dependend * interrupt service routine for a timer tick */ void handle_timer_interrupt() { #if (defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB)) && defined(CONFIG_DEBUG_BREAKIN) kdebug_check_breakin(); #endif TRACEPOINT(HANDLE_TIMER_INTERRUPT, printf("timer interrupt (curr=%p)\n", get_current_tcb())); #if defined(CONFIG_SMP) /* only cpu 0 maintains the clock */ if (get_cpu_id() == 0) #endif kernel_info_page.clock += TIME_QUANTUM; tcb_t * current = get_current_tcb(); tcb_t * wakeup = parse_wakeup_queue(current->priority, kernel_info_page.clock); current->current_timeslice -= TIME_QUANTUM; /* make sure runable threads are in the run queue */ if (current != get_idle_tcb()) thread_enqueue_ready(current); if (wakeup) { dispatch_thread(wakeup); return; } if (current->current_timeslice <= 0) { spin1(78); current->current_timeslice = current->timeslice; dispatch_thread(find_next_thread()); } }