Baixe o app para aproveitar ainda mais
Prévia do material em texto
Scheduler Isolation 1st Daniel Alfredo Herrera Marroquı́n Engenharia Mecatrônica Universidade Federal de Santa Catarina (UFSC) Joinville, Brasil daniel1 aamcc@hotmail.com 2nd Daniel Stringari Engenharia Mecatrônica Universidade Federal de Santa Catarina (UFSC) Jaraguá do sul, Brasil daniel.stringari@grad.ufsc.br I. INTRODUÇÃO Este relatório tem como objetivo principal, descrever o desenvolvimento do primeiro trabalho prático da disciplina de Sistemas de Tempo Real (EMB5633). O trabalho consiste na implementação de um escalonador, modificando o sistema de gerenciamento de threads já existente na versão do EPOS disponı́vel na disciplina. A implementação utilizando um escalonador, torna o processo mais genérico e reduz o atraso causado por JITTER. II. TAREFA A versão didática do OpenEPOS implementa o escalonamento de threads como uma propriedade dos mecanismos de gerenciamento de processos. Esta é na verdade a maneira como a maioria dos sistemas operacionais o implementa, mas, em essência, as polı́ticas e mecanismos de escalonamento podem ser reutilizadas para disco, rede e outros recursos do sistema. A motivação principal do EPOS em isolar o escalonador é a possibilidade de implementá-lo no hardware e, assim, reduzir o JITTER para tarefas HARD em tempo real. No entanto, essa refatoração provou ser uma maneira muito eficaz de praticar técnicas avançadas de desenvolvimento de software e obter uma visão do DESIGN em nı́vel de sistema. Perguntas: 1) Quais são as polı́ticas implementadas pelo escalonador multinı́vel original? Qual é a polı́tica entre nı́veis? E o que é intra-nı́vel? Resposta: O escalonador original executa as threads de acordo com as que estão na fila, trabalhando de certa forma, similar a polı́tica Firts In Firts Served. Isso significa que quem chega primeiro, vai ser executado por primeiro na fila de Ready. 2) Como é que o EPOS implementa um escalonador multinı́vel com um único Ready Queue ? Resposta: Criando um ponteiro para a thread que está executando, para posteriormente utilizar a fila e trocar a thread em execução com outras threads que estão na fila. 3) Você poderia implementar outras polı́ticas usando a mesma estratégia? Resposta: Talvez polı́ticas mais simples de escalonamento estático. Uma polı́tica de tempo real não seria possı́vel, pois, as threads não possuem um campo de deadline, já impossibilitando a implementação de um sistema de tempo real III. SOLUÇÃO TEÓRICA PROPOSTA A versão disponibilizada na disciplina conta com um sistema de gerenciamento de threads utilizando filas de prontos e suspensos. Esta implementação torna ao sistema operacional pouco genérico e com uma alta quantidade de JITTER. Para resolver este problema, mediante análise Gracioli et. al, foi proposto a criação de uma classe chamada Escalonador e outra Priority, que se relacionam ao mesmo tempo com a classe Thread, já existente. A. class scheduler A classe escalonador gerencia todas a Threads, utiliza uma lista do tipo Scheduling List, que é justamente projetada para esta tarefa. Dentro da lista são armazenadas as Threads com o tipo de polı́tica de escalonamento definida pelo usuário, além disso existe um elemento fora da lista, com nome CHOSSEN, que corresponde à célula que armazena a Thread que está sendo executado atualmente pelo processador. Isso possibilita que apenas a lista contenha as threads prontos para ser executados e não o atual. B. class priority Gerencia a prioridade do escalonamento das Threads e assim como a polı́tica de escalonamento utilizada no sistema como um todo. Nesta classe, pode ser escolhido se o método será preemptivo ou não. C. class Thread Classe já existente no EPOS, mas que teve modificações para trabalhar com um escalonador genérico. Uma modificação significante foi a troca das filas de textit ready e textit running pela classe escalonador. Na figura 1 é mostrada um esquema do gerenciamento das classes Thread, shceduler e Priority. Fig. 1. Diagrama de Classes IV. IMPLEMENTAÇÃO Para entender melhor o funcionamento geral do sistema pode se observar a figura 1. A lista contém todas as threads, organizadas pela polı́tica de escalonamento definida na classe Priority. A célula que contém o elemento que está sendo executado atualmente pelo processador é designado por CHOSSEN. Cada vez que é preciso delegar a CPU de um processo a outro, a thread que está no final da lista passa a ser o elemento choosen, e o elemento choosen passa ser inserido na fila de threads prontas, caso não for suspenso pelo método sleep(). Essa troca é feita pelo método dispatch ( Thread *READY, Thread *RUNNING), que faz a troca de contexto da CPU. O código pode ser apreciado na seção de anexos Fig. 2. Escalonador DIFICULDADES Uma grande dificuldade foi a utilização da lista fornecida pelo EPOS, por causa do elemento choosen, mas que no final tornou o processo do controle de acesso à CPU muito mais simples. Outra dificuldade foi entender o motivo da sobrecarga do operador () para a classe priority. E por último a maior dificuldade foi como ligar a classe priority com a classe Thread, esta ligação foi feita no arquivo Traits.h, onde alguns parâmetros da thread são inicializados. CONCLUSÕES Por fim, conclui-se que a atividade foi enriquecedora, acrescentando aos alunos experiência no desenvolvimento de algoritmos de controle de processos. O escalonador de processos foi desenvolvido com relativo sucesso, tendo alguma falhas no controle de processos. REFERENCES [1] G. Gracioli, A. A. Fröhlich, R. Pellizzoni and S. Fischmeister, “Implementation and evaluation of global and partitioned scheduling in a real-time OS” Springer Science, pp. 669–714, 2013. [2] G. Gracioli, ”Real-Time Operating System Support for Multicore Applications”, Florianópolis: Federal University of Santa Catarina, 359 pages, 2014 (Ph.D. Thesis). ANEXOS 1 2 template <typename T> 3 class scheduler: Scheduling_List<T,typename T::Criterion> 4 { 5 public: 6 typedef Scheduling_List<T,typename T::Criterion> List; 7 typedef typename List::Element Element; 8 9 scheduler() 10 { 11 12 } 13 ˜scheduler() 14 { 15 16 } 17 void insert(T *elemento) 18 { 19 List::insert(elemento->link()); 20 } 21 T* remove(T* elemento) 22 { 23 24 if(List::remove(elemento->link())) 25 { 26 return elemento; 27 } 28 else 29 { 30 return 0; 31 } 32 } 33 void resume(T * elemento) 34 { 35 insert(elemento); 36 } 37 void suspend(T *elemento) 38 { 39 remove(elemento); 40 } 41 42 T * volatile chosen() { 43 T * volatile o = List::chosen()->object(); 44 return o; 45 } 46 47 48 49 T* chosse() 50 { 51 52 T *auxi= List::choose()->object(); 53 return auxi; 54 } 55 T* chosse_another() 56 { 57 58 return List::choose_another()->object();// choose_another 59 } 60 T chosse(T elemento) 61 { 62 return List::choose_another(elemento)->object(); 63 } 64 volatile unsigned int num_of_threads; 65 protected: Listing 1. Classe SCHEDULER
Compartilhar