• Nenhum resultado encontrado

Sistemas Operativos. Processos e threads no Windows. Centro de Cálculo Instituto Superior de Engenharia de Lisboa

N/A
N/A
Protected

Academic year: 2021

Share "Sistemas Operativos. Processos e threads no Windows. Centro de Cálculo Instituto Superior de Engenharia de Lisboa"

Copied!
61
0
0

Texto

(1)

Sistemas Operativos

Processos e threads no Windows

João Pedro Patriarca (jpatri@cc.isel.ipl.pt)

Centro de Cálculo

(2)

Visão conceptual (simplista) de Processo e Thread

• Processo:

1. Objecto kernel usado pelo sistema operativo para gerir o processo

2. Espaço de endereçamento que contém o módulo executável, DLL’s,

stacks e heaps

• Thread:

1. Objecto kernel usado pelo sistema operativo para gerir a thread

2. Stack da thread onde são mantidos os parâmetros e variáveis locais das funções em execução no contexto da thread

(3)

Função CreateProcess

BOOL CreateProcess(

PCTSTR pszApplicationName,

PTSTR pszCommandLine,

PSECURITY_ATTRIBUTES psaProcess,

PSECURITY_ATTRIBUTES psaThread,

BOOL bInheritHandles,

DWORD fdwCreate,

PVOID pvEnvironment,

PCTSTR pszCurDir,

PSTARTUPINFO psiStartInfo,

PPROCESS_INFORMATION ppiProcInfo);

Pode ter o valor NULL (o primeiro token do próximo parâmetro deverá indicar o nome da aplicação)

Pode ser NULL; Consultar bib:

http://msdn.microsoft.com/

en-us/library/ms682425(v=vs.85)

Indicam se os handles retornados

são herdáveis por futuros processos filhos. A NULL, os handles não são herdáveis

Indica se o processo filho herdará os

handles herdáveis do processo pai Flags que controlam a classe de prioridade

e a criação do processo

Pode ter o valor NULL, herdando as variáveis de ambiente do pai

A NULL, a directoria é a mesma do processo pai; caso contrário, deverá incluir a drive e directoria

Inicialização mínima (consultar bib):

STARTUPINFO si = { sizeof(si) }; CreateProcess( ..., &si, ...);

typedef struct _PROCESS_INFORMATION { HANDLE hProcess;

HANDLE hThread; DWORD dwProcessId;

(4)

Parâmetro fdwCreateFlags

• O valor 0 coloca a thread principal do novo processo na fila de

threads Ready

• Controlo da criação do processo

– CREATE_DEBUG, CREATE_SUSPENDED, CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS

• Classes de prioridade:

– REALTIME_PRIORITY_CLASS, HIGH_PRIORITY_CLASS,

ABOVE_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS,

BELOW_NORMAL_PRIORITY_CLASS, IDLE_NORMAL_PRIORITY_CLASS – Normalmente não é especificado: processos criados com a prioridade

(5)

Criação de processo – passos

Convert and validate parameters and flags

Perform Windows-subsystem specific process initialization

Open EXE and create section object Create Windows process

object

Create Windows thread object

Start execution of the initial thread

Return to caller

Set up for new process and thread Final process/image initialization Start execution at entry point Stage 1 Stage 2 Stage 3 Stage 4 Stage 5 Stage 6 Stage 7 Creating process Windows subsystem New process

(6)

Terminação de um processo

• Cenários em que um processo pode terminar

– A função de entrada da thread primária retorna (forma adequada de terminar uma thread)

– Uma thread do processo chama a função ExitProcess (evitar este

método)

– Uma thread noutro processo chama a função TerminateProcess (evitar

este método)

– Todas as threads do processo terminam por si mesmas (raramente acontece)

(7)

Terminação de um processo

A função de entrada da thread primária retorna

• O retorno desta forma garante:

– Qualquer objecto C++ criado pela thread será destruído usando o seu destrutor

– Libertação da memória associada ao stack da thread

– O sistema afecta o código de saída (mantido no objecto kernel do processo) como valor de retorno da função de entrada

– O sistema decrementa o contador de referências do objecto kernel processo

(8)

Terminação de um processo

Função ExitProcess

VOID ExitProcess(UINT fuExitCode);

• Termina o processo e afecta como código de saída o valor do

parâmetro

fuExitCode

• Esta função não retorna

• No runtime C/C++, quando a thread primária retorna da função de

entrada (main), retorna para o código de startup

– Chama as funções registadas (atexit(pfunc)) para serem executadas

na conclusão do programa

– Chama os destrutores dos objectos alocados estaticamente – Aguarda que as threads deste processo terminem

– Chama a função ExitProcess

• Se a thread primária terminar com a função ExitThread, o processo

só termina se não existirem mais threads no processo

(9)

Terminação de um processo

Função TerminateProcess

BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode);

