0% found this document useful (0 votes)
19 views

Processes and Scheduler: ELT048 - EOS

This document discusses processes and scheduling in an operating system. It begins by reviewing function pointers and software engines. It then provides an exercise to update a class structure to include a function pointer member, create functions to add and remove processes from a circular buffer, and execute the first process in the buffer. Various process scheduling algorithms are discussed like first-in first-out, shortest remaining time, and round-robin. The document focuses on managing processes through data structures like circular buffers and process scheduling to optimize throughput, latency, and fairness of process execution.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Processes and Scheduler: ELT048 - EOS

This document discusses processes and scheduling in an operating system. It begins by reviewing function pointers and software engines. It then provides an exercise to update a class structure to include a function pointer member, create functions to add and remove processes from a circular buffer, and execute the first process in the buffer. Various process scheduling algorithms are discussed like first-in first-out, shortest remaining time, and round-robin. The document focuses on managing processes through data structures like circular buffers and process scheduling to optimize throughput, latency, and fairness of process execution.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 60

Processes and scheduler

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;

//definição do buffer circular


#define BUFFERSIZE 10
process buffer[BUFFERSIZE];

//definição dos “ponteiros” de acesso


int start, end;
Exercise
//função de adição de “process” no buffer
//Atenção na mudança dos parâmetros
void addProc(process nProcess){

//checagem de espaço disponível


if ( ((end+1)%BUFFERSIZE) != start){
//Atualização da posição atual
buffer[end] = nProcess;
//incremento da posição
end = (end+1)%(BUFFERSIZE);
}

}
Exercise
//função de remoção de um “process” do buffer
void removeProc (void){

//checagem se existe alguem pra retirar


if ( start != end){
//incremento da posição
start = (start +1)%(BUFFERSIZE);
}

}
Exercise
//função de execução de “process” no buffer
void exec(void){

//checar se existe alguem para ser executado


if (start != end){
//execução da função
buffer[start].func();
}

}
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

I really mean tasks.


Process
• A process consists of a
unit of code that can be
executed, a delimited
region of memory, and
a set of information
about its current state.

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))

//processo para piscar os leds


void blinkLeds (int time){
int i;
//liga os leds
LEDS = 0x00;
for(i = 0; i < time; i++){
__asm NOP
}
//desliga os leds
LEDS = 0xFF;
for(i = 0; i < time; i++){
__asm NOP
}
}
Process
reeschedule
Process reschedule
• How do I keep the process running?
 Re-run function?
 Create a loop with n repeats?
 Create an infinite loop?

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;
}

//Não funciona, deve ligar em uma chamada e


desligar em outra
Process re-execute
//Omissão das rotinas de tempo 2
//processo para piscar os leds
void toggleLeds (int time){
int i;
LEDS = ~LEDS;
}

//Não funciona bem, os tempos não são respeitados


Process re-execute
//Omissão das rotinas de tempo 3
//processo para piscar os leds
void toggleLeds (int time){
int i;
static int lastTime;
if ( (now() - lastTime) >= time){
LEDS = ~LEDS;
LastTime = now();
}

//a função now() deve retornar o horário em


unidades de segundo/milisegundo
Process
definition
In C language, and for this class
Process
• As mentioned the process is, in principle, a function
that must be executed when the process is called.
• In addition there are several important information
that must be aggregated to be able to manage the
process
 Priority, runtime, name, reserved memory region, etc.
• In general a structure is used to aggregate all this
information.

U
UNN II F
FEE II
Process
typedef int (*ptrFunc)(void);

//our new process


typedef struct {
char* nomeDoProcesso;
ptrFunc funcao;
int prioridade;
int tempo;
}process;
The kernel
Kernel

• In the computer field, the kernel is the part of the


code responsible for manage the interface between
the hardware and the application.
• The most critical hardware features in this regard
are processor, memory, and drivers.

U
UNN II F
FEE II
Kernel responsabilities

U
UNN II F
FEE II
Processes management

• The management can be done in lots of different


ways
 We’ll be using a circular buffer (process pool).
 The access to this buffer must be restricted to the kernel.

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);

• In this first example we will build the main part of our


kernel.
• It should have a way to store which functions are needed
to be executed and in which order.
• This will be done by a static vector of pointers to
function
 We’re not using the structs, only the function pointer
//pointer function declaration
typedef void(*ptrFunc)(void);
//process pool
static ptrFunc pool[4];

U
UNN II F
FEE II
microkernel(3);

• Each process is a function with the same signature


of ptrFunc
void tst1(void){
printf("Process 1\n");
}
void tst2(void){
printf("Process 2\n");
}
void tst3(void){
printf("Process 3\n");
}

