Buffer circular de processos com ponteiros de função
1. ELT048 - SOE
Processos
Rodrigo Almeida
Universidade Federal de Itajubá
2. Revisão
● Ponteiros de função
● Engine de processamento
3. Exercício
● Modifique a estrutura apresentada
anteriormente para incluir também um
ponteiro de função.
● Crie uma função que executa o ponteiro de
função armazenado na “primeira” posição
do buffer circular.
● Crie um main que adicione 3 elementos no
buffer e execute cada um deles na ordem
que foram inseridos.
● Add(x3), exec, remove, exec, remove, exec, remove
4. Exercício
typedef int (*ptrFunc)(void* param);
//definição da estrutura
typedef struct {
char tipo;
void* ptr;
ptrFunc func;
}process;
//definição do buffer circular
#define BUFFERSIZE 10
process buffer[BUFFERSIZE];
//definição dos “ponteiros” de acesso
int ini, fim;
5. Exercício
//função de adição de “process” no buffer
void addProc(process nProcesso){
//checagem de espaço disponível
if ( ((fim+1)%BUFFERSIZE) != ini){
//Atualização da posição atual
buffer[fim] = nProcesso;
//incremento da posição
fim = (fim+1)%(BUFFERSIZE);
}
}
6. Exercício
//função de remoção de um “process” do buffer
void removeProc (void){
//checagem se existe alguem pra retirar
if ( ini != fim){
//incremento da posição
ini = (ini+1)%(BUFFERSIZE);
}
}
7. Exercício
//função de adição de “process” no buffer
void exec(void){
//checar se existe alguem para ser executado
if (ini != fim){
//execução da função passando ptr como
parâmetro
buffer[ini].func(0);
}
}
8. Exercício
#include “stdio.h”
void main (void){
process p1 = {"",0,func1};
process p2 = {"",0,func2};
process p3 = {"",0,func3};
ini = 0;
fim = 0;
addProc(p1);
addProc(p2);
addProc(p3);
exec();
removeProc();
exec();
removeProc();
exec();
removeProc();
}
9. Processo
● Um processo é
composto por uma
unidade de código
que pode ser
executada, uma
região delimitada de
memória e um
conjunto de
informações sobre
seu estado atual.
10. Processo
● A implementação de um processo é muito
dependente do tipo de kernel utilizado e
das interfaces disponíveis ao programador.
● O processo mais simples pode ser
representado por uma função.
11. Processo
//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
}
}
12. Processo
● Como fazer para que o processo continue
executando?
● Re-executar a função?
● Fazer um loop interno com n repetições
● Fazer um loop infinito?
13. Processo
● Como fazer para que o processo continue
executando?
● Antes é preciso saber:
● Que tipo de kernel está rodando: preemptivo ou
cooperativo?
● Existe um escalonador temporal?
14. Processo
● Loop infinito: Só deve ser usado se o kernel
for capaz de interromper o processo ou se
este for o único processo do sistema.
● No último caso não faz sentido ter um kernel.
15. Processo – Loop infinito
//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
}
}
}
16. Processo
● Re-execução da função: permite que o
processo deixe tempo livre para o kernel
executar outras funções. Deve ser utilizado
no kernel cooperativo.
● Quando possível omite-se as rotinas de
tempo/delay deixando a cargo do kernel.
● Deste modo o sistema pode realizar alguma
tarefa mais útil
17. Processo – Reexecução
//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.
18. Processo – Reexecução
//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
19. Processo – Reexecução
//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
20. Processo – Reexecução
//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
21. Processo
● Como citado o processo é, a principio, uma
função que deve ser executada quando o
processo é chamado.
● Além disto existem diversas informações
importantes que devem ser agregadas para
que o processo seja gerenciavel
● Prioridade, tempo de execução, nome, região
de memória reservada etc.
● Em geral é utilizado uma estrutura para
agregar todas estas informações.
22. Processo
typedef int (*ptrFunc)(void* param);
//código antigo
typedef struct {
char* nomeDoProcesso;
ptrFunc funcao;
int prioridade;
int tempo;
}process;
23. Exercício
● Adaptar o código e executá-lo no kit de
desenvolvimento.
● Reunir todas as funções relacionadas à
operação com o buffer circular numa
biblioteca.
● Utilizar o debugger da placa para verificar o
funcionamento do programa.