Qual o principal problema encontrado nas principais estratégias de alocação de arquivos?

O slideshow foi denunciado.

Seu SlideShare está sendo baixado. ×

Notas de aula da disciplina Sistemas Operacionais ministrada no curso de Sistemas de Informação da PUC Campinas.

Qual o principal problema encontrado nas principais estratégias de alocação de arquivos?

Notas de aula da disciplina Sistemas Operacionais ministrada no curso de Sistemas de Informação da PUC Campinas.

Mais Conteúdo rRelacionado

  1. 1. Sistemas de Informação Sistemas Operacionais Daniel Paz de Araújo
  2. 2. 1. Introdução
  3. 3. 1.1 Conceito básico Em torno de um computador existem usuários com problemas para serem resolvidos, por programas específicos. Para um melhor aproveitamento do hardware, vários usuários compartilham simultaneamente o computador. Os programas podem apresentar necessidades conflitantes, pois disputam os recursos do equipamento. Exemplo: disco, memória, impressora.
  4. 4. 1.1 Conceito básico O S.O. é uma camada de software colocada entre o hardware e os programas que executam tarefas para os usuários. É responsável pelo acesso aos periféricos; sempre que um programa necessita de algum tipo de operação de entrada e saída. Como todos os acessos aos periféricos são feitos através do sistema operacional, ele pode controlar qual programa está acessando qual recurso. É possível, então, obter uma distribuição justa e eficiente de recursos.
  5. 5. 1.1 Conceito Básico Figura 1.1: Sistema Operacional
  6. 6. 1.2 Objetivos do sistema operacional O sistema operacional procura tornar a utilização do computador, ao mesmo temo, mais eficiente e mais conveniente. Maior eficiência significa mais trabalho obtido no mesmo hardware, através da distribuição de seus recursos entre os programas. Exemplo: espaço na memória, tempo de processador, impressora, espaço em disco, etc. Maior conveniência significa diminuir o tempo necessário para a construção dos programas, escondendo-se do programador detalhes do hardware. Exemplo: tipos de interface, acesso a periféricos, etc.
  7. 7. 1.2.1 Tipos de serviços Execução de programas: o sistema operacional recebe o nome do arquivo, aloca memória para o programa, copia o conteúdo para a memória principal e inicia sua execução. Armazenamento de arquivos: permite a criação, escrita, leitura e exclusão de arquivos, além de operações como renomear, obter o tamanho, data de criação e outras informações a seu respeito. Acesso a periféricos: alocação, leitura, escrita e liberação, além de obtenção e alteração de informações a seu respeito.
  8. 8. 1.2.1 Tipos de serviços À medida que diversos usuários compartilham o computador, passa a ser interessante saber quanto de mais recurso cada usuário necessita. Pode-se utilizar essa informação para calcular o valor a ser cobrado pelo uso do computador. Na busca de um melhor aproveitamento do hardware, diversos usuários podem compartilhar um computador. Cabe ao sistema operacional garantir que cada usuário possa trabalhar sem sofrer interferência danosa dos demais.
  9. 9. 1.3 S.O. na visão do usuário A arquitetura de um sistema operacional corresponde à imagem que o usuário tem do sistema, a forma como ele percebe o sistema. Essa imagem é definida pela interface através da qual o usuário acessa os serviços do sistema operacional. Essa interface, assim como a imagem, é formada pelas chamadas de sistemas e pelos programas de sistema.
  10. 10. 1.3.1 Chamadas de sistema Os programas solicitam serviços ao sistema operacional através das chamadas de sistema. Elas são semelhantes às chamadas de sub-rotinas, contudo enquanto estas são transferências para procedimentos normais do programa, as chamadas de sistema transferem a execução para o sistema operacional. Através de parâmetros, o programa informa exatamente o que necessita e o retorno da chamada de sistema, assim como retorno de uma sub-rotina, faz com que a execução do programa seja retomada a partir da instrução que segue a chamada. Exemplo: abertura de um arquivo.
  11. 11. 1.3.1 Chamadas de sistema A parte do sistema operacional responsável por implementar as chamadas de sistema é normalmente chamada de núcleo ou kernel. Os principais componentes do kernel são a gerência de processador, a gerência de memória, o sistema de arquivos e a gerência de entrada e saída. Muitos sistemas operacionais são implementados em camadas, primeiro um componente de software chamado micronúcleo ou microkernel implementa os serviços mais básicos associados a sistemas operacionais. Em cima do microkernel, usando seus serviços, o kernel propriamente dito implementa os demais serviços.
  12. 12. 1.3.1 Chamadas de sistema Figura 1.2: Organização do sistema em kernel e microkernel
  13. 13. 1.3.2 Programas de sistema Os programas de sistema, alguma vezes chamados de utilitários, são programas normais executados fora do kernel do sistema operacional. Esses programas implementam tarefas básicas para a utilização do sistema e muitas vezes são confundidos com o próprio sistema operacional. Como implementam tarefas essenciais para a utilização do computador, são, em geral, distribuídos pelo próprio fornecedor do sistema operacional. Exemplos são os utilitários para manipulação de arquivos: programas para listar arquivo, imprimir, copiar, renomear, listar conteúdo de diretório, entre outros.
  14. 14. 1.3.2 Programas de sistema O mais importante programa de sistema é o interpretador de comandos. Sua tarefa é receber comandos do usuário e executá-los. Para isso ele recebe as linhas tecladas pelo usuário, analisa seu conteúdo e executa o comando teclado. A execução do comando, na maioria das vezes, vai exigir uma ou mais chamadas de sistema. Exemplo: listagem de diretório
  15. 15. 1.3.2 Programas de sistema Os mesmos conceitos sobre o interpretador de comandos é igualmente válido para a situação em que o sistema operacional oferece uma interface gráfica de usuário (GUI - graphical user interface). A única diferença está na comodidade para o usuário, que passa a usar ícones, menus e mouse no lugar de digitar comandos textuais. Programadores utilizam principalmente editores de texto e compiladores. Usuários finais utilizam aplicativos e ferramentas de apoio. O sistema operacional propriamente dito fica escondido, longe da percepção do usuário comum.
  16. 16. 1.4 S.O. na visão de projeto Na visão de projeto, o mais importante é como o sistema está organizado internamente. A organização de um sistema operacional corresponde à forma como ele implementa os vários serviços. Dois tipos de eventos ativam o sistema operacional: uma chamada de sistema ou uma interrupção de periférico. É possível que a chamada de sistema envolva o acesso a um periférico. Nesse caso, o programa deverá esperar até que o periférico conclua a operação solicitada.
  17. 17. 1.4 S.O. na visão de projeto Em função das chamadas de sistema, o sistema operacional envia comandos para os controladores dos periféricos. O controlador deve informar ao sistema operacional quando a operação estiver concluída. Isso é feito por intermédio de uma interrupção, quando o processador para o que está fazendo e passa a executar uma rotina específica do sistema operacional. Como a interrupção do periférico avisa o término de alguma operação de entrada e saída, possivelmente uma chamada de sistema foi concluída. Nesse caso, um programa à espera de resposta poderá ser liberado.
  18. 18. 1.5 Histórico de sistemas operacionais Na década de 1940 não existia sistema operacional. O programador também é o operador do computador. Um programa tem total controle sobre a máquina, e acessa diretamente os periféricos. No máximo, existe uma biblioteca com rotinas de entrada e saída já programadas. Começou-se a utilizar operadores profissionais, assim o programador não mais opera o computador durante a execução de seu programa. Ele entrega ao operador o seu job.
  19. 19. 1.5 Histórico de sistemas operacionais Entretanto, o tempo de preparação para a execução de um job continua grande. É necessário retirar as fitas magnéticas, cartões de listagem do job que terminou e preparar o próximo. Para diminuir esse tempo entre jobs, eles passam a ser agrupados em lotes. Em um mesmo lote, ou batch, são colocados jobs com necessidades semelhantes. Essa é a origem do termo sistema em batch. Um mesmo job pode exigir a execução de vários programas. Cada uma dessas etapas é chamada de step.
  20. 20. 1.5 Histórico de sistemas operacionais Na década de 1950 surgiram os primeiros monitores residentes. O monitor residente é um tipo de programa que fica o tempo todo na memória. Quando um programa em execução termina, ele avisa o monitor que então, carrega automaticamente o próximo programa e inicia a execução dele. O monitor residente também é o local indicado para as rotinas de acesso aos periféricos, e são utilizadas por todos os programas. Desta forma as aplicações não precisam mais acessar diretamente os periféricos, apenas chamar a rotina apropriada dentro do monitor. Esse é o início da ideia de chamada de sistema.
  21. 21. 1.5 Histórico de sistemas operacionais Na década de 1960 surgiu o conceito de multiprogramação. Em geral, periféricos são dispositivos eletromecânicos e trabalham na faixa de milissegundo. Ao mesmo tempo, o processador é um dispositivo eletrônico, que trabalha na faixa de microssegundo. Por exemplo, enquanto é feito um único acesso à leitora de cartões, poderiam ser executadas 10.000 instruções de máquina ou mais. A solução imaginada foi manter diversos programas na memória principal ao mesmo tempo. Quando um dos programas está esperando a conclusão da entrada ou saída, outro programa inicia sua execução.
  22. 22. 1.5 Histórico de sistemas operacionais Duas inovações de hardware possibilitaram o desenvolvimento da multiprogramação. Interrupções: quando um comando é enviado para um periférico, imediatamente o sistema operacional inicia a execução de outro programa. É através de uma interrupção que o periférico avisa o sistema operacional quando o acesso tiver sido concluído. Pode-se fazer com que o processador fique em um laço, consultando a interface do periférico, até que a operação esteja concluída.
  23. 23. 1.5 Histórico de sistemas operacionais Discos magnéticos: vários jobs são lidos de cartão perfurado ou fita magnética para o disco. Como o disco permite acesso direto a qualquer posição, é possível ler parte do primeiro job e do segundo job. À medida que, em sua função de execução, um job solicita a leitura de mais dados, eles são buscados no disco. Com a utilização de disco magnético, não havia mais a necessidade de reunir jobs semelhantes em lotes. O termo batch passou então a designar um sistema no qual não existe interação entre o usuário e a execução do programa. Mais modernamente o termo batch foi substituído por "execução em background".
  24. 24. 1.5 Histórico de sistemas operacionais Na década de 1970 ocorreu a disseminação de sistemas timesharing. Em um ambiente com multiprogramação, diversos programas dividem o tempo do processador. Em um ambiente de timesharing, além da multipogramação, cada usuário possui um terminal onde ele interage com o programa em execução tendo a sensação de possuir o computador apenas para seus programas.
  25. 25. 1.5 Histórico de sistemas operacionais Na década de 1980 houve uma enorme disponibilidade de microcomputadores. No início, os sistemas operacionais para microcomputadores eram bastante simples, lembrando até o velho monitor residente. À medida que o hardware dessas máquinas foi melhorado, o mesmo aconteceu com o sistema operacional.
  26. 26. 1.5 Histórico de sistemas operacionais A maioria das aplicações comerciais é hoje construída em torno de bancos de dados. Ainda que a maioria dos sistemas gerenciadores de bancos de dados sejam implementados fora do sistema operacional, este deve oferecer algum suporte. Em um sistema operacional distribuído, vários computadores estão interconectados por meio de uma rede de comunicação de algum tipo. É possível, a partir de um dos computadores, acessar recursos em outros.
  27. 27. 1.5 Histórico de sistemas operacionais Os sistemas operacionais de tempo real, são usados no suporte às aplicações submetidas a requisitos de natureza temporal. Nesses sistemas, os resultados devem estar corretos e não somente do ponto de vista lógico, mas também devem ser gerados no momento correto. Exemplo: lavadoras de roupa, tráfego aéreo. À medida que são desenvolvidos computadores com diversos processadores, passa a ser necessário rever aspectos básicos dos sistemas operacionals. Por exemplo, agora existe um paralelismo real a ser aproveitado. diversos programas podem ser executados realmente em paralelo, mas nem todos os processadores possuem acesso a toda a memória.
  28. 28. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  29. 29. 2. Multiprogramação
  30. 30. 2.1 Mecanismo básico Em um sistema multiprogramado diversos programas são mantidos na memória ao mesmo tempo. A maioria dos programas não precisa de toda a memória do computador. Muitos programas ocupam uma pequena parcela da memória principal disponível. Sem multiprogramação, a memória não ocupada por um programa ficaria sem utilização. Com vários programas na memória, esse recurso é mais bem aproveitado.
  31. 31. 2.1 Mecanismo básico Figura 2.1: Memória em um sistema com multiprogramação
  32. 32. 2.2 O conceito de processo Em sistemas operacionais é conveniente diferenciar um programa de sua execução. Por exemplo, o mesmo programa pode estar sendo executado por vários usuários ao mesmo tempo. Na maioria das vezes, um processo é definido como "um programa em execução". Um programa é uma sequência de instruções e é passivo dentro do sistema, não alterando o próprio estado. O processo é um elemento ativo que altera o seu estado, à medida que executa um programa. É o processo que faz chamadas de sistema ao executar programas.
  33. 33. 2.3 Ciclos de um processo Processos são criados e destruídos, porém o momento e a forma com que isso ocorre depende do sistema operacional. Algum sistemas trabalham com um número fixo de processo, sendo criados na inicialização do sistema e destruídos quando o mesmo é desligado. Outra forma é sua associação com uma sessão de trabalho, criando processos no momento do acesso do usuário ao sistema e destruindo-os quando é executada o final da sessão.
  34. 34. 2.3 Ciclos de um processo A forma mais flexível de operação é permitir que os processos possam ser criados livremente, através de chamadas do sistema. Além da chamada de sistema "cria processo", serão necessárias chamadas para "autodestruição do processo"e também para a "eliminação de outro processo". A maioria dos processos de um sistema executa programas do usuário. Entretando alguns podem realizar tarefas de sistemas. São processos do sistema (daemon).
  35. 35. 2.3 Ciclos de um processo Por exemplo, para evitar conflitos na utilização da impressora, muitos sistemas trabalham com uma técnica chamada spooling. Para imprimir um arquivo, o processo de usuário deve colocá-lo em um diretório especial. Um processo do sistema copia os arquivos desse diretório para a impressora. Dessa forma, um processo de usuário nunca precisa esperar a impressora ficar livre, uma vez que ele não envia os dados para a impressora, mas sim para o disco. O processo que envia os dados para a impressora não está associado a nenhum usuário.
  36. 36. 2.3 Ciclos de um processo Após ter sido criado, o processo passa a ocupar o processador. Em determinados momentos, ele deixa de fazer isso para realizar uma operação de E/S. Os momentos em que um processo deseja ocupar o processador, são chamados de ciclos de processador. Quando o processo está esperando por uma operação de E/S, ele está em um ciclo de E/S. A chamada de sistema é o evento que termina o ciclo de processador em andamento e inicia um ciclo de E/S. A conclusão da chamada de sistema faz o caminho inverso.
  37. 37. 2.3 Ciclos de um processo Um processo que utiliza muito processador é chamado de cpu-bound. O seu tempo de execução é definido principalmente pelo tempo dos seus ciclos de processador. Por outro lado, um processo que utiliza muita E/S é chamado de i/o-bound (input/output-bound). Nesse caso, o tempo de execução é definido principalmente pela duração das operações de E/S. Não existe uma quantificação precisa para essas definições.
  38. 38. 2.4 Relacionamento entre processos Alguns sistemas suportam o conceito de grupos de processos. Se processos são criados através de chamada de sistema, pode-se considerar como pertencentes ao mesmo grupo todos os processos criados pelo mesmo processo. O conceito de grupo permite que operações possam ser aplicadas sobre todo um conjunto de processos, e não apenas sobre processos individuais. Por exemplo, os processos pertencentes a um mesmo grupo podem compartilhar os mesmos direitos perante o sistema.
  39. 39. 2.4 Relacionamento entre processos Em muitos sistemas os processos são criados por outros processos, pelas chamadas de sistema. Nesse caso, é possível definir uma hierarquia de processos. O processo que faz a chamada de sistema é chamado de processo pai, enquanto o processo criado é chamado de processo filho. Um mesmo processo pai pode estar associado a vários processos filhos. Os processos filhos, por sua vez, podem criar outros processos.
  40. 40. 2.4 Relacionamento entre processos Figura 2.2: Hierarquia de processos
  41. 41. 2.4 Relacionamento entre processos À medida que processos são criados e destruídos, nodos são acrescentados ou removidos da árvore, respectivamente. O sistema pode definir, por exemplo, o que fazer quando um processo com filhos é destruído. Pode-se definir que, quando um processo é destruído, todos os processos que derivam dele também são destruídos. Outra solução é manter o nodo que representa o processo destruído, até que todos os seus descendentes também terminem. Uma terceira solução é vincular os processos que são filhos do processo destruído com o processo pai daquele, isto é, com o "processo avô" deles.
  42. 42. 2.5 Estados de um processo Em máquinas multiprocessadoras existem diversos processadores. Nesse caso, diversos processos executam ao mesmo tempo. Porém, essa não é a situação mais comum. Vamos supor que existe um único processador no computador. Nesse caso é necessário manter uma fila com os processos aptos a ganhar o processador. Essa fila é chamada "fila de aptos" (ready queue).
  43. 43. 2.5 Estados de um processo A figura 2.3 ilustra essa situação. O processo 1 ocupa o processador, enquanto os processos 2 e 3 esperam na fila de aptos. Os processos na fila do processador estão em estado de apto (ready). Um único processo ocupa o processador a cada instante. O processo que ocupa o processador está no estado executando (running). Na figura, o processo 1 está no estado executando, enquanto os processos 2 e 3 estão no estado apto.
  44. 44. 2.5 Estados de um processo Figura 2.3: Fila de processos esperando pelo processador
  45. 45. 2.5 Estados de um processo A figura 2.4 mostra o diagrama de estados de um processo. No estado executando, um processo pode fazer chamadas de sistema. Até a chamada de sistema ser atendida, o processo não pode continuar sua execução. Ele fica bloqueado e só volta a disputar o processador após a conclusão da chamada. Enquanto espera pelo término da chamada de sistema, o processo está no estado bloqueado (blocked).
  46. 46. 2.5 Estados de um processo Figura 2.4: Diagrama de estados de um processo
  47. 47. 2.5 Estados de um processo A mudança de estado de qualquer processo é iniciada por um evento. Esse evento aciona o sistema operacional, que, então, altera o estado de um ou mais processos. A transição de estado executando para bloqueado é feita através de uma chamada de sistema. Ele fica bloqueado até o atendimento e, com isso, o processador fica livre. O sistema operacional então seleciona um processo na fila de aptos para receber o processador e altera seu estado para executando. O módulo do sistema operacional que faz essa seleção é chamado escalonador (scheduler).
  48. 48. 2.5 Estados de um processo Algumas chamadas de sistema são muito rápidas. Por exemplo, a leitura da hora atual. Não existe acesso a periférico, mas apenas consulta à variáveis do próprio sistema operacional. Nesse caso, o processo não precisa voltar para a fila de aptos: ele simplesmente retorna para a execução após a conclusão de chamada, o que implica um caminho do estado bloqueado para o estado executando.
  49. 49. 2.5 Estados de um processo Muitos sistemas procuram evitar que um único processo monopolize a ocupação do processador. E um processo está há muito tempo no processador, ele volta para o fim da fila de aptos. Um novo processo da fila de aptos ganha o processador e assim cada processo tem a chance de executar um pouco. Esse mecanismo cria um caminho entre o estado executando e o estado apto (a figura 2.5 mostra o grafo de estados dos processos com esses novos caminhos).
  50. 50. 2.5 Estados de um processo Figura 2.5: Novo diagrama de estados de um processo
  51. 51. 2.6 Gerência de filas O tempo de acesso a um periférico é muito grande se comparado aos tempos de processador. Se houver mais de uma solicitação for para o mesmo periférico, não é possível enviar o comando imediatamente, pois a maioria dos controladores de periféricos não suporta dois comandos simultâneos. O segundo processo terá que esperar o periférico ficar livre. De qualquer maneira, o processador ficou livre; um terceiro processo será retirado da fila de aptos e passará a ocupar o processador.
  52. 52. 2.6 Gerência de filas Quando uma solicitação é feita, é preciso verificar a fila do periférico. Se ela estiver vazia, o periférico está livre. O pedido é inserido na fila, e o comando é enviado para o controlador. Caso contrário, o periférico está ocupado e o pedido é inserido na fila, mas nada é enviado ao controlador.
  53. 53. 2.6 Gerência de filas A figura 2.6 ilustra um momento específico dentro do sistema. ● O processo 1 está executando. Na fila de aptos, esperando pelo processador, estão os processos 2 e 3. ● A impressora está livre. ● Existe um acesso em andamento na unidade de disco 0, feito pelo processo 4. ● O processo 5 também solicitou um acesso à unidade 0, mas deve esperar a conclusão do pedido em andamento. ● Os processos 4 e 5 estão bloqueados, ou seja, não disputam processador. ● A unidade de disco 1 está sendo acessada em função de um pedido do processo 6.
  54. 54. 2.6 Gerência de filas Figura 2.6: Filas do sistema operacional
  55. 55. 2.7 Mecanismo de interrupções O mecanismo de interrupções é um recurso comum dos processadores de qualquer porte. Ele permite que um controlador de periférico chame a atenção do processador. Analogia entre as interrupções de hardware e o telefone. Uma interrupção sempre sinaliza a ocorrência de algum evento. Quando ela acontece, desvia a execução da posição atual de programa para uma rotina específica. Essa rotina, responsável por atender a interrupção, é chamada de tratador de interrupção.
  56. 56. 2.7 Mecanismo de interrupções Para que a execução do programa interrompido não seja comprometida pela interrupção, é necessário que nenhum registrador seja alterado. Alguns processadores salvam automaticamente todos os registradores quando ocorre uma interrupção; outros, salvam apenas alguns, cabendo à rotina que atende à interrupção salvar os demais registradores. O local mais indicado é a pilha de execução. É usual o processador dispor de uma instrução tipo retorno de interrupção que repõe o conteúdo original dos registradores e faz o processador retomar a execução do programa interrompido.
  57. 57. 2.7 Mecanismo de interrupções A função básica de um controlador de periférico é conectar o dispositivo em questão com o processador. Através do barramento, o processador é capaz de realizar operações do tipo "lê dados", "escreve dados", "reinicializa", "lê status" e "escreve comando". O controlador é responsável por traduzir essas operações em uma sequência de acionamentos eletrônicos, elétricos e mecânicos capazes de realizar a operação solicitada. Para isso, o controlador deve saber como o periférico funciona. Daí resulta que cada tipo de periférico necessita de um controlador diferente.
  58. 58. 2.7 Mecanismo de interrupções A figura 2.7 mostra o diagrama de tempo resultante quando interrupções são empregadas para implementar E/S. Após enviar o comando para o controlador, o processador segue a execução do programa. Quando a operação é concluída, o controlador gera uma interrupção. O processador, então, lê os resultados do controlador.
  59. 59. 2.7 Mecanismo de interrupções Figura 2.7: Linha de tempo quando interrupção é usada para implementar E/S
  60. 60. 2.7 Mecanismo de interrupções A forma mais simples de identificar a origem de uma interrupção é associar a cada controlador um tipo diferente de interrupção. Dessa forma, o controlador não somente interrompe o processador, mas também informa qual o tipo de interrupção. A maioria dos processadores admite diversos tipos de interrupções. Cada tipo de interrupção é identificado por um número. Por exemplo, de 0 (zero) a 255.
  61. 61. 2.7 Mecanismo de interrupções Existem momentos em que um programa não pode ser interrompido. Por exemplo, o programa pode estar alterando variáveis que também são acessadas pelo tratador de interrupções. A solução para esse problema é desligar o mecanismo de interrupções temporariamente, enquanto o programa realiza uma tarefa crítica que não pode ser interrompida. Os processadores normalmente possuem instruções para habilitar e desabilitar interrupções. Enquanto as interrupções estiverem desabilitadas, elas são ignoradas pelo processador. Elas não são perdidas, apenas ficam pendentes.
  62. 62. 2.7 Mecanismo de interrupções É comum a existência de uma relação de prioridades entre os diferentes tipos de interrupções. Vamos supor que um dado processador atribui prioridade decrescente do tipo 0 até o tipo 255. Nesse caso, quando ocorre uma interrupção tipo 10, o processador automaticamente desabilita interrupções dos tipos 10 a 255 até que o atendimento da interrupção tipo 10 tenha sido concluído. Caso ocorra, durante esse intervalo de tempo, uma interrupção do tipo 5, ela é imediatamente reconhecida pelo processador. Assim, o tratador de interrupção tipo 10 é interrompido e o tratador de interrupções tipo 5 ativado.
  63. 63. 2.7 Mecanismo de interrupções Figura 2.8: Ativação em cascata de tratadores de interrupção
  64. 64. 2.7 Mecanismo de interrupções O endereço de um tratador de interrupção é chamado de vetor de interrupção que "aponta" para a rotina de atendimento da mesma. Em geral, existe uma tabela na memória com todos os vetores de interrupção, ou seja, com os endereços das rotinas responsáveis por tratar os respectivos tipos de interrupção. A ocorrência de uma interrupção dispara no processador uma sequência de atendimento. Toda a sequência é executada pelo hardware, comandada pela unidade de controle do processador.
  65. 65. 2.7 Mecanismo de interrupções Figura 2.9: Tabela dos vetores de interrupção
  66. 66. 2.7 Mecanismo de interrupções Interrupções de software (traps) são causadas pela execução de uma instrução específica para isso, tendo como parâmetro o número da interrupção que deve ser ativada. O uso mais comum para interrupções de software é a implementação das chamadas de sistema, por meio das quais os programas de usuário solicitam serviços ao sistema operacional. O endereço armazenado nas tabelas de vetores de interrupção deve mudar conforme a versão do sistema operacional, que na sua inicialização fica encarregado de colocar os endereços certos na tabela.
  67. 67. 2.7 Mecanismo de interrupções As interrupções por erro, ou interrupções de exceção acontecem quando o processador detecta algum tipo de erro na execução do programa, como por exemplo, uma divisão por zero ou o acesso a uma posição de memória que na verdade não existe. O procedimento de atendimento a essa classe de interrupção é igual ao descrito anteriormente.
  68. 68. 2.8 Proteção entre processos Na multiprogramação, diversos processos compartilham o computador. É necessário que o sistema operacional ofereça proteção aos processos e garanta a utilização correta do sistema. Por exemplo, um processo de usuário não pode formatar o disco. Também não se pode permitir que um processo entre em um laço infinito e, com isso, monopolize a utilização do processador.
  69. 69. 2.8.1 Modos de operação do processador O sistema operacional é responsável por implementar uma proteção apropriada para o sistema e para isso, é necessário o auxílio do processador (hardware). A forma usual é definir dois modos de operação: 1. Modo usuário: algumas instruções não podem ser executadas. 2. Modo supervisor: não existem restrições, e qualquer instrução pode ser executada. Essas instruções são chamadas privilegiadas. Se um processo de usuário tentar executar uma instrução privilegiada, o hardware automaticamente gera uma interrupção e aciona o sistema operacional que poderá abortar o processo.
  70. 70. 2.8.2 Proteção dos periféricos Para proteger os periféricos, as instruções de E/S são tornadas privilegiadas. A única forma de o processo de usuário realizar uma operação de E/S é através de uma chamada de sistema. Muitas arquiteturas oferecem uma instrução chamada de interrupção de software ou trap, que quando executada, apresenta um efeito semelhante ao de uma interrupção por hardware, a única diferença sendo o fato de ter sido causada pelo software e não por um evento externo vinculado ao hardware. As interrupções geradas por software também chaveiam o processador para o modo supervisor.
  71. 71. 2.8.2 Proteção de periféricos Figura 2.10: Modos de operação do processador
  72. 72. 2.8.3 Proteção da memória Para implementar a proteção de memória, o sistema operacional também necessita de auxílio da arquitetura. Sempre que o sistema operacional vai disparar um processo de usuário, ele carrega nos registradores de limite os valores relativos ao processo que vai executar. Ele coloca no registrador limite inferior o endereço do primeiro byte pertencente à área de trabalho do processo e no registrador limite superior é colocado o endereço do último byte válido para a sua área. A cada acesso à memória, o hardware de proteção compara o endereço gerado pelo processador com o conteúdo dos dois registradores limite e se estiver fora da área do usuário, é gerada uma interrupção.
  73. 73. 2.8.3 Proteção da memória Figura 2.11: Proteção de memória com registradores de limite
  74. 74. 2.8.3 Proteção da memória Algumas arquiteturas fazem o acesso aos periféricos através de posições específicas da memória. Essa técnica é chamada de E/S mapeada na memória. Nesse caso, a proteção da memória também implementa a proteção dos periféricos. Basta colocar os endereços dos periféricos fora dos limites da área do processo. O processo não será capaz de acessar o periférico sem gerar uma interrupção. Obviamente, o acesso aos registradores de limite deve ser feito através de instruções privilegiadas. Somente o sistema operacional pode alterar o seu conteúdo.
  75. 75. 2.8.3 Proteção da memória Para evitar que um único processo de usuário monopolize a utilização do processador, é empregado um temporizador (timer), que é um relógio de tempo real, implementado pelo hardware, que gera interrupções de tempos em tempos. As interrupções do temporizador ativam o sistema operacional que então verifica se o processo executado já está há muito tempo com o processador. Nesse caso, o sistema pode abortar o processo por exceder o limite de tempo de execução. O controle do temporizador deve ser feito através de instruções privilegiadas.
  76. 76. 2.8.3 Proteção da memória Figura 2.12: Hardware para verificação dos endereços
  77. 77. 2.8.3 Proteção da memória Muitas arquiteturas não definem apenas dois modos de operação, mas vários. Em cada modo de operação, também chamado de nível de proteção, algumas operações não são permitidas. Quanto mais confiável o software, mais direitos ele recebe. Com auxílio do hardware e um sistema operacional sem falhas, é possível construir sistemas seguros, ou seja, sistemas nos quais não ocorram interferências danosas entre usuários.
  78. 78. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  79. 79. 3. Programação Concorrente
  80. 80. 3. Programação concorrente Um programa que é executado por apenas um processo é chamado de programa sequencial. Nesse caso, existem somente um fluxo de controle durante a execução. Um programa concorrente é executado simultaneamente por diversos processos que cooperam entre si, isso é, trocam informações, o que significa trocar dados ou realizar algum tipo de sincronização. É necessária a existência de interação entre processos para que o programa seja considerado concorrente. O termo "programação concorrente" vem do inglês concurrent programming, onde concurrent significa "acontecendo ao mesmo tempo" ou concomitantemente.
  81. 81. 3.1 Motivação Um programa concorrente pode apresentar todos os tipos de erros que normalmente aparecem em programas sequenciais. Além disso, existem os erros associados com as interações entre os processos. Mesmo com todas as suas complexidades inerentes, existem muitas áreas nas quais a programação concorrente é útil. Considere um programa que deve ler registros de um arquivo, colocar em um formato apropriado e então enviar para uma impressora física.
  82. 82. 3.1.1 Programa sequencial Figura 3.1: Programa sequencial acessando arquivo e impressora
  83. 83. 3.1.1 Programa sequencial Figura 3.2: Linha de tempo do programa sequencial da figura 3.1
  84. 84. 3.1.1 Programa sequencial Inicialmente, o processo envia um comando para a leitura do arquivo e fica bloqueado, o disco então é acionado para realizar a operação de leitura. Uma vez concluída a leitura, o processo realiza a formatação e inicia a transferência dos dados para a impressora. Observe o diagrama da figura 3.2, o disco e a impressora nunca trabalham simultaneamente, embora não exista nenhuma limitação de natureza eletrônica. O programa sequencial é que não consegue ocupar ambos.
  85. 85. 3.1.2 Programa concorrente Figura 3.3: Programa concorrente acessando arquivo e impressora
  86. 86. 3.1.2 Programa concorrente Figura 3.4: Linha de tempo do programa concorrente da figura 3.3
  87. 87. 3.1.2 Programa concorrente O programa concorrente é mais eficiente, pois consegue manter o disco e a impressora trabalhando simultaneamente. O tempo total para realizar a impressão do arquivo é menor quando a solução concorrente é empregada. Se o processo Leitor for sempre mais rápido, o buffer ficará cheio, e então o processo Leitor terá que esperar até que o processo impressor retire algo do buffer. Por outro lado, se o processo impressor for sempre mais rápido, eventualmente o buffer ficará vazio e ele terá que esperar pelo processo leitor.
  88. 88. 3.2 Paralelismo Na verdade, a maior motivação para a programação concorrente é a engenharia de software. Aplicações inerentemente paralelas são mais facilmente construídas se programação concorrente é utilizada. Estão enquadrados nesse grupo, aplicações envolvendo protocolos de comunicação, aplicações de supervisão e controle industrial, e como era de se esperar, a própria construção de um sistema operacional.
  89. 89. 3.2 Paralelismo A figura 3.5 ilustra uma rede local na qual existem diversos computadores pessoais utilizados pelos usuários e existe um computador dedicado ao papel de servidor de impressão na rede. O programa "servidor de impressão" deve: receber mensagens pela rede; escrever em disco os pedaços de arquivos recebidos; enviar mensagens pela rede contendo, por exemplo, resposta às consultas sobre seu estado; ler arquivos previamente recebidos; enviar dados para a impressora. Todas essas atividades devem ser realizadas simultaneamente.
  90. 90. 3.2 Paralelismo Figura 3.5: Rede local incluindo um servidor de impressão dedicado
  91. 91. 3.2 Paralelismo A figura 3.6 mostra uma das possíveis soluções para a organização interna do programa concorrente "servidor de impressão". Cada círculo representa um processo. Cada flecha representa a passagem de dados de um processo para o outro. Essa passagem de dados pode ser feita, por exemplo, através de variáveis que são compartilhadas pelos processos envolvidos na comunicação.
  92. 92. 3.2 Paralelismo Figura 3.6: Servidor de impressão como programa concorrente
  93. 93. 3.2 Especificação do paralelismo É poissível especificar paralelimos através de comandos: ● create_process: permite a criação de um segundo fluxo de execução, paralelo àquele que executou o comando. ● exit: o fluxo de controle que o executa é imediatamente terminado. ● wait_process: permite que um fluxo de execução espere outro fluxo terminar.
  94. 94. 3.2 Especificação do paralelismo Figura 3.7: Exemplo contendo os comandos create_process, exit e wait_process
  95. 95. 3.2 Especificação do paralelismo É importante observar que processos paralelos podem executar em qualquer ordem. Algumas possíveis saídas: Alo do pai Alo do filho Alo do filho Filho 1 morreu Filho 2 morreu Alo do pai Alo do filho Filho 1 morreu Alo do filho Filho 2 morreu
  96. 96. 3.2 Especificação do paralelismo Figura 3.8: Diagrama de tempo associada com o programa da figura 3.7
  97. 97. 3.2 Especificação do paralelismo Figura 3.9: Diagrama de tempo associada com o programa da figura 3.7
  98. 98. 3.2 Especificação do paralelismo Figura 3.10: Grafo de precedência para o programa da figura 3.7
  99. 99. 3.2 Especificação do paralelismo Muitas vezes são usados grafos de precedência para representar o paralelismo existente em um programa. No grafo de precedência, os nodos representam trechos de código e os arcos representam relações de precedência. Um arco no nodo X para o nodo Y representa que o código associado com Y somente poderá ser executado após o término do código associado com X. Vamos supor agora que o programador deseje que, necessariamente, o processo do filho 1 termine para então o processo filho 2 iniciar.
  100. 100. 3.2 Especificação do paralelismo Figura 3.11: Programa do exemplo 3.7 alterado
  101. 101. 3.2 Especificação do paralelismo Uma forma mais estruturada de especificar paralelismo em programas concorrentes é conseguida com o uso dos comandos Parbegin e Parend. Enquanto o par Begin-End delimita um conjunto de comandos que serão executados sequencialmente, o par Parbegin-Parend delimita um conjunto de comandos que serão executados em paralelo. O comando que segue ao Parend somente será executado quando todos os fluxos de controle criados na execução do Parbegin-Parend tiverem terminado.
  102. 102. 3.2 Especificação do paralelismo Os comandos Parbegin-Parend definem uma nova estrutura de controle para a linguagem. Nos exemplos, a sintaxe da linguagem C foi estendida com a inclusão desse novo comando. Também é possível usar uma versão menos elegante para o comando Parbegin que, entretanto, mantém sua funcionalidade. Dessa vez, Parbegin aparece como uma função de biblioteca cujos parâmetros são os nomes das funções a serem disparadas em paralelo.
  103. 103. 3.2 Especificação do paralelismo Figura 3.12: Exemplo contendo os comandos Parbegin e Parend
  104. 104. 3.3 Problema da seção crítica Uma forma de implementar a passagem de dados de um processo para o outro são variáveis compartilhadas pelos processos envolvidos na comunicação. A passagem acontece quando um processo escreve em uma variável que será lida por outro processo. A quantidade exata de memória compartilhada entre os processos pode variar conforme o programa. Processos podem compartilhar todo o seu espaço de endereçamento, apenas um segmento de memória, algumas estruturas de dados ou algumas variáveis. O sistema operacional arranja para que os processos acessem as mesmas posições de memória.
  105. 105. 3.3 Problema de seção crítica Figura 3.13: Compartilhamento de memória
  106. 106. 3.3 Problema da seção crítica Não é possível eliminar as variáveis compartilhadas de um programa concorrente quando elas são o mecanismo de comunicação entre os processos. A solução está em controlar o acesso dos processos e suas variáveis compartilhadas, de modo a garantir que um processo não acesse uma estrutura de dados enquanto essa estiver sendo utilizada por outro processo. A parte do código de um processo que acessa uma estrutura de dados compartilhada é chamada de seção crítica.
  107. 107. 3.3 Problema da seção crítica Uma solução para o problema da seção crítica estará correta quando apresentar as seguintes propriedades: ● Existe exclusividade mútua entre os processos com referência na execução das respectivas seções críticas. ● Quando um processo P deseja entrar na seção crítica e nenhum outro processo está executando a sua seção crítica, o processo P não é impedido de entrar. ● Nenhum processo pode ter seu ingresso na seção crítica postergado indefinidamente, ou seja, ficar esperando para sempre. ● Não depender da velocidade relativa da execução dos processos, nem da quantidade de processadores (cores) existentes.
  108. 108. 3.4 Mecanismos básicos de exclusão mútua Tipicamente, uma solução para o problema da seção crítica tem a forma de um mecanismo que controla o acesso dos processos ao código da seção crítica. Através de primitivas específicas alocadas imediatamente antes (entrada) e imediatamente depois (saída) da seção crítica, esse mecanismo age de maneira a obter-se as quatro propriedades citadas anteriormente (ou, pelo menos, a maioria delas).
  109. 109. 3.4.1 Soluções em software puro Dentro da categoria dos protocolos de software puro, os mais famosos são os algoritmos de Dekker e de Peterson. Nessas soluções os processos executam um determinado algoritmo na entrada e outro na saída da seção critica. Tais algoritmos não incluem nenhuma chamada ao sistema operacional, nem o emprego de instruções privilegiadas.
  110. 110. 3.4.1 Soluções em software puro Figura 3.18: Protocolo de software puro: solução de Peterson
  111. 111. 3.4.1 Soluções em software puro A variável flag é um array com duas posições, cada uma indica quando o respectivo processo deseja entrar na seção crítica (valor 1 indica "quero entrar"). A variável turn contem o número do processo com a preferência no momento. O processo P0 poderá entrar na seção crítica quando P1 não deseja entrar na seção crítica ou quando a preferência no momento é para P0. Embora o algoritmo apresentado funcione apenas para dois processos, ele pode ser extendido para o caso de muitos processos.
  112. 112. 3.4.1 Soluções em software puro Soluções em software puro não são muito empregados na pratica por duas razões: 1. são bastante complexas, o que dificulta a depuração dos problemas; 2. apresentam a propriedade chamada busy-waiting, quando um processo aguarda em um laço a sinalização de um evento.
  113. 113. 3.4.2 Desabilitação de interrupções Através desta solução simples, toda vez que um processo vai acessar variáveis compartilhadas antes ele desabilita interrupções. Dessa forma, ele pode acessar as variáveis com a certeza de que nenhum outro processo vai ganhar o processador, dado que as interrupções (timer, disco, etc.) que deflagram o escalonador. No final da seção crítica, ele torna a habilitar as interrupções. Esse esquema é efetivamente usado nas aplicações que executam em sistemas pequenos e dedicados, como sistemas embarcados (embedded systems).
  114. 114. 3.4.2 Desabilitação de interrupções Desabilitar interrupções vai contra os mecanismos de proteção e não pode ser considerado um método genérico para resolver o problema da seção crítica. Essa é uma operação proibida para processos de usuário em sistemas de propósito geral já que são instruções que só podem ser executadas em modo privilegiado. Desabilitar interrupções também diminui a eficiência do sistema à medida que periféricos não são atendidos imediatamente durante as execuções de seções críticas (interrupções ficam pendentes e são atendidas somente após a seção crítica).
  115. 115. 3.4.3 Spin-lock Essa solução é baseada em uma instrução de máquina chamada "test-and-set", embora uma instrução do tipo "swap" ou "compare on store" possa ser usada também. A seção crítica será protegida por uma variável que ocupará a posição da memória. Essa variável é normalmente chamada de lock (fechadura). Quando lock contém "0", a seção crítica está livre. Quando lock contém "1", ela está ocupada. A variável é inicializada com "0". Antes de entrar na seção crítica, um processo precisa "fechar a porta", colocando "1" em lock. Entretanto ele só pode fazer isso se "a porta estiver aberta".
  116. 116. 3.5 Mutex O nome mutex é derivado de "mutual exclusion" (exclusão mútua). Uma variável mutex pode assumir apenas os valores livre e ocupado. A operação lock é usada pelo processo para solicitar acesso à seção crítica (entrada); A operação unlock permite ao processo informar que não deseja mais usar a seção crítica (saída).
  117. 117. 3.5.1 Implementação de mutex No caso de computadores com um único processador, a solução mais comum é desabilitar interrupções. Para computadores com vários processadores, desabilitar interrupções não basta. Nesse caso, o spin-lock é usado, pois ele impede que um outro processo, executando em outro processador, execute a operação lock ou unlock sobre o mesmo mutex.
  118. 118. 3.6 Semáforos Podemos sintetizar o funcionamento das operações P e V sobre um semáforo S da seguinte forma: P (S): S.valor = S.valor - 1; Se S.valor < 0 Então bloqueia o processo, insere em S.fila V (S): S.valor = S.valor + 1; Se S.fila não está vazia Então retira processo P de S.fila, acorda P
  119. 119. 3.6 Semáforos Para que semáforos funcionem corretamente, é essencial que as operações P e V sejam atômicas. Isso é, uma operação P ou V não pode ser interrompida no meio e outra operação sobre o mesmo semáforo iniciada. Semáforos tornam a proteção da seção crítica muito simples. Para cada estrutura de dados compartilhada, deve ser criado um semáforo S inicializado com o valor 1. Todo processo, antes de acessar essa estrutura, deve executar um P(S), ou seja, a operação P sobre o semáforo S associado com a estrutura de dados em questão. Ao sair da seção crítica, o processo executa V(S).
  120. 120. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  121. 121. 4. Gerenciamento de Memória
  122. 122. 4.1 Introdução Historicamente, a memória principal sempre foi vista como um recurso escasso e caro. Uma das maiores preocupações dos projetistas foi desenvolver Sistemas Operacionais que não ocupassem muito espaço de memória e, ao mesmo tempo, otimizassem a utilização dos recursos computacionais. Mesmo atualmente, com a redução de custo e consequente aumento da capacidade da memória principal, seu gerenciamento é um dos fatores mais importantes no projeto de Sistemas Operacionais. Enquanto nos sistemas monoprogramáveis a gerência da memória não é muito complexa, nos sistemas multiprogramáveis essa gerência se torna crítica, devido à necessidade de se maximizar o número de usuários e aplicações utilizando eficientemente o espaço da memória principal.
  123. 123. 4.1.1 Funções básicas Em geral programas são armazenados em memórias secundárias, como discos ou fitas, por ser um meio não-volátil, abundante e de baixo custo. Como o processador somente executa instruções localizadas na memória principal, o Sistema Operacional deve sempre transferir programas da memória secundária para a memória principal antes deles serem executados. Como o tempo de acesso à memória secundária é muito superior ao tempo de acesso à memória principal, o Sistema Operacional deve buscar reduzir o número de operações de E/S à memória secundária, para evitar problemas de desempenho do sistema. A gerência de memória deve tentar manter na memória principal o maior número possível de processos residentes, permitindo maximizar o compartilhamento do processador e demais recursos computacionais.
  124. 124. 4.1.1 Funções básicas Mesmo na ausência de espaço livre, o sistema deve permitir que novos processos sejam aceitos e executados. Isto é possível através da transferência temporária de processos residentes na memória principal para a memória secundária, liberando espaço para novos processos. Este mecanismo é conhecido como swapping. Outra preocupação na gerência de memória é permitir a execução de programas que sejam maiores que a memória física disponível, implementando técnicas como overlay e memória virtual. Em um ambiente de multiprogramação, o sistema operacional deve proteger as áreas de memória ocupadas por cada processo, além da área onde reside o próprio sistema. Caso um programa tente realizar algum acesso indevido à memória, o sistema de alguma forma deve impedí-lo. Apesar de a gerência de memória garantir a proteção de áreas da memória, mecanismos de compartilhamento devem ser oferecidos para que diferentes processos possam trocar dados de forma protegida.
  125. 125. 4.2 Alocação de memória
  126. 126. 4.2.1 Alocação Contígua Simples Foi implementada nos primeiros Sistemas Operacionais, porém ainda está presente em alguns sistemas monoprogramáveis. Nesse tipo de organização, a memória principal é subdividida em duas áreas: uma para o sistema operacional e outra para o programa do usuário. Dessa forma, o programador deve desenvolver suas aplicações, preocupado, apenas, em não ultrapassar o espaço de memória disponível, ou seja, a diferença entre o tamanho total da memória principal e área ocupada pelo Sistema Operacional.
  127. 127. 4.2.1 Alocação Contígua Simples Alocação Contígua Simples
  128. 128. 4.2.1 Alocação Contígua Simples Esquema em que o usuário tem controle sobre toda a memória principal, inclusive a área do Sistema Operacional. Implementa controle de proteção do sistema através de registrador que delimita a área do Sistema Operacional. Fácil implementação e código reduzido, porém não utiliza os recursos computacionais de forma eficiente, pois apenas um usuário/aplicação pode dispor deste recurso.
  129. 129. 4.2.2 Técnica Overlay Na alocação contígua simples, todos os programas estão limitados ao tamanho da área de memória principal disponível para o usuário. Uma solução encontrada para o problema é dividir o programa em módulos, de forma que seja possível a execução independente de cada módulo, utilizando uma mesma área de memória. Essa técnica é chamada de overlay.
  130. 130. 4.2.2 Técnica Overlay Técnica Overlay
  131. 131. 4.2.2 Técnica Overlay A técnica de overlay utiliza uma área de memória comum, os os módulos “não-carregados” poderão compartilhar esta área de memória (área de overlay). Sempre que um módulo “não-carregado” for referenciado pelo módulo principal, o módulo será carregado da memória secundária para a área de overlay. No caso de uma referência a um módulo já carregado, a carga não será realizada.
  132. 132. 4.2.2 Técnica Overlay A definição das áreas de overlay é função do programador, através de comandos específicos das linguagem de programação utilizada. O tamanho da área de overlay é estabelecido a partir do tamanho do maior módulo. Esta técnica tem a vantagem de permitir ao programador expandir os limites da memória principal, porém deve ser utilizada com cuidado, pois pode trazer sérios problemas de desempenho, devido a possibilidade de transferência excessiva dos módulos entre a memória principal e a secundária.
  133. 133. 4.2.3 Alocação Contígua Particionada Os Sistemas Operacionais evoluíram no sentido de proporcionar melhor aproveitamento dos recursos disponíveis. Nos sistemas monoprogramáveis, o processador permace grande parte do tempo ocioso e a memória principal é subutilizada. Os sistemas multiprogramáveis já são muito mais eficientes no uso do processador, necessitando assim, que diversos programas estejam na memória principal ao mesmo tempo e que novas formas de gerência da memória sejam implementadas.
  134. 134. 4.2.4 Alocação Contígua Particionada Fixa Nos primeiros sistemas multiprogramáveis, a memória era dividida em pedaços de tamanho fixo, chamados partições. O tamanho das partições, estabelecido na fase de inicialização do sistema, era definido em função do tamanho dos programas que executariam no ambiente. Sempre que fossem necessárias alterações do tamanho de uma partição, o sistema deveria ser reinicializado com a nova configuração.
  135. 135. 4.2.4 Alocação Contígua Particionada Fixa Alocação Contígua Particionada Fixa (Estática) - Absoluta
  136. 136. 4.2.4 Alocação Contígua Particionada Fixa Inicialmente, os programas só podiam ser carregados e executados em apenas uma partição específica, mesmo se outras estivessem disponíveis. Esta limitação se devia aos compiladores e montadores, que geravam apenas código absoluto. No exemplo acima, supondo que os programas A e B estivessem sendo executados, os programas C e E não poderiam ser processados na terceira partição, mesmo esta estando livre. A esse tipo de gerência chamou-se alocação particionada estática absoluta.
  137. 137. 4.2.4 Alocação Contígua Particionada Fixa Com a evolução dos compiladores, montadores, ligadores e carregadores, o código gerado deixou de ser absoluto e passou a ser realocável. No código realocável, todas as referências a endereços no programa são relativas ao início do código e não a endereços físicos de memória. Desta forma, os programas puderam ser executados a partir de qualquer partição.
  138. 138. 4.2.4 Alocação Contígua Particionada Fixa Alocação Contígua Particionada Fixa (Estática) - Realocável
  139. 139. 4.2.4 Alocação Contígua Particionada Fixa Supondo que na partição 1 esteja o programa C, na partição 2 o programa A e na partição 3 o programa B. Caso os programas A e B terminassem, o programa E poderia ser executado tanto na partição 2 quanto na partição 3. Para manter o controle sobre as partições alocadas, a gerência de memória mantém uma tabela com o endereço inicial de cada partição, seu tamanho, e se está em uso ou não.
  140. 140. 4.2.4 Alocação Contígua Particionada Fixa Tabela de Alocação de Partições
  141. 141. 4.2.4 Alocação Contígua Particionada Fixa A esse tipo de gerência chamou-se alocação particionada estática relocável. Neste esquema de memória, a proteção baseia-se em dois registradores, que indicam os limites (inferior e superior) da partição onde o programa está sendo executado.
  142. 142. 4.2.4 Alocação Contígua Particionada Fixa Proteção na Alocação Particionada
  143. 143. 4.2.4 Alocação Contígua Particionada Fixa Tanto nos sistemas de alocação absoluta quanto nos de alocação realocável, os programas, normalmente, não preenchem totalmente as partições onde são carregados, deixando área de memória livre. Este problema é conhecido como fragmentação interna. Exemplo de implementação: OS/MFT (Multiprogramming with Fixed Number of Tasks) da IBM
  144. 144. 4.2.5 Alocação Contígua Particionada Dinâmica Na alocação particionada dinâmica ou variável, foi eliminado o conceito de partições de tamanho fixo. Nesse esquema, cada programa utilizaria o espaço necessário, tornando essa área sua partição. Como cada programa utiliza apenas o espaço que necessita, o programa de fragmentação interna não ocorre. Um outro problema começará a ocorrer, conhecido como fragmentação externa. Ele ocorre quando os programas forem terminando e deixando espaços cada vez menores na memória, não permitindo o ingresso de novos programas.
  145. 145. 4.2.5 Alocação Contígua Particionada Dinâmica Alocação Contígua Particionada Dinâmica
  146. 146. 4.2.5 Alocação Contígua Particionada Dinâmica Existem duas soluções para este problema. O primeiro método indica que, conforme os programas terminem, apenas os espaços livres adjacentes sejam reunidos, produzindo áreas livres de tamanho maior.
  147. 147. 4.2.5 Alocação Contígua Particionada Dinâmica Primeira solução para fragmentação interna
  148. 148. 4.2.5 Alocação Contígua Particionada Dinâmica A segunda solução envolve a relocação de todas as partições ocupadas, eliminando todos os espaços entre elas e criando uma única área livre contígua. Para que esta solução possa ser implementada, é necessário que o sistema tenha a capacidade de mover os diversos programas na memória principal, ou seja, realizar a relocação dinâmica.
  149. 149. 4.2.5 Alocação Contígua Particionada Dinâmica Segunda solução para fragmentação interna
  150. 150. 4.2.5 Alocação Contígua Particionada Dinâmica Esta técnica de gerenciamento é conhecida como alocação particionada dinâmica com relocação. Reduz em muito o problema da fragmentação, porém aumenta a complexidade do algoritmo e o consumo de recursos do sistema (processador e área de disco). Exemplo de implementação: OS/MVT (Multiprogramming with a Variable Number os Tasks) da IBM.
  151. 151. 4.2.6 Estratégias de Alocação de Partição O Sistemas Operacionais implementam, basicamente, três estratégias para determinar em qual área livre um programa será carregado para execução. A melhor estratégia depende de uma série de fatores, como o tamanho dos programas a serem processados. Independente do algoritmo utilizado, o sistema possui uma lista das áreas livres, com o endereço e o tamanho de cada área.
  152. 152. 4.2.6 Estratégias de Alocação de Partição Estratégias de Alocação de Partição
  153. 153. 4.2.6 Estratégias de Alocação de Partição Qual partição livre alocar a um processo que pede por um tamanho X ? ● FIRST-FIT: a primeira partição livre onde caibam X bytes é escolhida; ○ A procura pode começar sempre no início da lista, ou a partir do último bloco alocado (“next-fit”). ● BEST-FIT: a partição livre de tamanho mais parecido com X bytes é escolhida (sendo igual ou maior do que X); ○ Pode se aproveitar da ordenação da lista de área ivres. ○ Pode aumentar o problema de fragmentação. ● WORST-FIT: a maior a partição livre é escolhida; ○ Diminui o problema de fragmentação, pois deixa espaços livres maiores.
  154. 154. 4.2.6 Estratégias de Alocação de Partição Exemplo de Uso das Estratégias de Alocação de Partição
  155. 155. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.
  156. 156. 5. Gerenciamento de Memória Virtual
  157. 157. 5.1 Introdução Memória Virtual é uma ténica poderosa e sofisticada de gerência de memória, onde as memórias principal e secudária são combinadas, dando ao usuário a ilusão de existir uma memória muito maior que a capacidade real da memória principal. O conceito desta técnica fundamenta-se em não vincular o endereçamento feito pelo programa aos endereços físicos da memória principal. Desta forma, programas e suas estruturas de dados deixam de estar limitados ao tamanho da memória física disponível, pois podem possuir endereços associados à memória secundária. Outra vantagem é permitir um número maior de processos compartilhando a memória principal, utilizando de forma mais eficiente o processador. Também possibilita a minimização do problema da fragmentação da memória principal. A primeira implementação foi realizada no início da década de 1960, no sistema Atlas, desenvolvido na Universidade de Manchester (Kilburn, 1962). Posteriormente, a IBM introduziria este conceito comercialmente na família System/370 em 1972. Atualmente a maioria dos sistemas operacionais utilizam-se desta técnica de gerenciamento, com exceção de alguns sistemas de supercomputadores.
  158. 158. 5.1 Introdução Existe um forte relacionamento entre a gerência de memória virtual e a arquitetura de hardware do sistema computacional. Por motivos de desempenho, é comum que algumas funções da gerência de memória virtual sejam implementadas diretamente no hardware. Além disso, o código do sistema operacional deve levar em consideração várias características específicas da arquitetura, especialmente o esquema de endereçamento do processador. A gerência de memória virtual, também conhecida como gerência de alocação não-contígua, aborda três técnicas que permitem sua implementação: paginação, segmentação e segmentação com paginação.
  159. 159. 5.1.1 Espaço de endereçamento virtual O conceito de memória virtual se aproxima muito da idéia de um vetor, existente nas linguagens de alto nível. Quando um programa faz referência a um elemento do vetor, não há preocupação em saber a posição de memória daquele dado. O compilador encarrega-se de gerar instruções que implementam esse mecanismo, tornando-o totalmente transparente ao programador. No caso da memória virtual, a abstração ocorre em relação aos endereços dos programas e dados. Um programa no ambiente de memória virtual não faz referência a endereços físicos de memória (endereços reais), mas apenas a endereços virtuais. O momento da execução, o endereço virtual referenciado é traduzido para um endereço físico, pois o processador manipula apenas posições da memória principal. O mecanismo de tradução destes endereços é denominado como mapeamento.
  160. 160. 5.1.1 Espaço de endereçamento virtual Espaços de endereçamento virtual x real
  161. 161. 5.1.1 Espaço de endereçamento virtual Programas podem fazer referência a endereços virtuais que estejam fora dos limites da memória principal, não há mais a limitação do tamanho da memória física disponível. A memória secundária é utilizada como extensão da memória principal. Quando um programa é executado, apenas parte do seu código fica residente na memória principal, permanecendo o restante na memória secundária até ser referenciado. Possibilita aumentar o compartilhamento da memória principal entre muito processos. No desenvolvimento das aplicações, os programadores não necessitam preocupar-se dos endereços virtuais, uma vez que os compiladores e ligadores (linkers) se encarregam desta tarefa.
  162. 162. 5.1.1 Espaço de endereçamento virtual Espaço de endereçamento virtual
  163. 163. 5.1.2 Mapeamento O processador apenas executa instruções e referencia dados residentes no espaço de endereçamento real; portanto, deve existir um mecanismo que transforme os endereços virtuais em endereços reais. Esse mecanismo, conhecido por mapeamento, permite traduzir um endereço localizado no espaço virtual para um associado no espaço real. A consequencia deste mapeamento é que um programa não necessita estar necessariamente alocado em endereços contíguos na memória principal para ser executado. Nos sistemas modernos, a tarefa de tradução de endereços virtuais é realizada pelo hardware juntamente com o sistema operacional, de forma a não comprometer seu desempenho e torná-lo totalmente transparente a usuários e aplicações. O dispositivo de hardware responsável por essa tradução é conhecido como Unidade de Gerência de Memória (Memory Management Unit – MMU), sendo acionado sempre que se faz referência a um endereço virtual. Depois de traduzido, o endereço real pode ser utilizado pelo processador para o acesso à memória principal. Como cada processo tem seu próprio endereçamento virtual, o mecanismo de tradução encarrega-se de manter tabelas de mapeamento exclusivas para cada processo.
  164. 164. 5.1.2 Mapeamento Tabela de Mapeamento
  165. 165. 5.1.2 Mapeamento A tabela de mapeamento é uma estrutura de dados existente para cada processo. A troca de tabelas (de um processo para outro) é realizada através de um registrador, que indica a posição inicial da tabela corrente. Toda a vez que há uma mudança de contexto, o registrador é atualizado com o endereço da nova tabela. As tabelas mapeiam blocos de dados, cujo o tamanho determina o número de entradas existentes nas tabelas de mapeamento.
  166. 166. 5.1.2 Mapeamento
  167. 167. 5.1.3 Alocação de Memória Virtual por Paginação Técnica de gerência de memória onde o espaço de endereçamento virtual e o espaço de endereçamento real são divididos em blocos de mesmo tamanho chamados páginas. As páginas no espaço virtual são denominadas páginas virtuais, enquanto que as páginas do espaço real são chamadas de páginas reais ou frames. Todo o mapeamento de endereço virtual em real é realizado através de tabelas de páginas. Cada processo possui sua própria tabela de páginas e cada página virtual do processo possui uma entrada na tabela, com informações de mapeamento que permitem ao sistema localizar a página real correspondente.
  168. 168. 5.1.3 Alocação de Memória Virtual por Paginação Alocação de Memória Virtual por Paginação
  169. 169. 5.1.3 Alocação de Memória Virtual por Paginação Quando um programa é executado, páginas virtuais são transferidas da memória secundária para a memória principal e colocadas nos frames. Nesta técnica, o endereço virtual é formado pelo número da página virtual (NPV) e por um deslocamento. O endereço físico é obtido combinando-se o endereço do frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual. Além da informação sobre a localização da página virtual, a ETP possui outras informações, como o bit de validade (valid bit) que indica se uma página está carregada na memória principal. Se o bit for 0 (zero), indica que não a página não está carregada, mas se o valor for 1, a página está carregada na memória principal. Caso a página referenciada não esteja na memória principal, dizemos que ocorreu um page fault. Neste caso, o sistema transfere a página da memória secundária para a memória principal, realizando uma operação de E/S conhecida como page in ou paginação.
  170. 170. 5.1.3 Alocação de Memória Virtual por Paginação Tradução do Endereço Virtual
  171. 171. 5.1.4 Proteção e Compartilhamento de Memória Em qualquer sistema multiprogramável, onde diversas aplicações compartilham a memória principal, devem existir mecanismos para preservar as áreas de memória do sistema operacional e dos diversos processos dos usuários. Um primeiro nível de proteção é inerente ao próprio mecanismo de memória virtual por paginação, onde cada processo tem a sua própria tabela de mapeamento e a tradução dos endereços é realizada pelo sistema. Desta forma um processo não pode acessar as áreas de memória de outros processos, a menos que haja compartilhamento explícito de páginas entre os processos. A proteção de acesso é realizada individualmente em cada página da memória principal, utilizando-se as entradas das tabelas de mapeamento onde alguns bits especificam os acessos permitidos.
  172. 172. 5.1.4 Proteção e Compartilhamento de Memória
  173. 173. 5.1.4 Proteção e Compartilhamento de Memória ● De forma resumida há dois tipos de acessos básicos realizado em uma página: leitura e gravação. É possível a combinação destes acessos, produzindo um mecanismo simples e eficiente. Mecanismo de Proteção
  174. 174. 5.1.5 Alocação de Memória Virtual por Segmentação É a técnica de gerência de memória onde o espaço de endereçamento virtual é dividido em blocos de tamanhos diferentes chamados segmentos. Na técnica de segmentação, um programa é dividido logicamente em sub-rotinas e estruturas de dados, que são alocadas em segmentos na memória principal. Há uma relação entre a lógica do programa e sua alocação na memória principal. Normalmente a definição dos segmentos é realizada pelo compilador, a partir do código fonte do programa, e cada segmento pode representar um procedimento, função, vetor ou pilha. O espaço de endereçamento virtual de um processo possui um número máximo de segmentos que podem existir, onde cada segmento pode variar de tamanho dentro de um limite. O tamanho do segmento pode ser alterado durante a execução do programa.
  175. 175. 5.1.5 Alocação de Memória Virtual por Segmentação Segmentação
  176. 176. 5.1.6 Alocação de Memória Virtual por Segmentação com Paginação É a técnica de gerência de memória onde o espaço de endereçamento é dividido em segmentos e, por sua vez, cada segmento dividido em páginas. Esse esquema de gerência de memória tem o objetivo de oferecer as vantagens tanto da técnica de paginação quanto da técnica de segmentação. Nessa técnica, um endereço virtual é formado pelo número do segmento virtual (NSV), um número de página virtual (NPV) e um deslocamento. Através no NSV, obtém-se uma entrada na tabela de segmentos, que contém informações da tabela de páginas do segmento. O NPV identifica unicamente a página virtual que contém o endereço, funcionando como um índice na tabela de páginas. O deslocamento indica a posição do endereço virtual em relação ao início da página na qual se encontra. O endereço físico é obtido, então, combinando-se o endereço do frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual. Na visão do programador, sua aplicação continua sendo mapeada em segmentos de tamanhos diferentes, em função das sub-rotinas e estruturas de dados definidas no programa. Por outro lado, o sistema trata cada segmento como um conjunto de páginas de mesmo tamanho, mapeadas por uma tabela de páginas associadas ao segmento. Dessa forma, um segmento não precisa estar contíguo na memória principal, eliminando o problema da fragmentação externa encontrado na segmentação pura.
  177. 177. 5.1.6 Alocação de Memória Virtual por Segmentação com Paginação Segmentação com Paginação
  178. 178. 5.1.7 Swapping em Memória A técnica de swapping permite aumentar o número de processos que compartilham a memória principal e, consequentemente, o grau de multiprogramação do sistema. Quando existem novos processos para serem executados e não há memória principal livre suficiente para alocação, o sistema utiliza o swapping, selecionando um ou mais processos para saírem da memória e oferecer espaço para novos processos. Depois de escolhidos, o sistema retira os processos da memória principal para a memória secundária (swap out), onde as páginas ou segmentos são gravados em um arquivo de swap (swap file). Com os processos salvos na memória secundária, os frames ou segmentos alocados são liberados para novos processos. Porteriormente, os processos que forem retirados da memória devem retornar para a memória principal (swap in) para serem novamente executados.
  179. 179. 5.1.7 Swapping em Memória Há várias políticas que podem ser aplicadas na escolha dos processos que devem ser retirados da memória principal. Todas elas buscam os processos com menor chance de serem executados em um futuro próximo, sendo que a maioria dos critérios de escolha baseiam-se no estado do processo e na sua prioridade. O swapping com base em estado seleciona, inicialmente, os processos com estado em espera; porém se estes não forem suficientes ele também selecionará os em estado de pronto com menor prioridade. O arquivo de swap é compartilhado por todos os processos que estão em execução. Cada processo tem uma área reservada no arquivo que é liberada quando o processo é eliminado. Em alguns sistemas, o arquivo de swap é, na verdade, uma área em disco reservada exclusivamente para esta função.
  180. 180. 5.1.8 Trashing Pode ser definido como sendo a excessiva transferência de páginas/segmentos entre a memória principal e a memória secundária. Esse problema está presente em sistemas que implementam tanto paginação como segmentação. Na memória virtual por paginação, o thrashing ocorre em dois níveis: no do próprio processo e no do sistema. No nível do processo, a excessiva paginação ocorre devido ao elevado número de page faults gerado pelo programa em execução. Esse problema faz com que o processo passe mais tempo esperando por páginas que realmente sendo executado. No nível de sistema ocorre quando existem mais processos competindo por memória principal que espaço disponível. Neste caso, o ideal é reduzir o número de páginas de cada processo na memória, poré isto leva ao thrashing do processo. Caso a redução não seja suficiente, o sistema iniciará o swapping. Se este mecanismos for ao extremo, o sistema passará mais tempo realizando swappings que atendendo aos processos.
  181. 181. 5.1.8 Trashing Em sistema que implementam segmentação, o thrashing também ocorre em dois níveis. No nível do processo, a transferência excessiva de segmentos é devida à modularização extrema do programa. E no nível do sistema é semelhante ao da paginação, com a ocorrência de swapping de processos para liberar memória para os demais. Independente das soluções apresentadas, se existirem mais processos para serem executados que memória real disponível, a única solução é a expansão da memória principal. É importante ressaltar que este problema não ocorre apenas em sistema que implementam memória virtual, mas também em sistemas com outros mecanismos de gerência de memória.
  182. 182. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.
  183. 183. 6. Gerenciamento de Dispositivos
  184. 184. 6.1 Fundamentos Uma parte bastante importante dentro dos Sistemas Operacionais é a dos mecanismos de Entradas e Saídas, através do qual o sistema se comunica com o mundo externo. Este nível é composto por processos servidores de E/S (gerentes de dispositivos e drivers) que também são processos do S.O. e também competem pelos seus recursos.
  185. 185. 6.1 Fundamentos Entrada é toda instrução de envio de dados ao mundo exterior e Saída é toda instrução de recepção de dados dele. Essas instruções, em geral compreendem duas etapas: 1. Saída: ○ comandos de ação do dispositivo. ○ comandos de atribuição de dados para a operação. 2. Entrada: ○ comandos de indicação de endereços dos dados. ○ comandos de verificação do estado do dispositivo.
  186. 186. 6.1 Fundamentos Portanto as instruções de E/S são sempre do tipo: ○ Sai comando; ○ Sai dados; ○ Entra dados; e ○ Entra Estado do Dispositivo. Toda operação do tipo E/S pode ser subdividida no tempo em 3 etapas distintas: 1. Início da E/S 2. Transferencia de dados 3. Finalização da operação Em geral, existe um sistema de 'RETRAY' para o caso de finalizações sem sucesso.
  187. 187. 6.2 Tipos de E/S E/S com Polling (Interrogação): Implementa certo paralelismo entre a UCP e os Dispositivos de E/S. ● O programa após iniciar uma operação de E/S num dispositivo, continua executando outras tarefas (por exemplo, outra operação de E/S num outro dispositivo) e periodicamente testa o estado do dispositivo disparado para verificar se ele já completou a operação. ● É programada pelo usuário, o programa fica dependente dos aspectos físicos, além de não perder o controle da UCP. Além disso, o programa depende as características do dispositivos e perde a portabilidade.
  188. 188. 6.2 Tipos de E/S E/S Assíncronas Com Interrupções: O programa inicia a operação de E/S passando comando ao dispositivo e continua outras tarefas em paralelo, até que o dispositivo encerre a operação, gerando um sinal de interrupção para a UCP para que a finalização da operação seja executada.
  189. 189. 6.2 Tipos de E/S E/S Por Acesso Direto A Memória (DMA): É um mecanismo de E/S assíncrona não programada onde um dispositivo controlador de acessos a memória do sistema promove as operações de E/S diretamente, independente da participação da UCP, disputando com ela as vias de dados e endereços, e sinalização só no final da operação. ● Note que num mecanismo de interrupções sem DMA a cada operação, o dispositivo gera um sinal para a UCP a fim de completar a operação. ● No sistema de DMA, a UCP comanda um acesso passando as instruções e o endereço na memória do dado a ser transferido e o Controlador de DMA faz toda a operação e somente avisa a UCP de sua execução, sem necessidade de sua intervenção.
  190. 190. 6.2 Tipos de E/S No uso de DMA, usa-se também a E/S programada para transferências de comandos e endereços ao Controlador. Informações para o Controlador: ● End. Inicial do bloco de dados na memória onde se dará a operação. ● Sentido da transferência de dados (leitura ou escrita). ● Número de células de memória a serem transferidas. OBS.: A memória só tem um porto de acesso (ponto de entrada) e um mecanismo de arbitração incorporado ao hardware define que tem direito a acessar, de acordo com sua prioridade. A prioridade maior é dada aos Controladores de ADM e depois a UCP pois sua velocidade é muito maior que a dos dispositivos. Este mecanismo é chamado Roubo de Ciclo ('cicle stealing').
  191. 191. 6.2 Tipos de E/S E/S por CANAIS Característico de sistemas grandes, um Canal é um processador dedicado as funções de E/S. Pode executar Programas de canal armazenados em certos endereços da memória que a UCP passa como parâmetro ao processador de canal. ● Nos IBM: Canais de E/S. ● Nos CDC cyber: PPU (Periferal Processor Unit) Canais podem ser multiplexados por um mesmo processador de canal, de modo a ter-se em andamento várias entradas ou saídas ocorrendo em paralelo, controladas pelo mesmo processador de canal.
  192. 192. 6.2 Tipos de E/S BUFFERS No histórico dos S.O., vimos que a velocidade de processamento dependia no início da velocidade dos periféricos, pois não havia até então paralelismo entre eles e a UCP. Além dos avanços no Hardware e nas formas de E/S, os sistemas mais recentes implementam formas de E/S que fazem uso de BUFFERS que são meios de armazenamento intermediários utilizados para suavizar as diferenças de velocidade de produção e consumo de dados entre a UCP e os Dispositivos. A estratégia de bufferização está baseada nos comandos de Sincronização entre processos Produtor/consumidor, tratado no capítulo sobre sincronismo, através das primitivas Wait e Signal do núcleo.
  193. 193. 6.3 Camadas A gerência de dispositivos é parte do S.O. responsável por ocultar das aplicações os detalhes de controle e operação dos diversos dispositivos conectados ao sistema. A própria gerência de dispositivos é normalmente implementada em diversas camadas, de forma a proporcionar uma melhor generalização das operações de controle frente a constante evolução e mudança da tecnologia de implementação do hardware dos dispositivos.
  194. 194. 6.3 Camadas ● Assim, a maioria dos S.O.s implementa a gerência de dispositivos em um esquema parecido com o abaixo representado:
  195. 195. 6.3 Camadas Biblioteca de E/S Normalmente, as linguagens oferecem comando para manipular os recursos de E/S, que são o primeiro nível de interação do aplicativo com a gerência de E/S. Esses comandos são independentes até mesmo do S.O. Por exemplo, o usuário cria um arquivo em qualquer linguagem através de um comando da própria linguagem que não o obriga a saber nada sobre como será a formatação física do arquivo no disco.
  196. 196. 6.3 Camadas Biblioteca de E/S O compilador da linguagem, por sua vez, traduz esses comandos em comando Chamadas de Sistema, que são os comandos oferecidos pela camada mais de cima da gerência de dispositivos e que, no desenho acima, chamamos biblioteca de E/S. Cada System call da biblioteca possui parâmetros que são passados pelo compilador da linguagem, naturalmente ainda independentemente da implementação física, e resolvidos na fase de link do programa do usuário. Além de esconder características de implementação, as Chamadas de Sistema têm por objetivo oferecer um nível onde sejam implementadas rotinas que afinal são comuns a várias linguagens e a diferentes aplicativos e que, portanto, não precisam ser duplicadas nos diferentes aplicativos ou linguagens.
  197. 197. 6.3 Camadas Sistemas de E/S É a camada imediatamente abaixo na estrutura da Gerência de E/S e tem os seguintes objetivos: ● Realizar operações comuns a dispositivos distintos, sem levar em consideração aspectos específicos do dispositivo ● Fazer o mapeamento entre dispositivos lógicos e seus respectivos drivers de dispositivos físicos ● Uniformizar unidades de informação (blocos, registros, bytes, etc.) ● Gerenciar a ocorrência de alguns tipos de erros ● Controlar o compartilhamento de recursos, impondo os sincronismos que se fizerem necessários ● Controlar as prerrogativas de acesso dos usuários aos dispositivos ● Controlar a bufferização das informações com o objetivo de acelerar as operações de E/S.
  198. 198. 6.3 Camadas Drivers de Software Os drivers de software, device drivers ou simplesmente drivers, manipulam um só dispositivo ou, no máximo, uma família de dispositivos. Normalmente os drivers são feitos em Assembly pelo próprio fabricante do dispositivo e são fornecidos gratuitamente quando se compra o Hardware (ou são disponibilizados da internet, por exemplo). Suas funções são: ● Receber comandos genéricos e traduzí-los para comandos específicos do dispositivo ● Manipular os registradores e demais elementos de hardware específicos do controlador
  199. 199. 6.3 Camadas Drivers de Software Mapear unidades de um nível superior (como por exemplo blocos) em unidades físicas do dispositivo (como por exemplo, disco, trilhas, setores, etc.) Gerar e manipular interrupções de operações feitas por hardware dedicado (fim de transferência de um bloco de dados ou erro de transferência de dados, por exemplo).
  200. 200. 6.3 Camadas Drivers de Software
  201. 201. 6.3 Camadas Controladoras São placas de hardware que possuem registradores, memória local e as vezes processadores dedicados a manipular um determinado dispositivo. Em geral bufferizam a informação recebida ou enviada ao dispositivo por um barramento dedicado ou algum outro canal de comunicação e transferem os dados para a memória principal geralmente através de DMA. Assim, a CPU fica livre para realizar outras operações enquanto está se realizando a transferência de dados do/para o dispositivo.
  202. 202. 6.3 Camadas Controladoras Alguns padrões de controladoras utilizados atualmente são: ● IDE interface controladora de discos magnéticos e óticos mais utilizada nos computadores pessoais. Possui um padrão mais antigo (PIO) e um mais recente (ULTRA DMA) ● SCSI (Small Computer System Interface) – define padrões de Hardware e software que permitem conectar diferentes dispositivos como discos magnéticos, óticos, scanners, unidades de fita, etc. ● USB – interface de uso geral com protocolo de rede que permite conectar virtualmente todos os dispositivos de uma máquina (inclusive teclado e mouse) e que começa a se configurar como o provavel padrão de futuro.
  203. 203. 6.3 Camadas Dispositivos São os equipamentos propriamente ditos, como impressoras, discos, fitas, teclados, scanners, vídeos, registradores gráficos, etc. Podem ser divididos em estruturados e não estruturados. Estruturados são os que transferem informações em blocos (estruturas) de tamanho fixo. A transferência pode ser direta, como no caso dos discos onde se acessa diretamente o endereço de um bloco ou seqüencial, como no caso das fitas, em que é preciso percorrer seqüencialmente o meio de armazenamento. Os não estruturados são os dispositivos em que os dados fluem em lotes de tamanho indefinido, ou mesmo um a um, como é o caso dos teclados, mouse ou impressoras.
  204. 204. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.

Quais são os principais problemas da alocação contígua de arquivos?

Um problema na alocação contígua é a fragmentação dos espaços livres causado pela criação e eliminação constante de arquivos é que com o tempo surgem espaços vagos sem o tamanho suficiente para se alocar novos arquivos.

Qual a desvantagem da estratégia de alocação de arquivos Worst Fit?

Desvantagens: – Pouca flexibilidade no crescimento dos arquivos. – Tamanho máximo do arquivo deve ser conhecido no momento da alocação. – Ocorrência de fragmentação externa.

Qual o principal problema encontrado nas alocações Particionadas estática e dinâmica?

9.3.2 – Alocação Particionada Dinâmica Aumento do grau de compartilhamento diminuindo o problema da fragmentação. Partições sem tamanho fixo, onde cada programa utiliza o espaço que necessita. Existe ainda o problema de fragmentação, conforme os programas vão terminando e deixando espaços cada vez menores.

Quais são as vantagens e as desvantagens dos métodos para alocação de espaço em disco?

Vantagens: A principal vantagem é que o acesso a esses arquivos que ficam dispostos continuamente no disco se torna simples, tanto na forma sequencial como na direta. Desvantagem: Deficiência na alocação de espaço livre para novos arquivos.