U
UNN II F
FEE II
microkernel(3);

• The kernel itself consists of three functions:


 One to initialize all the internal variables
 One to add a new process
 One to execute the main kernel loop
//kernel internal variables
ptrFunc pool[4];
int end;
//kernel function's prototypes
void kernelInit(void);
void kernelAddProc(ptrFunc newFunc);
void kernelLoop(void);

U
UNN II F
FEE II
microkernel(3);

//kernel function's implementation

void kernelInit(void){
end = 0;
}

void kernelAddProc(ptrFunc newFunc){


if (end <4){
pool[end] = newFunc;
end++;
}
}

U
UNN II F
FEE II
microkernel(3);

//kernel function's implementation

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

AKA: the real boss.


Scheduler

• The scheduler is responsible for choosing which is


the next process to be executed.
• There are some parameters to consider:
 Throughtput: number of processes per time.
 Latency:
• Turnaround time - time between the beginning and end of a
process.
• Response time: value between a request and the first response
of the process.
• Fairness / Waiting Time - allow an equal amount of time for
each process.

U
UNN II F
FEE II
microkernel(3);

//second implementation
//circular buffer and struct added
kernel_example(3.2);
Scheduler

• First in first out


• Shortest remaining time
• Fixed priority pre-emptive scheduling
• Round-robin scheduling
• Multilevel queue scheduling

U
UNN II F
FEE II
Scheduler

Scheduling algorithm CPU Through Turnaround Response


Overhead put time time

First In First Out Low Low High Low

Shortest Job First Medium High Medium Medium

Priority based Medium Low High High


scheduling

Round-robin High Medium Medium High


scheduling
Multilevel Queue High High Medium Medium
scheduling

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

• Considerations for the embedded environment


 With the scarcity of computational resources, a very
complex algorithm can undermine the processing
capacity very quickly. Simpler algorithms are preferred.
 Real-time systems have some needs that are usually only
met by "unfair" schedulers that can privilege some
processes.
• Ex: priority based 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:

• When n tends to infinite U must be less than 69,3%

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);

• The only struct field is the function pointer. Other


fields will be added latter.
• The circular buffer open a new possibility:
 A process now can state if it wants to be rescheduled or
if it is a one-time run process
 In order to implement this every process must return a
code.
 This code also says if there was any error in the process
execution

U
UNN II F
FEE II
Exemplo

• Cooperative kernel example


 The presented code can be compiled in any C compiler
• The kernel consists of three functions:
 KernelInit (): Initializes internal variables
 KernelAddProc (): Adds processes in the pool
 KernelLoop (): Initializes the process manager
• This function has an infinite loop because it only needs to be
terminated when the equipment / board is switched off.

U
UNN II F
FEE II
microkernel(3);

//return code
#define SUCCESS 0
#define FAIL 1
#define REPEAT 2

//function pointer declaration


typedef char(*ptrFunc)(void);

//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);

• Presenting the new processes


void tst1(void){
printf("Process 1\n");
return REPEAT;
}
void tst2(void){
printf("Process 2\n");
return SUCCESS;
}
void tst3(void){
printf("Process 3\n");
return REPEAT;
U }
UNN II F
FEE II
Exemplo
void main(void){
//declaring the processes
process p1 = {tst1};
process p2 = {tst2};
process p3 = {tst3};
kernelInit();
//Test if the process was added successfully
if (kernelAddProc(&p1) == SUCCESS){
printf("1st process added\n");}
if (kernelAddProc(&p2) == SUCCESS){
printf("2nd process added\n");}
if (kernelAddProc(&p3) == SUCCESS){
printf("3rd process added\n");}
kernelLoop();
}
Exemplo
Console Output:
---------------------------
1st process added
2nd process added
3rd process added
Ite. 0, Slot. 0: Process 1
Ite. 1, Slot. 1: Process 2
Ite. 2, Slot. 2: Process 3
Ite. 3, Slot. 3: Process 1
Ite. 4, Slot. 0: Process 3
Ite. 5, Slot. 1: Process 1
Ite. 6, Slot. 2: Process 3
Ite. 7, Slot. 3: Process 1
Ite. 8, Slot. 0: Process 3
...
---------------------------
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

• Create kernel.c, kernel.h.


• Adapt the source code to run on the board.
• Test processes reeschedule.
• Create one process to blink led 1 (PORTD).
• Create a second process to blink led 2 (PORTD).
• Create a third process to blink led 3 (PORTD).

U
UNN II F
FEE II

You might also like