Processes and Scheduler: ELT048 - EOS
Processes and Scheduler: ELT048 - EOS
ELT048 – EOS
Review
Review
• Function pointers
• Software Engine
U
UNN II F
FEE II
Exercise
• Update last class structure to void main (void){
include a function pointer as AddProc("name1", 1, func1);
one of its members. AddProc("name2", 2, func2);
• Create a function (ExecProc) AddProc("name3", 3, func3);
that executes the pointer ExeProc();
stored in the "first" filled RemoveProc();
position of the circular buffer. ExeProc();
• Create a main that executes RemoveProc();
the commands to the side: ExeProc();
• Create the three different RemoveProc();
functions, each printing a }
different phrase.
U
UNN II F
FEE II
Exercise
typedef int (*ptrFunc)(void);
//definição da estrutura
typedef struct {
char name;
int time;
ptrFunc func;
}process;
}
Exercise
//função de remoção de um “process” do buffer
void removeProc (void){
}
Exercise
//função de execução de “process” no buffer
void exec(void){
}
Exercise
#include "stdio.h"
void main (void){
process p1 = {"",0,func1};
process p2 = {"",0,func2};
process p3 = {"",0,func3};
start = 0; end = 0;
addProc(p1);
addProc(p2);
addProc(p3);
exec();
removeProc();
exec();
removeProc();
exec();
removeProc();
}
Processes
U
UNN II F
FEE II
Process
• The implementation of a process is closely
dependent on the type of kernel used and the
interfaces available to the programmer.
• The simplest process can be represented by a
function.
U
UNN II F
FEE II
Process
//ponteiro para mapa de I/O
#define LEDS (*((unsigned char*)0xF95))
U
UNN II F
FEE II
Process reschedule
• First you must know:
What kind of kernel is running: preemptive or
cooperative?
Is there a time scheduler?
U
UNN II F
FEE II
Process reschedule
• Infinite Loop: Should only be used if
1) the kernel is able to interrupt the process or if
2) the process is the only one running on the system.
• In case 2 it does not make sense to have a kernel.
U
UNN II F
FEE II
Process – infinite loop
//processo para piscar os leds
void blinkLeds (int time){
int i;
//liga os leds
for(;;){//ever
LEDS = 0x00;
for(i = 0; i < time; i++){
__asm NOP
}
//desliga os leds
LEDS = 0xFF;
for(i = 0; i < time; i++){
__asm NOP
}
}
}
Process reschedule
• Re-run the function:
Allows the process to free up time for the kernel to
perform other functions.
Must be used in cooperative kernel.
• When possible, one should not use delay routines,
leaving time counting for the kernel.
• In this way the system can perform more useful
tasks while waiting
U
UNN II F
FEE II
Process re-execute
//Original
//processo para piscar os leds
void toggleLeds (int time){
int i;
LEDS = 0x00;
for(i = 0; i < time; i++){
__asm NOP
}
//desliga os leds
LEDS = 0xFF;
for(i = 0; i < time; i++){
__asm NOP
}
}
//igual à primeira implementação. Gasta tempo
atoa.
Process re-execute
//Omissão das rotinas de tempo 1
//processo para piscar os leds
void toggleLeds (int time){
int i;
//liga os leds
LEDS = 0x00;
//desliga os leds
LEDS = 0xFF;
}
U
UNN II F
FEE II
Process
typedef int (*ptrFunc)(void);
U
UNN II F
FEE II
Kernel responsabilities
U
UNN II F
FEE II
Processes management
http://learnyousomeerlang.com/building-applications-with-otp
U
UNN II F
FEE II
microkernel(3);
//first implementation
kernel_example(3.1);
U
UNN II F
FEE II
microkernel(3);
U
UNN II F
FEE II
microkernel(3);
U
UNN II F
FEE II
microkernel(3);
U
UNN II F
FEE II
microkernel(3);
void kernelInit(void){
end = 0;
}
U
UNN II F
FEE II
microkernel(3);
void kernelLoop(void){
int i;
for(;;){
//cycle through the processes
for(i=0; i<end; i++){
(*pool[i])();
}
}
}
U
UNN II F
FEE II
microkernel(3);
//main loop
void main(void){
kernelInit();
kernelAddProc(tst1);
kernelAddProc(tst2);
kernelAddProc(tst3);
kernelLoop();
}
U
UNN II F
FEE II
Simple?
That’s all?
Scheduler
U
UNN II F
FEE II
microkernel(3);
//second implementation
//circular buffer and struct added
kernel_example(3.2);
Scheduler
U
UNN II F
FEE II
Scheduler
U
UNN II F
FEE II
Scheduler
Operating System Preemption Algorithm
Amiga OS Yes Prioritized Round-robin scheduling
FreeBSD Yes Multilevel feedback queue
Linux pre-2.6 Yes Multilevel feedback queue
Linux 2.6-2.6.23 Yes O(1) scheduler
Linux post-2.6.23 Yes Completely Fair Scheduler
Mac OS pre-9 None Cooperative Scheduler
Mac OS 9 Some Preemptive for MP tasks, Cooperative Scheduler for
processes and threads
Mac OS X Yes Multilevel feedback queue
NetBSD Yes Multilevel feedback queue
Solaris Yes Multilevel feedback queue
Windows 3.1x None Cooperative Scheduler
Windows 95, 98, Me Half Preemptive for 32-bit processes, Cooperative
Scheduler for 16-bit processes
Windows NT (XP, Vista, 7, Yes Multilevel feedback queue
2k)
U
UNN II F
FEE II
Scheduler
U
UNN II F
FEE II
Scheduler
• Why use priority based schedulers?
Simple and deterministic
• How can I choose a process priority?
Function importance
Shared resources
Mathematical model (RMS)
U
UNN II F
FEE II
Scheduler
• RMS Rate-monotonic scheduling
Static priority for each process
Priorities are given according to the process cycle
• Process with bigger cycle has a lower priority
Given that there are no resource shared between
processes:
U
UNN II F
FEE II
Kernel impact on schedulers
• Pre-emption • Cooperative
It allows the kernel to It is necessary that the
pause a process to run a processes end up giving
second without opportunity for other
changing the code's processes to be executed
variables and flow. by the processor
Requires hardware Infinite loops can lock
support due to the entire system
interruptions Can be programmed
Can only be entire in C and requires
programmed in no special hardware
assembly
U
UNN II F
FEE II
Scheduler
• Rescheduling of processes
For a cooperative kernel it is important that all processes
terminate voluntarily to cede CPU space to the other
processes.
In cases where the process needs to be run constantly it
should be rescheduled in the CPU
U
UNN II F
FEE II
Practical example
microkernel(3);
U
UNN II F
FEE II
Exemplo
U
UNN II F
FEE II
microkernel(3);
//return code
#define SUCCESS 0
#define FAIL 1
#define REPEAT 2
//process struct
typedef struct {
ptrFunc func;
} process;
Process * pool[POOL_SIZE];
microkernel(3);
char kernelInit(void){
start = 0;
end = 0;
return SUCCESS;
}
char kernelAddProc(process * newProc){
//checking for free space
if ( ((end+1)%POOL_SIZE) != start){
pool[end] = newProc;
end = (end+1)%POOL_SIZE;
return SUCCESS;
}
return FAIL;
}
microkernel(3);
void kernelLoop(void){
for(;;){
//Do we have any process to execute?
if (start != end){
//check if there is need to reschedule
if (pool[start]->func() == REPEAT){
kernelAddProc(pool[start]);
}
//prepare to get the next process;
start = (start+1)%POOL_SIZE;
}
}
}
microkernel(3);
void main(void){
//declaring the processes
process p1 = {tst1};
process p2 = {tst2};
process p3 = {tst3};
kernelInit();
//Test if the process were added
if (kernelAddProc(&p1) == SUCCESS){
/*Turn led 1*/}
if (kernelAddProc(&p2) == SUCCESS){
/*Turn led 2*/}
if (kernelAddProc(&p3) == SUCCESS){
/*Turn led 3*/}
kernelLoop();
}
Exercise
U
UNN II F
FEE II