preempt.c File Reference

Simple preemptive multitasking scheduler. More...

#include "cfg/cfg_proc.h"
#include "proc_p.h"
#include "proc.h"
#include <kern/irq.h>
#include <kern/monitor.h>
#include <cpu/frame.h>
#include <cpu/irq.h>
#include <cfg/log.h>
#include <cfg/module.h>
#include <cfg/depend.h>

Go to the source code of this file.

Functions

void preempt_yield (void)
 Define function prototypes exported outside.
int preempt_needPreempt (void)
 Check if we need to schedule another task.
void preempt_preempt (void)
 Preempt the current task.
void preempt_switch (void)
 Give the control of the CPU to another process.
void preempt_wakeup (Process *proc)
 Immediately wakeup a process, dispatching it to the CPU.
static void preempt_schedule (void)
 Call the scheduler and eventually replace the current running process.

Detailed Description

Simple preemptive multitasking scheduler.

Preemption is explicitly regulated at the exit of each interrupt service routine (ISR). Each task obtains a time quantum as soon as it is scheduled on the CPU and its quantum is decremented at each clock tick. The frequency of the timer determines the system tick granularity and CONFIG_KERN_QUANTUM the time sharing interval.

When the quantum expires the handler proc_needPreempt() checks if the preemption is enabled and in this case preempt_schedule() is called, that possibly replaces the current running thread with a different one.

The preemption can be disabled or enabled via proc_forbid() and proc_permit() primitives. This is implemented using a global atomic counter. When the counter is greater than 0 the task cannot be preempted; only when the counter reaches 0 the task can be preempted again.

Preemption-disabled sections may be nested. The preemption will be re-enabled when the outermost preemption-disabled section completes.

The voluntary preemption still happens via proc_switch() or proc_yield(). The first one assumes the current process has been already added to a private wait queue (e.g., on a semaphore or a signal), while the second one takes care of adding the process into the ready queue.

Context switch is done by CPU-dependent support routines. In case of a voluntary preemption the context switch routine must take care of saving/restoring only the callee-save registers (the voluntary-preemption is actually a function call). The kernel-preemption always happens inside a signal/interrupt context and it must take care of saving all registers. For this, in the entry point of each ISR the caller-save registers must be saved. In the ISR exit point, if the context switch must happen, we switch to user-context and call the same voluntary context switch routine that take care of saving/restoring also the callee-save registers. On resume from the switch, the interrupt exit point moves back to interrupt-context, resumes the caller-save registers (saved in the ISR entry point) and return from the interrupt-context.

Note:
Thread priority (if enabled by CONFIG_KERN_PRI) defines the order in the proc_ready_list and the capability to deschedule a running process. A low-priority thread can't preempt a high-priority thread.

A high-priority process can preempt a low-priority process immediately (it will be descheduled and replaced in the interrupt exit point). Processes running at the same priority can be descheduled when they expire the time quantum.

Note:
Sleeping while preemption is disabled fallbacks to a busy-wait sleep. Voluntary preemption when preemption is disabled raises a kernel bug.
Author:
Bernie Innocenti <bernie@codewiz.org>
Andrea Righi <arighi@develer.com>

Definition in file preempt.c.


Function Documentation

void preempt_switch ( void   ) 

Give the control of the CPU to another process.

Note:
Assume the current process has been already added to a wait queue.
Warning:
This should be considered an internal kernel function, even if it is allowed, usage from application code is strongly discouraged.

Definition at line 172 of file preempt.c.

void preempt_yield ( void   ) 

Define function prototypes exported outside.

Voluntarily release the CPU.

Required to silent gcc "no previous prototype" warnings.

Definition at line 204 of file preempt.c.