void check_scheduling(void) { uint32_t prio = get_highest_priority(); task_t* curr_task = per_core(current_task); if (prio > curr_task->prio) { reschedule(); #ifdef DYNAMIC_TICKS } else if ((prio > 0) && (prio == curr_task->prio)) { // if a task is ready, check if the current task runs already one tick (one time slice) // => reschedule to realize round robin const uint64_t diff_cycles = get_rdtsc() - curr_task->last_tsc; const uint64_t cpu_freq_hz = 1000000ULL * (uint64_t) get_cpu_frequency(); if (((diff_cycles * (uint64_t) TIMER_FREQ) / cpu_freq_hz) > 0) { LOG_DEBUG("Time slice expired for task %d on core %d. New task has priority %u.\n", curr_task->id, CORE_ID, prio); reschedule(); } #endif } }
/* Up or "V" operation on a semaphore. Increments SEMA's value and wakes up one thread of those waiting for SEMA, if any. This function may be called from an interrupt handler. */ void sema_up (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); old_level = intr_disable (); if (!list_empty (&sema->waiters)) { /* Unblocks the thread with the highest priority in the sema->waiters list. */ struct list_elem *e = get_highest_priority (&sema->waiters); struct thread *t = list_entry (e, struct thread, elem); list_remove (e); thread_unblock (t); } sema->value++; /* A thread is unblocked: checks if the current should yield. */ highest_priority_test (); intr_set_level (old_level); }