ELT048 - SOE



        Processos

       Rodrigo Almeida
Universidade Federal de Itajubá
Revisão
●   Ponteiros de função
●   Engine de processamento
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
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;
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);
    }

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

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

}
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();
}
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.
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.
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
  }
}
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?
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?
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.
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
    }
  }
}
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
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.
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
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
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
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.
Processo
typedef int (*ptrFunc)(void* param);

//código antigo
typedef struct {
  char* nomeDoProcesso;
  ptrFunc funcao;
  int prioridade;
  int tempo;
}process;
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.

Definição de processos

  • 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çãode “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çãode 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çãode “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 mapade 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 – Loopinfinito //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 //processopara 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ãodas 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ãodas 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ãodas 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.