• Distingue-se da função ExitProcess por poder ser chamada por

qualquer thread dentro ou fora do processo

• Usar apenas na condição de não se conseguir terminar o processo

por qualquer outro método

• O sistema garante que os recursos associados ao processo são

completamente eliminados

• Acção de terminação assíncrona o que justifica a chamada da função

WaitForSingleObject para determinar a conclusão do processo

(10)

Terminação de um processo

Todas as threads do processo terminam por si mesmas

• Todas as thread retornam da função de entrada ou chamam a função

ExitThread ou a função TerminateThread

• Numa situação destas, o sistema termina o processo marcando o

código de saída do processo com o valor do código de saída da

última thread que terminou

(11)

Terminação de um processo

Acções realizadas

• Termina as threads ainda existentes no processo

• Todos os objectos User e GDI alocados ao processo são libertados

• Todos os objectos kernel são fechados e eliminados se os

contadores de referências dos objectos atingiram o valor 0

• O código de saída do processo altera de

STILL_ACTIVE (0x103) para

o valor passado na função ExitProcess ou TerminateProcess

• O objecto kernel processo é sinalizado (para efeitos de

sincronização)

• O contador de referências do objecto kernel processo é

decrementado

BOOL GetExitCodeProcess(

HANDLE hProcess,

(12)

Processo filho

PROCESS_INFORMATION pi; DWORD dwExitCode;

// Spawn the child process.

BOOL fsuccess = CreateProcess(..., &pi);

if (fsuccess) {

// Close the thread handle as soon as it is no longer needed!

CloseHandle(pi.hThread);

// Suspend our execution until the child has terminated.

WaitForSingleObject(pi.hProcess, INFINITE);

// The child process terminated; get its exit code.

GetExitCodeProcess(pi.hProcess, &dwExitCode);

// Close the process ahndle as soon as it is no longer needed.

CloseHandle(pi.hProcess);

// Detached child process.

PROCESS_INFORMATION pi; BOOL fsuccess = CreateProcess(..., &pi); if (fsuccess) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); }

(13)

demo11

Terminate process and free resources

• As experiências, de 1 a 5, ilustram o comportamento na libertação dos recursos alocados nas diferentes formas de terminar um processo

(14)

Visão conceptual (simplista) de Processo e Thread

• Processo:

1. Objecto kernel usado pelo sistema operativo para gerir o processo 2. Espaço de endereçamento que contém o módulo executável, DLL’s,

stacks e heaps

• Thread:

1. Objecto kernel usado pelo sistema operativo para gerir a thread

2. Stack da thread onde são mantidos os parâmetros e variáveis locais das

funções em execução no contexto da thread

(15)

Função CreateThread

HANDLE CreateThread(

PSECURITY_ATTRIBUTES psa,

DWORD cbStackSize,

PTHREAD_START_ROUTINE pfnStartAddr,

PVOID pvParam,

DWORD dwCreateFlags,

PDWORD pdwThreadID);

• Na escrita de programas em C/C++ dever-se-á usar a função

_beginthreadex em vez de CreateThread

Pode ter o valor NULL (atributos de segurança por omissão). Pode ser usado para determinar se um objecto processo filho tem acesso ao objecto kernel thread criado por esta função

Memória que ficará committed

inicialmente. O valor 0 usa os valores presentes na imagem do executável.

