Bruno Affonso Diego Chiquito Ruan Berté Escalonador O código de Escalonamento no Windows é implementado no Kernel. A rotina que desempenha as tarefas do Escalonador é chamado de Despachador do Kernel. Determina qual Thread deve ser executada. Troca de contexto: salva o estado da Thread em execução > carregar o estado de outra Thread > e iniciar a execução desta nova Thread. Escalonador O Windows escalona usando as threads. Processos não executam, apenas fornecem recursos e um contexto para a execução das suas Threads. Se um processo A tiver 10 Threads executáveis, um Processo B tiver 2 Threads executáveis, e todas as 12 Threads estiverem na mesma prioridade, cada Thread teoricamente receberia 1/12 do tempo da CPU (Windows não daria 50% do tempo da CPU para o processo A e 50% para o processo B). Trocas de Contexto O escalonador mantém uma fila de Threads executáveis para cada nível de prioridade. Estas são chamadas ready Threads (threads prontas). Quando o processador se torna disponível, o sistema realiza a troca de contexto. Salva contexto da Thread que acabou de ser executada > coloca a Thread que acabou de terminar sua execução no final da fila de sua prioridade > encontra a fila de maior prioridade que contém ready Threads > retira a Thread no início da fila, carregar seu contexto, e executa. Níveis de Prioridade As Threads são programadas para executar baseadas na sua Prioridade. Os níveis de prioridade vão de 1 a 15 (menor prioridade) e de 16 a 31 (maior prioridade). O sistema trata todas as threads que possuem a mesma prioridade como iguais. O sistema atribui frações de tempo para as threads de maior prioridade. Se nenhuma delas estiver pronta para executar, são atribuídas fatias de tempo para as próximas threads de maior prioridade. Níveis de Prioridade Se uma thread de maior prioridade ficar disponível para execução, o sistema deixa de executar a thread de prioridade baixa (sem deixar que ela termine de usar seu tempo), e atribui uma fatia de tempo completa para a thread de maior prioridade. A prioridade de cada thread é determinada pelos seguintes critérios: A classe de prioridade do processo; O nível de prioridade da thread dentro da classe de prioridade do seu processo. Aumento de Prioridade Cada thread tem uma prioridade dinâmica, esta prioridade é usada pelo escalonador para determinar qual thread executar. O sistema pode aumentar e diminuir a prioridade dinâmica para assegurar que esta thread seja executada. As threads com prioridade base entre 16 e 31(tempo real) não sofrem aumento de prioridade por parte do sistema, apenas threads com prioridade base entre 1 e 15 recebem aumento dinâmico de prioridade. Aumento de Prioridade Depois de elevar a prioridade dinâmica de uma thread, o escalonador reduz sua prioridade em um nível toda vez que a thread usa completamente sua fatia de tempo, até que a thread volte a sua prioridade base. A intenção desses ajustes é tentar prover uma capacidade de resposta mais justa possível nos cenários de escalonamento, mas como qualquer algoritmo de escalonamento, estes ajustes não são perfeitos e nem sempre beneficia todas as aplicações. Aumento de Prioridade Tem-se uma thread de prioridade 7 que está em execução, impedindo uma thread de prioridade 4 de receber tempo da CPU entretanto, uma thread de prioridade 11 está esperando por algum recurso que a thread de prioridade 4 bloqueou. Mas como a thread de prioridade 7 está tomando todo o tempo da CPU, a thread de prioridade 4 nunca irá executar por tempo suficiente para terminar o que quer que ela esteja fazendo e disponibilizar o recurso que bloqueia a thread de prioridade 11. Como o Windows lida com essa situação? Balance Set Manager Uma vez por segundo, o "Gerenciador de Equilíbrio" (Balance Set Manager), uma thread de sistema que existe principalmente para realizar funções de gerenciamento de memória, procura filas prontas de quaisquer threads que estiveram em estado de "pronto" (isto é, que não executaram ainda) por 4 segundos. Se ele encontrar essa thread, o Gerenciador de Equilíbrio aumenta a prioridade da thread para 15. Balance Set Manager Uma vez que a thread for executada, a prioridade é imediatamente reduzida para sua prioridade base original. Se a thread não houver terminado e uma thread de prioridade maior estiver pronta para executar, a thread que foi reduzida volta para a fila "pronta", onde, novamente, esta fica disponível para um novo aumento se ficar lá (na fila) por mais 4 segundos. Balance Set Manager O Gerenciador de Equilíbrio não verifica realmente todas as threads sempre que é executado. Para minimizar o tempo de CPU utilizado, ele verifica somente 16 threads prontas, se houver mais threads naquele nível de prioridade, ele se lembra onde parou e inicia o próximo passo. Além disso, ele aumentará apenas dez threads em cada passagem - se ele encontrar dez threads que mereçam esse aumento, ele para a verificação naquele ponto e inicia na próxima passagem. Preempção Nesse cenário de escalonamento, uma thread com prioridade menor é interrompida quando uma thread com prioridade maior fica pronta para executar. Quando uma thread é interrompida, ela é posta no começo da fila de threads prontas para a prioridade que estava executando. Estados de uma Thread Inicializado: uma thread começa no estado inicializado durante sua criação. Pronto: uma vez criada, entra no estado Pronto, nesse estado as threads estão esperando para usar um processador. Reserva: a thread entra no estado de reserva quando o despachador decide em qual processador será executada, aguardando a sua vez por aquele processador. Execução: uma vez obtido o processador a thread entra em estado de Execução. Estados de uma Thread Terminado: quando a thread termina de executar. Espera: estado em que a thread precisa de alguma entrada ou saída. Transição: quando a thread concluir sua espera, ou ela volta para o estado pronto ou entra no estado de transição. A pilha de núcleo de uma thread no estado de transição foi paginada para fora da memória (por exemplo, porque não executou por um período de tempo e o sistema precisou de memória para outros propósitos). Desconhecido: o sistema coloca uma thread no estado desconhecido quando não está seguro do estado da thread (usualmente devido a um erro) Thread Pools Corta despesas compartilhando e reciclando threads. Mantém limite sobre o número de threads ativas. Provê gerenciamento das threads de trabalho. POSIX vs. Windows Pthreads-w32 – Diferenças: Tipos de dados como pthread_thread_t, pthread_mutex_t, e pthread_cond_t, são todos utilizados como HANDLE no Win32. Só há uma função necessária para fazer uma thread bloquear enquanto espera por um objeto: WaitForSingleObject. Portanto, somente um conjunto de parâmetros necessita ser conhecido, independente se o código está esperando em uma thread, um mutex, um semáforo, ou um evento. No POSIX, se uma thread sinaliza uma condição, e não há uma thread esperando, o sinal é perdido. No Windows, se um evento é sinalizado, a thread continua sinalizando até que o evento seja alterado. Windows Vista Mudanças no kernel Figura 1 Figura 2 Windows Vista e 7 Thread Pool modo Usuário Windows 8 Thread Pool melhorada: Inserção de Heurística; Possível atraso na criação de novas threads; Prevenção de thread explosion. Windows CE e Mobile Como um sistema operacional de multiprocessamento preemptivo, o Windows CE suporta até 32 processos rodando simultaneamente no sistema. Windows CE o Windows Mobile provêm 256 níveis de prioridade para as threads. Para assinalar níveis de prioridade, o Windows CE usa CeSetThreadPriority and CeGetThreadPriorityfun ctions. CeSetThreadPriority define a prioridade para uma específica thread. CeGetThreadPriority retorna 0 (zero) como a maior prioridade e 255 como a menor. Referências http://www.albahari.com/threading/ https://msdn.microsoft.com/enus/library/windows/desktop/ms686760(v=vs.85).aspx http://jmhartsoftware.com/opensource.htm https://software.intel.com/en-us/blogs/2006/10/19/whywindows-threads-are-better-than-posix-threads https://technet.microsoft.com/ptbr/magazine/2007.02.vistakernel.aspx http://channel9.msdn.com/Shows/Going+Deep/InsideWindows-8-Pedro-Teixeira-Thread-pool https://msdn.microsoft.com/en-us/library/aa450600.aspx https://msdn.microsoft.com/en-us/library/aa911506.aspx