My Kernel v0.1.0

Scheduler implementation. More...

Collaboration diagram for Scheduling:

Modules

 Processes
 
 Waitqueue
 Waiting queue.
 
 Worker thread
 Worker thread.
 

Macros

#define no_preemption_scope()
 Define a scope during which the current thread should never be pre-empted. More...
 

Functions

void schedule (void)
 Reschedule the current thread. More...
 
void schedule_preempt (void)
 Forcibly reschedule the current thread.
 
bool scheduler_preempt_disable (void)
 Prevent the current thread from being pree-empted by the scheduler. More...
 
void scheduler_preempt_enable (bool old_if_flag)
 Re-allow the current thread to be pre-empted. More...
 
void sched_new_thread (thread_t *)
 Add a new thread to be scheduled. More...
 
static ALWAYS_INLINE void sched_new_thread_create (thread_entry_t entrypoint, void *data, u32 flags)
 Create a new thread and instantly schedule it. More...
 
void sched_block_thread (struct thread *)
 Mark the thread as blocked. More...
 
void sched_unblock_thread (thread_t *)
 Unblock a currently blocked thread. More...
 
void sched_block_waiting_until (struct thread *, clock_t until)
 Block thread and wait until a given deadline.
 
void sched_unblock_waiting_before (clock_t deadline)
 Unblock all waiting threads whose deadline is inferior to deadline.
 

Detailed Description

Scheduler

The scheduler is responsible for ... well, scheduling proceses.

It has to decide which threads to run next, and when, among all currently running threads. This is what allows running multiple threads on a single CPU.

A good scheduler is crucial to the user's experience, and this is often what makes the "feel" of the entire OS.

Design

For now, our scheduler uses a preemptive round-robin design. It holds a list of currently running threads, called the runqueue, and cycles between them at a regular interval.

The interval is set currently set to 2MS, per thread, per cycle, and is handled inside irq_timer_handler. If the current thread is still running when the current interval reaches its end, the next one takes its place, and the timer is reset. This is called preemption.

During the execution of a thread, it often needs to access some resources, thus having to wait until the resource is available. When this is the case, the thread is marked as SCHED_WAITING using sched_block_current_thread, and we switch to the next available running thread. Once the resource is available, the relevant interface has the resposibility to notify the scheduler that the thread can be rescheduled, using sched_unblock_thread.

Improvements

Macro Definition Documentation

◆ no_preemption_scope

#define no_preemption_scope ( )
Value:
for (sched_scope_t scope CLEANUP(sched_scope_destructor) = \
sched_scope_constructor(); \
!scope.done; scope.done = true)

WARNING: As this macro uses a for loop to function, any 'break' directive placed inside it will break out of the guarded scope instead of that of its containing loop.

Function Documentation

◆ sched_block_thread()

void sched_block_thread ( struct thread thread)

A blocked thread cannot be rescheduled until it is explicitely unblocked using sched_unblock_thread()

◆ sched_new_thread()

void sched_new_thread ( thread_t thread)

When adding a new thread, its state will be set to SCHED_RUNNING

◆ sched_new_thread_create()

static ALWAYS_INLINE void sched_new_thread_create ( thread_entry_t  entrypoint,
void *  data,
u32  flags 
)
static
See also
sched_new_thread thread_create

◆ sched_unblock_thread()

void sched_unblock_thread ( thread_t thread)

The thread is marked as SCHED_RUNNING and is automatically added to the appropriate runqueue.

◆ schedule()

void schedule ( void  )

This is the main function of the scheduler. It is called when we want to switch to the next scheduled thread. It automatically reinserts the current thread into the correct queue depending on its state.

◆ scheduler_preempt_disable()

bool scheduler_preempt_disable ( void  )
Returns
Wether interrupts were previously enabled

◆ scheduler_preempt_enable()

void scheduler_preempt_enable ( bool  old_if_flag)
Parameters
old_if_flagThe state of the interrputs prior to locking