DWORD WINAPI <threadFuncName>( PVOID param);

O retorno corresponde ao valor de saída (idêntico ao valor de retorno da função main)

Pode ter o valor NULL Valor 0: a thread pode ser colocada de imediato em execução Valor CREATE_SUSPENDED: a thread sai do estado Suspended quando for

(16)

CreateThread steps

1. Transforma parâmetros Windows API em flags nativas e constrói

estrutura nativa que descreve os parâmetros objecto

2. Constrói lista de atributos com duas entradas: client ID e endereço TEB

3. NtCreateThread é chamada para criar o contexto do User. Depois

chama PspCreateThread para criar um objecto Executive thread suspensa

4. CreateThread realiza acções associadas com o stack

5. CreateThread notifica o subsistema Windows acerca da nova thread

para que realize algumas inicializações

6. O handle da nova thread e o seu ID são retornados para o chamador

7. A menos que a thread tenha sido criada com a flag CREATE_SUSPENDED

activa, a thread é colocada na fila de threads ready para ser colocada em execução pelo scheduler. Nessa altura executa o passo 7 descrito na iniciação de um processo já no contexto do User

(17)

Terminação de uma thread

• Cenários em que uma thread pode terminar

– A função correspondente ao ponto de entrada da thread retorna (método adequado)

– A thread mata-se a si própria chamando a função ExitThread (evitar

este método)

– Uma qualquer thread deste processo chama a função TerminateThread

(evitar este método)

(18)

Terminação de uma thread

A função correspondente ao ponto de entrada retorna

• O retorno desta forma garante:

– Todos os objectos C++ criados no âmbito da thread são destruídos apropriadamente com a chamada dos destrutores respectivos

– O sistema liberta a memória associada ao stack da thread

– O sistema afecta o código de saída (mantido no objecto kernel da thread) como valor de retorno da função de entrada

– O sistema decrementa o contador de referências do objecto kernel

thread

(19)

Terminação de uma thread

Função ExitThread

VOID ExitThread(DWORD dwExitCode);

• Termina a thread e o sistema operativo elimina todos os recursos

alocados à thread

• Recursos correspondentes a objectos C/C++ não são devidamente

destruídos

• Esta função não retorna

• Na escrita de programas em C/C++ dever-se-á usar a função

_endthreadex em vez de ExitThread

(20)

Terminação de uma thread

Função TerminateThread

BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);

• Distingue-se da função ExitThread por poder ser chamada por

qualquer thread dentro do processo

• Usar apenas na condição de não se conseguir terminar a thread por

qualquer outro método

• Acção de terminação assíncrona o que justifica a chamada da função

WaitForSingleObject para determinar a conclusão da thread

• Ao contrário da função ExitThread, o stack da thread não é

eliminado com a chamada de

TerminateThread

– Qualquer outra thread que mantenha uma referência para uma variável no stack da thread terminada não recebe excepção quando aceder a essa posição de memória

(21)

Terminação de uma thread

Terminação de um processo

• As funções ExitProcess e TerminateProcess terminam todas as

threads contidas no processo

– Todos os recursos do processo serão eliminados incluindo os stacks das

threads

– Contudo não destrói adequadamente todos os recursos

• Não executa os destrutores dos objectos C++ • Não despeja os buffers em memória no disco • ...

• No runtime C/C++ quando a função

main da thread primária retorna

é chamada a função ExitProcess

(22)

Terminação de uma thread

Acções realizadas

• Liberta todos os handles de objectos User mantidos pela thread

• O código de saída da thread altera de STILL_ACTIVE (0x103) para o

valor passado na função

ExitThread ou TerminateThread

• O objecto kernel thread é sinalizado (para efeitos de sincronização)

• Se a thread for a última thread activa do processo, o sistema

considera o processo terminado também

• O contador de referências do objecto kernel thread é decrementado

BOOL GetExitCodeThread(

HANDLE hThread,

(23)

demo12

Terminate thread and free resources

• As experiências, de 1 a 5, ilustram o comportamento na libertação dos recursos alocados nas diferentes formas de terminar uma thread

(24)

Aspectos internos da thread quando iniciada

VOID RtlUserThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam) { __try {

ExitThread((pfnStartAddr)(pvParam)); }

__except(UnhandledExceptionFilter(GetExceptionInformation())) {

Other CPU registers CONTEXT

Thread Kernel object

Usage count = 2

Exit code = STILL_ACTIVE Suspend count = 1 Signaled = FALSE Other properties and statistics EIP SP pvParam pfnStartAddr . . . . Low address High address VOID RtlUserThreadStart(...) { ... } Thread stack NTDLL.dll

bib: Windows via C/C++, Richter, Nasarre, 5ª edição, fig. 6-1

(25)

Thread scheduling

• Dispatch

– Conjunto de código associado ao despacho de threads, preemptivo e baseado em prioridades

– Execução no âmbito do kernel

– Uma thread tem um tempo limite de posse do CPU (Quantum)

• Uma thread pode usar menos tempo que o seu Quantum

– Quando acontece necessidade de scheduling (context switch)?

• Uma nova thread ficou ready para executar

• A thread corrente em execução deixou o estado ready ou atingiu o seu Quantum • A prioridade de uma thread alterou

• A afinidade de uma thread a um processador alterou

– O sistema Windows é preemptivo

(26)

Dispatcher database

31 0 CPU 0 ready queues Ready summary Deferred Thread 1 Thread 2 Process Thread 3 Thread 4 Process 31 0 CPU 1 ready queues Ready summary Deferred 0 31 31 0 Campo KPRCB Tipo

ReadySummary Bitmask (32 bits)

DeferredReadyListHead Lista simplesmente ligada

DispatcherReadyListHead Array de 32 entradas

(27)

Cenários de Scheduling

• Mudança voluntária

• Preempção

• Fim do quantum

Priority Running Ready 18 ... 16 14 ... To wait state

Priority Running Ready 18

... 16

14 ...

From Wait state

Priority Running Ready 15

14 13

(28)

Níveis de prioridade

• Nativo versus subsistema Windows

• Mapeamento

• Noção de prioridade base e prioridade corrente (no caso de threads)

• Alteração da prioridade base

– software

– comando de linha start (experimentar a aplicação Notepad e observar com o Task Manager)

(29)

Prioridades de processos e threads

Mapeamento entre sistema nativo e subsistema Windows

Real-time Levels 16-31 31 0 15 1 16 Real-time time critical

Real-time idle Dynamic time critical

Dynamic Levels 1-15

Dynamic idle

Level 0: Used for zero page thread; not available to Win32 applications

• Processo: classe de prioridade

Thread:

– Prioridade base = Fx(classe de prioridade, prioridade relativa) – Prioridade corrente = prioridade base + boost priority

• Alteração da classe de prioridade

– Parâmetro fdwCreate da função CreateProcess – Linha de comando, com o comando Start:

> start /low notepad

– Após criação, com a função SetPriorityClass Prioridades nativas

Relative

Thread Priority

Process Priority Class Idle Below Normal Normal Above Normal High Real-Time Time-critical 15 15 15 15 15 31 Highest 6 8 10 12 15 26 Above normal 5 7 9 11 14 25 Normal 4 6 8 10 13 24 Below normal 3 5 7 9 12 23 Lowest 2 4 6 8 11 22

(30)

Programação de prioridades

Funções relevantes

(31)

Estados da thread

Ready (1)

Thread à espera para ser executada;

O dispatcher olha para este pool de threads quando procura por uma thread para colocar em execução

Deferred ready (7): threads que foram seleccionadas para execução num determinado

CPU mas que ainda não foram scheduled

Standby (3): thread seleccionada para ser a próxima a correr num determinado CPU;

apenas uma thread neste estado por CPU no sistema

Running (2)

Uma thread entra no estado Running quando o dispatcher executa o Context SwitchA execução continua até terminar o seu quantum, ser preemptida por outra thread

com maior prioridade, terminar, ou entrar no estado Wait voluntariamente

Waiting (5)

– Entra neste estado: por vontade própria (objectos de sincronização); o sistema operativo entrou no estado Wait no contexto da thread; entre outros

– Quando sai deste estado poderá ser colocada de novo em execução ou na lista de

threads Ready

Gate Waiting (8): entra neste estado quando espera por um objecto gate dispatcher (cap. 3)

Transition (6): entra neste estado quando a thread está preparada para execução mas ainda lhe faltam recursos em memória (kernel stack)

Terminated (4): entra no estado quando a thread termina a execução

(32)

Transição entre estados numa thread

Ready Waiting or Gate waiting Deferred ready Transition Init Terminate Standby Running preempt preemption, quantum end voluntary switch

(33)

Quantum

• Quantidade de tempo que uma thread possui o CPU

– A partir do Window Vista = 2 intervalos de clock – Windows Server 2008 = 12 intervalos de clock – 1 intervalo de clock (aproximadamente)

• x86, uniprocessador = 10 ms

• 64bits ou multiprocessador = 15 ms

• Quantum boosting

– Quando um processo é colocado em foreground as threads têm o seu quantum triplicado

(34)

Afinidade a CPUs

CPU0 CPU1 CPU2 CPU3 Memory Board 1 CPU4 CPU5 CPU6 CPU7 Memory Board 2 CPU8 CPU9 CPU10 CPU11 Memory Board 3 NUMA Machine

(35)

Linhas de cache num contexto multiprocessador

• Cenário:

– CPU1 lê 1 byte. O byte solicitado e adjacentes são carregados na cache do CPU1

– CPU2 lê o mesmo byte. Os mesmos bytes são carregados na cache do CPU2

– CPU1 altera o byte lido

• O respectivo byte na cache do CPU2 fica inválido; a arquitectura garante a marcação como inválida da linha de cache do CPU2

• Boas práticas:

– Um CPU deverá ter as suas variáveis em memória agrupadas numa linha de cache: as variáveis de um programa que sejam acedidas num intervalo de tempo curto deverão ser declaradas próximas

– Evitar que dois ou mais CPU’s partilhem variáveis em memória: threads que partilhem recursos deverão ter afinidade ao mesmo CPU

– Separar dados de leitura apenas dos dados que serão lidos e escritos

• Usar a directiva para o compilador C/C++ __declspec(align(#)) int __declspec(align(CACHE_ALIGN)) var;

(36)

Como garante o sistema justiça na distribuição do CPU

Priority boost

• Cenários onde pode acontecer um priority boost

(as unidades incrementadas dependem do cenário em causa)

1. Na conclusão de uma operação I/O completion

2. Depois de concluir uma acção de espera por eventos ou semáforos

3. Depois das threads de um processo foreground completarem uma

operação de Wait

4. Quando threads GUI acordam

5. Quando uma thread está Ready há demasiado tempo sem ser colocada

em execução (CPU starvation)

• Por cada quantum gasto em execução é decrementada a sua

prioridade até atingir o valor da prioridade base

– Uma thread nestas condições pode ser preemptida por outra de maior prioridade; a thread não perde o seu quanto de execução com a

(37)

Priority boost

Funções relevantes

BOOL SetProcessPriorityBoost( HANDLE hProcess,

BOOL bDisablePriorityBoost); // true: disable all

// process thread’s boost BOOL GetProcessPriorityBoost(

HANDLE hProcess,

PBOOL pbDisablePriorityBoost); BOOL SetThreadPriorityBoost(

HANDLE hThread,

BOOL bDisablePriorityBoost); // true: disable thread // boost

BOOL GetThreadPriorityBoost( HANDLE hThread,

(38)

Idle thread

• Idle thread é a thread com menor prioridade (incluindo a Zero Page

thread com nível de prioridade 0)

• A Idle thread, na realidade, não tem prioridade

• Apenas é colocada em execução quando não existir nenhuma outra

thread no estado Ready

(39)

Threads Schuduling

•Funções utilizadas na demo:

– SetProcessAffinityMask; – SetThreadAffinityMask; – SetThreadPriority;

– SetProcessPriorityBoost – SuspendThread;

(40)

Considerações sobre a biblioteca runtime C/C++

• Preocupações com a biblioteca standard do C num cenário de

programação concorrente

– A biblioteca na sua génese não previa execução concorrente – Variáveis com alocação estática: errno, strtok, strerror, ...

• Solução:

– Cada thread tem as variáveis globais da biblioteca reunidas num bloco – O bloco fica alojado num espaço de endereçamento pertencente à

thread (TLS – Thread Local Storage)

• Problema: Como associar o bloco a uma thread?

• Solução: Chamando a função

_beginthreadex em vez da função

CreateThread

(41)

Função _beginthreadex (pseudocódigo)

O chamador deverá mapear os tipos dos argumentos da função CreateThread para a função _beginthreadex

uintptr_t __cdecl _beginthreadex( void* psa, unsigned cbStackSize,

unsigned (__stdcall * pfnStartAddr) (void*), void* pvParam,

unsigned dwCreateFlags, unsigned * pdwThreadID) { _ptiddata ptd; // Pointer to thread’s data block

uintptr_t thdl; // Thread handles // Allocate data block for the new thread

if ((ptd = (_ptiddata)_calloc_crt(1, sizeof(struct _tiddata))) ==NULL) goto error_return;

initptd(ptd); // Initialize data block

// Save desired thread function and parameter

ptd->_initaddr = (void*)pfnStartAddr; ptd->_initarg = pvParam;

ptd->handle = (uintptr_t)(-1); // Create the new thread

thdl = (uintptr_t)CreateThread((LPSECURITY_ATTRIBUTES)psa, cbStackSize, _threadstartex, (PVOID)ptd, dwCreateFlags, pdwThreadID);

if (thdl == 0) goto error_return; return (thdl); error_return: _free_crt(ptd); return ((uintptr_t)0L); }

Considerações sobre a biblioteca runtime C/C++

As funções _beginthreadex, _threadstartex, _callthreadstartex e _endthreadex estão definidas no módulo <Visual Studio pathname>\vc\crt\src\threadex.c

(42)

Função _threadstartex (pseudocódigo)

static unsigned long WINAPI _threadstartex( void* ptd) {

// Associate the tiddata block with this thread so _getptd() // will be able to find it in _callthreadstartex

TlsSetValue(__tlsindex, ptd);

((_ptiddata)ptd)->_tid = GetCurrentThreadId(); // save this thread ID // ... initializations not relevant

_callthreadstartex(); // call helper function

// The execution code should never reach here //(the thread dies in _callthreadstartex)

return (0L); }

(43)

Função _callthreadstartex (pseudocódigo)

static void _callthreadstartex( void* ptd) {

_ptiddata ptd; // Pointer to thread’s data block

// Get the pointer to thread data from TLS

ptd = _getptd();

// Wrap desired thread function in SEH frame to handle run-time // errors and signal support

__try {

// Call desired thread function, passing it he desired parameter // Pass thread’s exit code value to _endthreadex

_endthreadex(

((unsigned (WINAPI*)(void*))(((_ptiddata)ptd)->_initaddr))

(((_ptiddata)ptd)->_initarg) );

}

__except(_XcptFilter(GetExceptionCode(), GetExceptionInformation())) {

// The execution code should never reach here

_exit(GetExceptionCode()); }

}

(44)

Função _endthreadex (pseudocódigo)

void __cdecl _endthreadex( unsigned retcode ) {

_ptiddata ptd; // Pointer to thread’s data block

// Not relevant cleanup

// Get the address of this thread’s tiddata block

ptd = _getptd_noexit(); // Free the tiddata block

if (ptd != NULL) _freeptd(ptd);

// Terminate the thread

ExitThread(retcode); }

(45)

Definição de errno

_CRTIMP extern int * __cdecl _errno (void);

#define errno (*_errno())

int * __cdecl _errno(void) {

_ptiddata ptd = _getptd_noexit(); if (!ptd) return &ErronoNoMem; else return (&ptd->_terrno); }

Considerações sobre a biblioteca runtime C/C++

int * p = &errno; if (*p == ENOMEM) { ...

(46)

Considerações sobre a biblioteca runtime C/C++

Bibliotecas runtime C/C++

• Bibliotecas usadas com o Microsoft Visual Studio

– LibCMt.lib, para ligação estática

– LibCMtD.lib, para ligação estática com debug

– MSVCRt.lib, para ligação dinâmica com a DLL MSVCR80.dll (biblioteca usada por omissão na criação de um novo projecto)

– MSVCRtD.lib, para ligação dinâmica com a DLL MSVCR80.dll com debug – MSVCMRt.lib, usada no âmbito de código managed e código nativo – MSVCURt.lib, biblioteca compilada com código 100% MSIL

• Caminho da configuração da biblioteca a usar no Visual Studio

– Project Properties → Configuration Properties → C/C++ → Code Generation – Escolher uma das bibliotecas associadas ao campo Runtime Library

• Funções da biblioteca que nunca deverão ser usadas

– unsigned long _beginthread(

void (__cdecl *start_address)(void *) unsigned stack_size,

void * arglist); – void _endthread(void);

(47)

Tempos associados à execução de uma thread

ULONGLONG GetTickCount64();

// Não considera a preempção

BOOL GetThreadTimes(HANDLE hThread,

PFILETIME pftCreationTime,

// valor absoluto desde 1 de Janeiro de 1601

PFILETIME pftExitTime,

// valor absoluto desde 1 de Janeiro de 1601

PFILETIME pftKernelTime,

// valor relativo gasto em kernel mode

PFILETIME pftUserTime);

// valor relativo gasto em user mode

• PFILETIME expresso no número de intervalos de 100 nano-segundos

• Funções adequadas para medir intervalos de tempo longos (fraca

precisão)

– O tempo de CPU de uma thread é contabilizado com base num temporizador que gera ciclos entre os 10 e 15 ms

BOOL GetProcessTimes(<same as GetThreadTimes>);

// Tempo

gasto por todas as threads do processo

(48)

Time Stamp Counter (contador de alta resolução)

• Time Stamp Counter: contador de 64 bits do processador que conta

o número de ciclos desde que a máquina iniciou

BOOL QueryThreadCycleTime(HANDLE ThreadHandle,

PULONG64 CycleTime);

BOOL QueryProcessCycleTime(HANDLE ProcessHandle,

PULONG64 CycleTime);

• Número de ciclos atribuídos a uma thread ou a todas as threads de

um processo (considera a preempção)

#define ReadTimeStampCounter()

• Macro definida no WinNT.h que retorna o valor do contador TSC (usa

a função intrínseca

__rdtsc providenciada pelo compilador C++)

• Funções medidoras de tempo de alta resolução

BOOL QueryPerformanceFrequency(LARGE_INTEGER* pliFrequency); BOOL QueryPerformanceCounter(LARGE_INTEGER* pliCount);

(49)

Bibliografia

• “Windows internals”, Russinovich e Solomon, cap. 5, 5ª edição

• “Windows via C/C++”, Richter e Nasarre, cap. 4, 6 e 7, 5ª edição

• MSDN - windows development

(50)
(51)

Bloco EPROCESS (Executive Process Block)

Estrutura de dados que representa um processo

Kernel process block (or PCB)

Process ID Parent process ID

Exit status Create and exit times

Active process link Quota block

Memory management information Exception port

Debugger port

Device map

Process environment block

Image filename Image base address Process priority class

Windows process block Job object

Primary access token Handle table

EPROCESS PsActiveProcessHead

(52)

Bloco KPROCESS (Kernel Process Block or PCB)

Estrutura de dados

Dispatcher header Kernel time

User time

Inswap/Outswap list entry Process spinlock

Process affinity

Resident kernel stack count Process base priority Default thread quantum

Process state Thread seed Disable boost flag

Process page directory

bib: Windows internals, Russinovich, Solomon, fig. 5-3

(53)

Bloco PEB (Process Environment Block)

Estrutura de dados

Image base address Module list

Thread-local storage data Code page data Critical section timeout

Number of heaps Heap size information GDI shared handle table

Operating system version number information Image version information

Image process affinity mask

Process heap

(54)

Variáveis kernel, contadores de performance e funções

relacionados com processos

• Fica apenas a referência dado o volume de informação

– “Windows Internals”, Russinovich e Solomon, Cap. 5 – Variáveis kernel: tabela 5-2

– Contadores de performance: tabela 5-3 – Funções relevantes: tabela 5-4

(55)

Bloco ETHREAD (Executive thread block)

Estrutura de dados que representa uma thread

KTHREAD Create and exit times

Process ID Thread start address Impersonation information

ALPC message information Timer information

EPROCESS Access token

Pending I/O requests TEB

(56)

Bloco KTHREAD (Kernel thread block)

Estrutura de dados

Dispatcher header Total user time Total kernel time

Thread-scheduling information Trap frame

Synchronization information List of pending APCs

Kernel stack information System service table

Thread-local storage array

TEB Timer block and wait block

List of objects thread is waiting on

(57)

Bloco TEB (Thread environment block)

Estrutura de dados

Exception list Stack base Stack limit Thread ID Active RPC handle LastError value

Count of owned critical sections

Subsystem thread information block (TIB) Fiber information

PEB

Current locale User32 client information

GDI32 information OpenGL information

TLS array

Winstock data

(58)

Variáveis kernel, contadores de performance e funções

relacionados com threads

• Fica apenas a referência dado o volume de informação

– “Windows Internals”, Russinovich e Solomon, Cap. 5 – Variáveis kernel: tabela 5-11

– Contadores de performance: tabela 5-12 – Funções relevantes: tabela 5-13

(59)

Funções da Windows API que promovem scheduling

(60)

Prioridades de processos e threads

Mapeamento entre sistema nativo e subsistema Windows

• Alteração da classe de prioridade

– Na criação com a função CreateProcess

Real-time Levels 16-31 31 0 15 1 16 24 Real-time time critical

Real-time idle Dynamic time critical

Dynamic Levels 1-15

Dynamic idle

Used for zero page thread; not available to Win32 applications Real-time High Above Normal Normal Below Normal Idle 13 10 8 6 4

• Processo: classe de prioridade

Thread:

– Prioridade base =

Fx(classe de prioridade, prioridade relativa) – Prioridade corrente

bib: Windows internals, Russinovich, Solomon, fig. 5-13

Prioridades lógicas Prioridades nativas

(61)

Prioridades de processos e threads

Mapeamento entre sistema nativo e subsistema Windows

Relative Thread Priority

Process Priority Class

Idle Below Normal Normal Above Normal High Real-Time Time-critical 15 15 15 15 15 31 Highest 6 8 10 12 15 26 Above normal 5 7 9 11 14 25 Normal 4 6 8 10 13 24 Below normal 3 5 7 9 12 23 Lowest 2 4 6 8 11 22 Idle 1 1 1 1 1 16

Referências

Documentos relacionados

intitulado “O Plano de Desenvolvimento da Educação: razões, princípios e programas” (BRASIL, 2007d), o PDE tem a intenção de “ser mais do que a tradução..

Esta dissertação pretende explicar o processo de implementação da Diretoria de Pessoal (DIPE) na Superintendência Regional de Ensino de Ubá (SRE/Ubá) que conforme a

[r]

De acordo com o Consed (2011), o cursista deve ter em mente os pressupostos básicos que sustentam a formulação do Progestão, tanto do ponto de vista do gerenciamento

No final, os EUA viram a maioria das questões que tinham de ser resolvidas no sentido da criação de um tribunal que lhe fosse aceitável serem estabelecidas em sentido oposto, pelo

insights into the effects of small obstacles on riverine habitat and fish community structure of two Iberian streams with different levels of impact from the

A versão reduzida do Questionário de Conhecimentos da Diabetes (Sousa, McIntyre, Martins &amp; Silva. 2015), foi desenvolvido com o objectivo de avaliar o

Taking into account the theoretical framework we have presented as relevant for understanding the organization, expression and social impact of these civic movements, grounded on