La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Windows internals http://www.microsoft.com/italy/msdn/studenti scoriani@microsoft.com.

Presentazioni simili


Presentazione sul tema: "Windows internals http://www.microsoft.com/italy/msdn/studenti scoriani@microsoft.com."— Transcript della presentazione:

1 Windows internals http://www.microsoft.com/italy/msdn/studenti

2 Benvenuti Un giorno di full immersion nel kernel di Windows
Architettura del kernel Come funziona Come sfruttarlo al meglio Come analizzare i problemi

3 Agenda Architettura kernel di Windows Gestione della memoria Processi
Thread Thread pool Jobs Interprocess communication Overlapped I/O Domande & Risposte

4 Architettura kernel di Windows

5 MS Windows NT: obiettivi del progetto
Compatibilità applicazioni Win32, Win16, MS-DOS, OS/2, POSIX Portabilità Ieri: piattaforma Intel, RISC Oggi: IA-32 (Pentium), IA-64 (Itanium) A breve: AMD-64 (Opteron) Robustezza Estendibilità Performance binaria, sorgente, file system

6 Portabilità Laptop Computer Personal Server Symmetric Multiprocessors

7 Architettura di MS Windows NT
I/O Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER

8 Robustezza: Spazi di indirizzamento separati
System Memory (2 GB) Per-Process Paged Non-paged Physical Addressing Range

9 Robustezza: User Mode e Privileged-Processor Mode
applicazioni in esecuzione Accesso esclusivamente allo spazio di indirizzamento dei processi Divieto di accesso diretto all’hardware Privileged-Processor Mode Contiene il codice di sistema: executive, drivers, kernel e HAL “Trusted” Può eseguire qualsiasi istruzione Accesso all’intero spazio di indirizzamento

10 Robustezza: Security Per-User Permissions Auditing Access
Access Control List (ACL) Auditing Access Quotas (sempre presente, non implementato fino a Windows 2000)

11 Robustezza: i sottosistemi
User Mode Win32-Based Application POSIX OS/2 Subsystem Win32 Subsystem Local Procedure Call Executive Send Reply Privileged-Processor Mode

12 Applications and Subsystems (User-Mode Instruction Set)
Estendibilità I/O Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER Jobs Timer Queue Encryption NTFS-5 NTFS FAT

13 Gli oggetti di NT (kernel objects)
Process Thread Section File Access Token Event Semaphore Mutex Registry

14 Object model L’object model consente di: monitorare le risorse
implementare la sicurezza condividere le risorse

15 Object: struttura interna
Object Name Object Directory Security Descriptor Quota Charges Open Handle Counter Open Handle Database Permanent/Temporary Kernel/User Mode Type Object Pointer Object Body Type Object Header Object Attributes

16 Object: interfaccia esterna
Funzioni Parametri comuni Createxxx Security attributes, inheritance, name Openxxx Security attributes, inheritance, name BOOL CloseHandle(hObject) BOOL DuplicateHandle(hSourceProcess, hSource, hTargetProcess, lphTarget, fdwAccess, fInherit, fdwOptions) Lo scope di un Object Handle è relativo a ogni singolo processo Durata di un oggetto

17 Struttura SECURITY_ATTRIBUTES
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES;

18 Security Detail Access Token Event Object Access Control List
Security ID: LEES Group IDs: TEAM1 TEAM2 LOCAL INTERACTIVE WORLD Privileges: None . Security Descriptor Allow LEES Synchronize Modify State TEAM1 Access Token Event Object Access Control List

19 Architettura Windows NT/2000
Radici nel passato (VMS) Disegno modulare ed estendibile Pochi cambiamenti e molte ottimizzazioni dal kernel di Windows NT 3.1 a quello di Windows 2000 Modello ad oggetti, ma non object-oriented

20 Gestione della memoria (Memory Manager)

21 Gestione della memoria
I processori iAPX86 Indirizzamenti real-mode e protected-mode Funzioni API Condivisione della memoria VLM – Very Large Memory AWE – Address Windowing Extension

22 I Processori Intel iAPX86
Tutti eseguono il boot in Real Mode Su 8088/8086 è l’unica possibilità Su 286 e successivi è necessario per compatibilità Dopo il boot 286 e successivi possono passare al protected mode Tutti hanno un’architettura segmentata

23 Indirizzamento in real-mode
15 15 : segment offset (shift left by 4 bits) 19 4 3 19 16 15 segment’s base address effective address + 1 MB RAM 19 linear address 220 = 1MB

24 Real-mode Nessun meccanismo di protezione della memoria
Diverse combinazioni segment:offset indirizzano la stessa locazione di memoria fisica Nessun supporto hardware nativo per una efficacie implementazione del multitasking Microsoft ha inventato una implementazione software del multitasking per Windows 1.x

25 Protected-mode (32 bit) : ? GDT LDT selector offset RAM BASE ACC.
15 2 1 31 : selector T I RPL offset GDT 15 16GB/ 64TB BASE ACC. LIMIT ACCESS x 8192 BA+SS ? 63 48 BA LDT 15 SEGMENT 1 BASE ACC. LIMIT ACCESS TI = Table Index RPL = Requestor Privilege Level GDT = Global Descriptors Table (64KB) LDT = Local Descriptors Table (64KB) BASE = BA = Base Address (32 bit) LIMIT = Limit (20 bit) = 1 MB ACC. = ACCESS = Access Byte (12 bit) SS = Segment Size x 8192 63 48 RAM G D A V L P DPL S TYPE Struttura Interna Access Byte G = 0  SS = Limit x 1 Byte = 1 MB G = 1  SS = Limit x 1 Page = Limit x 4KB = 4GB (G = Granularity Bit)

26 Protected-mode (32 bit) Se la granularità è una pagina (4KB), ciascun segmento è da 4GB e lo spazio di indirizzamento virtuale è di 64TB! Il descriptor è comunque compatibile con 16 bit PM L’architettura è comunque segmentata e limita la portabilità Tipicamente le piattaforme RISC non hanno architettura segmentata…

27 Eliminare la Segmentazione
In Win95 e WinNT, il sistema operativo utilizza un solo segmento da 4GB In pratica, l’indirizzamento in Win32 è basato esclusivamente sull’offset (32 bit) L’indirizzamento appare lineare (o flat) Questo assicura la portabilità ad architetture non segmentate (es. RISC) Win32 indirizza fino a 4GB RAM fisica Tuttavia la strategia di implementazione è basata sulle Pagine La quantità minima di memoria allocabile è la pagina = 4KB

28 Perchè Paginare la Memoria
Se l’offset fosse usato come un riferimento diretto alla locazione di memoria, lo spazio di indirizzamento virtuale coinciderebbe con la RAM fisica installata Per indirizzare 4GB virtuali, sarebbe necessario disporre di 4GB di RAM fisica in ogni sistema! La paginazione consente di simulare uno spazio di indirizzamento fisico da 4GB anche se la RAM fisica installata è <4GB Remapping della memoria fisica sulla memoria virtuale Paginazione su disco Exceptions generate dal processore e gestite dal sistema operativo

29 32 bit Offset in Win32 i386 PDE (10 bit) PTE (10 bit) OFFSET (12 bit)
31 22 21 12 11 PDE (10 bit) PTE (10 bit) OFFSET (12 bit) 20 bits 12 bits 20 bits 12 bits 4GB 1023 1023 PAGE 4KB Page Directory Page Table Win32 Process Context CR#3 i386 RAM PDE = Page Directory Entry PTE = Page Table Entry CR#3 = Control Register #3

30 Spazio di indirizzamento
System Memory (2 GB) Per-Process Paged Non-paged Physical Addressing Range

31 Memoria virtuale R e s r v d Process Address Space Physical Memory
Page Tables Physical Memory Invalid Process Address Space 2 GB Committed Pages R e s r v d

32 Page Directory, Page Table, Page Frame
4 MB 8 MB 12 MB 2 GB Directory 1024 Entries Table Paging File Byte Within Page 10 Bits 12 Bits Directory Index Table Index Valid Paged Invalid Virtual Address Space 4K Frame Physical Memory

33 Paging File Contiene Pagine scambiate dalla Memoria RAM al Disco
Dimensione pagina: 4K o 8K Paging Policy

34 Page Commitment Process Address Space 2 GB Committed Pages R e s r v d

35 Copy-on-Write e Guard Pages
Page 2 Copy Committed Memory Process 2 Virtual Process 1 (Read-Write) Section

36 Funzioni API: VirtualAlloc
Manipolazione pagine virtuali o spazi di indirizzamento Lettura stato pagine virtuali o spazi di indirizzamento LPVOID VirtualAlloc(lpvAddress, cbSize, fdwAllocationType, fdwProtect) BOOL VirtualFree(lpAddress, cbSize, fdwFreeType) BOOL VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect) DWORD VirtualQuery(lpAddress, pmbiBuffer,cbLength) BOOL VirtualLock(lpvAddress, cbSize) BOOL VirtualUnlock(lpvAddress, cbSize)

37 Esempio: Uso di Funzioni VirtualXXX
... lpBase = VirtualAlloc (NULL, my_size, MEM_RESERVE, PAGE_NOACCESS); __try{ // an EXCEPTION_ACCESS_VIOLATION here // will be fixed by MyFilter if possible } __except (MyFilter (GetExceptionInformation())) { VirtualFree (lpBase, 0, MEM_RELEASE);

38 Gestione Heap Lo Heap è ottimizzato per allocare blocchi di memoria più piccoli senza l’overhead di pagina (4k o 8k) Ogni processo ha uno Heap di default E’ possibile allocare Heap privati La memoria allocata in uno heap può portare a fenomeni di frammentazione Sono Thread-Safe per default

39 Funzioni API: HeapAlloc
Allocazione di un Heap privato HANDLE HeapCreate(flOptions, dwInitialSize, dwMaximumSize) BOOL HeapDestroy(hHeap) LPVOID HeapAlloc(hHeap, dwFlags, dwBytes) BOOL HeapFree(hHeap, dwFlags, lpMem) DWORD HeapSize(hHeap, dwFlags, lpMem) LPVOID HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes) Sono Thread-Safe per default

40 Funzioni API: LocalAlloc/GlobalAlloc
Tutti i puntatori sono valori a 32 bit LocalAlloc e GlobalAlloc allocano memoria dallo stesso Heap GlobalAlloc garantisce allocazioni con allineamento a 16 bit HGLOBAL GlobalAlloc(fuFlags, cbBytes) HLOCAL LocalAlloc(fuFlags, cbBytes) Presenti solo per ragioni di compatibilità: richiamano HeapAlloc

41 Funzioni API: C Run-Time Library
Le funzioni delle Standard C Run-Time Libraries possono essere usate (malloc, calloc, free, realloc, ...) Bilanciare chiamate malloc() con free(), senza mischiare con GlobalFree(), HeapFree() o altro

42 Memory-Mapped File I Memory-Mapped Files consentono di condividere la memoria tra processi diversi Sono l’equivalente Win32 dell’oggetto kernel Section

43 Viste di Memory-Mapped File
PG.SYS File Physical Memory Views Sections

44 FileMapping: le cose ovvie
Il file è mappato in memoria come se fosse effettivamente caricato Gli indirizzi di memoria necessari ad effettuare il mapping devono essere riservati Solo le pagine effettivamente utilizzate (a cui si accede in lettura o in scrittura attraverso puntatori di memoria) vengono effettivamente lette/scritte su disco Il Paging File usato come Memory Mapped File non rende persistenti le operazioni effettuate in memoria

45 File Mapping: le cose meno ovvie
Tutte le operazioni di I/O su file avvengono come operazioni di file-mapping La cache dell’I/O Manager è integrata con il Memory Manager Tutte le volte che si apre un eseguibile (.EXE, .DLL, .OCX), il codice e le risorse non vengono caricate in memoria fino a che non sono realmente utilizzate (anche queste sono operazioni di file-mapping) Caricando più volte la stesso file EXE/DLL da processi diversi, la memoria fisica impegnata è sempre la stessa

46 CreateFileMapping e OpenFileMapping
Crea un oggetto Section HANDLE CreateFileMapping(hFile, lpsa, fdwProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpszMapName) Apre un oggetto Section HANDLE OpenFileMapping(dwDesiredAccess, bInheritHandle, lpszMapName) Assegnando a hFile il valore –1 si usa il PagingFile

47 MapViewOfFile e UnmapViewOfFile
LPVOID MapViewOfFile(hMapObject, fdwAccess, dwOffsetHigh, dwOffsetLow, cbMap) BOOL UnmapViewOfFile(lpBaseAddress) BOOL FlushViewOfFile(lpvBase, cbFlush) UnmapViewOfFile scrive tutti i cambiamenti su disco Lazy Writes su disco delle scritture in memoria E’ garantita la coerenza di viste differenti di un singolo oggetto Section

48 Usare Memory-Mapped File come Shared Memory
Process 2 Virtual Memory Process 1 Committed Section View

49 Gestione della memoria
Superare il muro dei 4Gb con Win32 Solo per i dati, non per il codice VLM – Very Large Memory Solo su Windows 2000 Advanced Server Solo per processori a 64 bit, ad oggi solo Alpha, che non supporta più Windows 2000 AWE – Address Windowing Extension Su tutte le versioni di Windows 2000 Per tutti i processori a 32 e 64 bit (Win64) Meno comodo da usare...

50 AWE – Address Windowing Extension
Per tutti i processori e per tutte le versioni di Windows 2000 Memoria mappata nello spazio virtuale disponibile al processo (2Gb/3Gb) Non funziona con funzioni grafiche/video Granularità 4K/8K Il processo deve essere abilitato (diritto Lock Pages in Memory) Una zona allocata con AWE non può essere condivisa con altri processi

51 AWE – Funzioni AllocateUserPhysicalPages VirtualAlloc
MapUserPhysicalPages FreeUserPhysicalPages AllocateUserPhysicalPages – Allocazione di memoria fisica con AWE VirtualAlloc – con parametro MEM_RESERVE or MEM_PHYSICAL riserva una spazio di indirizzi per mappare una zona allocata con AWE MapUserPhysicalPages – Map/Unmap della memoria fisica allocata con AllocateUserPhysicalPages ad uno spazio di indirizzi riservato con VirtualAlloc FreeUserPhysicalPages – Libera la memoria fisica allocata con AllocateUserPhysicalPages

52 Gestione della memoria
Introduzione architetturale Funzioni API Memory mapped file Condivisione della memoria VLM & AWE

53 Processi

54 Cosa è un Processo? Un istanza di un programma in esecuzione
Un processo possiede degli Oggetti Gli oggetti sono rappresentati dagli Handle Cosa distingue un processo da un altro? Handle table Memoria privata Windows Il processo è un insieme di thread, ed esiste fino a che contiene almeno un thread

55 Win32-Based Process Model
. . . Access Token Virtual Address Space Description Object Table Thread x File y Section z Available Objects Handle 1 Handle 2 Handle 3

56 Object Handle Ogni Object Handle Tipi di Object Handle
E’ valido solo nel contesto del proprio processo Può essere ereditato Mantiene un oggetto in vita nel sistema fino a che tutti gli handle allo stesso oggetto non sono chiusi Tipi di Object Handle Private: CreateMutex, OpenSemaphore, ... Duplicated: BOOL DuplicateHandle(...) Inherited: fInheritHandles a TRUE in CreateProcess Pseudo: GetCurrentProcess(), GetCurrentThread(), ...

57 Ciclo di vita di un Processo
Un processo viene creato associando sempre un file eseguibile (.EXE), che è mappato in memoria ed eseguito Creando un processo viene creato un thread Il primo thread di un processo può essere chiamato thread principale, anche se la sua chiusura non determina necessariamente la fine del processo La run-time library del C termina il processo corrente se si esce dalla funzione main() con return, indipendentemente dalla presenza di altri thread

58 Creazione di un Processo
BOOL CreateProcess(lpszImageName, lpszCommandLine, lpsaProcess, lpsaThread, fInheritHandles, fdwCreate, lpvEnvironment, lpszCurDir, lpsiStartInfo, lppiProcInfo) HANDLE OpenProcess(fdwAccess, fInherit, IDProcess)

59 Informazioni ritornate dalla creazione di un Processo
typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION; Gli handle hProcess e hThread vanno sempre chiusi con CloseHandle(hObject) quando non sono più utilizzati E’ un errore frequente dimenticare questa operazione su entrambi gli handle restituiti!

60 Chiudere un Processo Chiusura normale Chiudere l’handle ad un processo
VOID ExitProcess(uExitCode) Chiudere l’handle ad un processo BOOL CloseHandle(hObject) Chiusura immediata (e anomala) di un processo BOOL TerminateProcess(hProcess, uExitCode) La chiusura dell’ultimo thread di un processo implica una chiamata ad ExitProcess()

61 Funzioni API LPTSTR GetCommandLine(VOID)
HANDLE GetCurrentProcess(VOID) DWORD GetCurrentProcessId(VOID) VOID GetStartupInfo(lpsi) HANDLE OpenProcess(fdwAccess, fInherit, IDProcess) DWORD GetEnvironmentVariable(lpszName, lpszValue, cchValue) BOOL SetEnvironmentVariable(lpszName, lpszValue) LPVOID GetEnvironmentStrings(VOID)

62 Interprocess Communication (IPC)
IPC viene realizzata quando due o più processi condividono un oggetto Gli oggetti usati per IPC includono: Shared memory (section object) Files Semaphores Pipes / Mailslot Windows sockets I metodi di accesso condiviso sono gli stessi per molti oggetti di tipo diverso

63 Condivisione di oggetti
Può avvenire in tre modi: BOOL DuplicateHandle(hSourceProcess, hSource, hTargetProcess, lphTarget, fdwAccess, fInherit, fdwOptions) Creando o aprendo un “Named Object” Ereditarietà

64 Condivisione di oggetti
Gli oggetti condivisi sono handle diversi che puntano allo stesso oggetto kernel Thread x Process A Object Table Thread y File k Section z Kernel Objects Handle 1 Handle 2 Handle 3 Process B File w

65 Ereditarietà Access Token Process A Granted Access Inheritance
Thread x File y Section z Available Objects Handle 1 Handle 2 Handle 3 Object Table Granted Access Inheritance

66 Ereditarietà Gli oggetti condivisi attraverso ereditarietà assumono lo stesso valore di Handle CreateProcess(…) Process A Object Table Thread y File k Section z Kernel Objects Handle 1 Handle 2 Handle 3 Process B Object Table Handle 1 Handle 2 Handle 3 Thread x

67 Controllare l’ereditarietà
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES; BOOL bInheritHandle;

68 Processi Achitettura Object Handle Ciclo di vita di un processo
Condivisione di oggetti Ereditarietà

69 Thread

70 Cosa è un Thread? Un thread è un percorso di esecuzione all’interno di un processo Un thread accede a tutte le risorse del processo in cui è contenuto Il ThreadID contraddistingue un thread nel sistema operativo, indipendentemente dal processo ospitante Un thread esiste fino a che: il percorso di esecuzione termina viene chiuso con ExitThread viene chiuso/distrutto il processo ospitante

71 Preemptive vs. Cooperative
Thread 2 Preemptive (Windows NT) Thread 1 Processor Done Task 2 Cooperative (Windows 3.1) Task 1 Time I/O or Idle Executing Involuntary Voluntary

72 Win32 Preemptive Multitasking
Thread 1 Thread 2 Process A Process B Process C Process D Thread 3 Process E System Scheduler i386

73 Perché usare thread multipli?
I thread sono più economici dei processi Per dividere task paralleli Per supportare la concorrenza Perché i thread comunicano più velocemente Per sfruttare Symmetric Multiprocessing

74 Thread Overhead Ogni thread Win32 ha un “gemello” nel sottosistema Host Ci sono due stack per ogni thread C’è un Hardware Context per thread C’è un insieme di variabili statiche delle C Run-Time Library per thread

75 Schedulazione dei Thread
Lo Scheduler Win32 : Schedula soltanto thread E’ preemptive E’ basato sulle priorità

76 Scheduler Lo scheduler conosce solo i Thread
Ogni Thread ha due livelli di priorità Priorità di base Priorità corrente La priorità corrente è analizzata per decidere quale thread eseguire Non spiegare troppo come viene usato il livello di priorità corrente, arrivano le slide più avanti.

77 Scheduler La priorità di base è funzione di due valori:
Classe di priorità del processo Valore di priorità del thread La priorità corrente è dinamica (viene variata dallo scheduler), ma non scende mai al di sotto della priorità di base

78 Priorità di processi e thread
IDLE BELOW_NORMAL NORMAL ABOVE_NORMAL HIGH REALTIME Thread IDLE LOWEST BELOW_NORMAL NORMAL ABOVE_NORMAL HIGHEST TIME_CRITICAL La combinazione di classe di priorità di processo e thread determina il valore di priorità di base del thread (tra 0 e 31)... NT non abbassa la priorirità di un thread al di sotto del valore di base definito.

79 Calcolo priorità di base dei thread
Realtime Time Critical 31 Realtime Realtime Livelli 16-31 24 Realtime Idle 16 High Dynamic Time Critical 15 13 Above Normal Normal Dynamic Livelli 1-15 10 Below Normal 8 Idle 6 4 Dynamic Idle System Idle

80 Scheduler Logica di funzionamento dello scheduler
Trova il thread attivo con priorità corrente più alta e lo esegue per un quantum Solo il thread non sospeso con la priorità più alta viene eseguito Se ci sono più thread con lo stesso livello, effettua un round-robin tra questi L’unico modo per eseguire thread a priorità più bassa è che i thread a priorità più alta vadano in stato di Wait (ad es. per operazioni di I/O) Note a lato: se al termine del quantum non ci sono cambiamenti in sospensioni e/o priorità, lo steso thread riceve nuovamente il quantum. In un sistema multiprocessore (SMP), possono verificarsi condizioni per cui su un processore non gira il thread al momento non sospeso con la priorità più alta.

81 Scheduler Impatto dello scheduler sui tempi di risposta
Appena un thread a priorità più alta non è più sospeso, lo scheduler interrompe il thread in esecuzione e passa il controllo al thread con la priorità più alta La priorità di un thread non agisce quindi direttamente sulla percentuale di tempo di CPU assegnata

82 Priorità di processi e thread
Variable Real-Time Real-Time Class High Class Normal Class Lo scheduler agisce solo in base al livello di priorità corrente del thread, che però cambia in continuazione (a parte i casi descritti più avanti). Notare che i processi “normali” hanno una priorità massima di 15; anche le applicazioni in Idle possono spostare un thread a quella priorità. Le priorità superiori a 11 possono causare, rallentamenti del sistema operativo; processi in Real-Time possono fermare servizi del sistema operativo come Flush della cache del disco, mouse, ecc. Idle Class 1 5 10 15 16 20 25 31

83 Scheduler Come fa Windows a funzionare?
Il trucco è che la priorità corrente del thread è modificata continuamente dallo scheduler: I thread in attesa vengono premiati I thread che usano più CPU sono penalizzati L’applicazione in primo piano riceve un quantum più lungo Paragonare i thread ai lavori assegnati a chi lavora in un azienda: cambiano continuamente di priorità, e quello con la priorità più alta è l’unico a essere portato avanti, almeno fino a che non arriva un lavoro con una proprietà più alta. L’unica differenza tra un impiegato e lo scheduler di NT è che l’impiegato si stressa prima.

84 Scheduler Andamento del livello di priorità corrente nel tempo
Priority Boost Quantum Decay Round-Robin at Base Base La priorità dinamica cambia come segue: ad ogni quantum la priorità scende, quando il thread va in wait si ha un Priority Boost. Notare che se il thread consuma molta CPU, comunque la sua priorità non scende mai al di sotto del livello di priorità base (tutti i quantum successivi fino ad una Wait restano al livello base di priorità). Run Wait Run Preempt Run Tempo

85 Scheduler Non voglio che lo scheduler cambi il livello di priorità corrente di un thread. Come faccio? Il livello di priorità corrente non scende mai al di sotto della priorità base. Un thread con priorità TIME_CRITICAL ha sempre il valore di priorità corrente 15 Tutti i valori superiori a 15 non sono mai modificati dinamicamente (processi in classe di priorità REALTIME)

86 Scheduler Non sono solo driver Priorità dinamiche Priorità statiche
High Class Real-Time Class Above Normal Normal Class Non sono solo driver Below Normal Lo scheduler agisce solo in base al livello di priorità corrente del thread, che però cambia in continuazione (a parte i casi descritti più avanti). Notare che i processi “normali” hanno una priorità massima di 15; anche le applicazioni in Idle possono spostare un thread a quella priorità. Le priorità superiori a 11 possono causare, rallentamenti del sistema operativo; processi in Real-Time possono fermare servizi del sistema operativo come Flush della cache del disco, mouse, ecc. Idle Class 1 5 10 15 16 20 25 31

87 Controllare le priorità
Un’applicazione può controllare la priorità dei suoi thread: CreateProcess parametro fdwCreate BOOL SetPriorityClass(hProcess, fdwPriority) BOOL SetThreadPriority(hThread, nPriority)

88 Creazione di un Thread La funzione Win32 per creare un thread è CreateThread Ogni libreria o ambiente di sviluppo ha delle funzioni specifiche per creare un thread: C/C++ RTL _beginthread(...) MFC AfxBeginThread(...) Se si usano le C-Run Time Libraries, specificare la versione multi-thread delle librerie nelle opzioni del progetto

89 C Run-Time Library

90 Funzioni di creazione dei Thread
Win32 API HANDLE CreateThread( lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) C Run-Time API unsigned long _beginthread( void (*start_address) (void *), unsigned stack_size, void *arglist)

91 Esempio CreateThread DWORD WINAPI CalculationThreadProc (LPVOID lpv) { printf(“CalculationThreadProc: Param=%d\n”, *((lpint)lpv); return 0; } DWORD main (void) { DWORD dwThreadId, dwThrdParam = 1; HANDLE hThread; hThread = CreateThread (NULL, //no security attributes 0, //default stack size CalculationThreadProc, //thread function &dwThrdParam, //thread function argument 0, //default creation flags &dwThreadId); //returns thread ID if (hThread == INVALID_HANDLE_VALUE) return 1; ... }

92 Esempio CalculationThreadProc
typedef struct _threadargs { } THREADARGS, * LPTHREADARGS; DWORD WINAPI CalculationThreadProc ( LPVOID lpv) { LPTHREADARGS lpta = lpv; BOOL bRet; /*Do Calculation*/ return bRet; }

93 Thread IDs e Handles DWORD GetCurrentThreadId(VOID)
DWORD GetCurrentProcessId(VOID) HANDLE CreateThread(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) HANDLE CreateRemoteThread(hProcess, lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) HANDLE GetCurrentThread(VOID) HANDLE GetCurrentProcess(VOID)

94 Uscita da un Thread Funzioni API Win32
VOID ExitThread(dwExitCode) BOOL TerminateThread(hThread, dwExitCode) Funzioni API C Run-Time Libraries void _endthread(void)

95 Valori di uscita da un thread
BOOL GetExitCodeProcess (hProcess, lpdwExitCode) BOOL GetExitCodeThread (hThread, lpdwExitCode) DWORD WaitForSingleObject(hObject, dwTimeout) DWORD WaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout)

96 evitare tecniche di polling
Sincronizzazione Per scrivere codice efficiente è indispensabile... evitare tecniche di polling

97 Sincronizzazione Un thread che non deve aspettare un evento esterno deve andare in stato di Wait Se un thread deve aspettare che un altro thread abbia compiuto una certa operazione, si sfruttano gli oggetti kernel per la Sincronizzazione: Mutex Semaphore Event Critical Section

98 Attesa su Oggetti kernel
Per sospendere un thread fino a che uno o più oggetti kernel non diventano “segnalati”, usare le funzioni di Wait: DWORD WaitForSingleObject( hObject, dwTimeout) DWORD WaitForMultipleObjects( cObjects, lphObjects, fWaitAll, dwTimeout) DWORD MsgWaitForMultipleObjects( cObjects, lphObjects, fWaitAll, dwTimeout, fdwWakeMask )

99 Scenario di sincronizzazione 1
Gestire in maniera efficiente l’input da una porta seriale Attende il prossimo carattere o il riempimento del buffer di input Legge e processa i caratteri Attende il prossimo carattere o il buffer Si usa l’oggetto Event, che è funzionalmente simile ad una variabile booleana

100 Event Objects Interprocess or Intraprocess Named or Unnamed
HANDLE CreateEvent(lpsa, fManualReset, fInitialState, lpszEventName) HANDLE OpenEvent(fdwAccess, fInherit, lpszEventName) BOOL SetEvent(hEvent) BOOL ResetEvent(hEvent) BOOL PulseEvent(hEvent)

101 Uso di Event HANDLE hEvent = CreateEvent ( NULL, // no security TRUE, // event must be reset // manually FALSE, // initially nonsignaled NULL); // anonymous event StartTaskThatSignalsEventWhenDone (hEvent); // Do other processing. // Wait for event to be signaled; then reset it. WaitForSingleObject (hEvent, INFINITE); ResetEvent(hEvent); ... CloseHandle (hEvent);

102 Scenario di sincronizzazione 2
Proteggere strutture dati condivise, come code e liste in memoria condivisa, dal danneggiamento dovuto ad accessi concorrenti Si usa l’oggetto Mutex, che è un flag che coordina l’esecuzione di operazioni mutualmente esclusive Solo un thread può detenere un Mutex, gli altri thread vengono sospesi sulla Wait fino a che il Mutex non viene rilasciato

103 Mutex Objects Interprocess or Intraprocess Named or Unnamed
Noncounting Mutual Exclusion HANDLE CreateMutex( lpsa, fInitialOwner, lpszMutexName) HANDLE OpenMutex( fdwAccess, fInherit, lpszMutexName) BOOL ReleaseMutex(hMutex)

104 Uso di Mutex if (!hMutex) // if we have not yet created the mutex { // create mutex with creator having initial ownership hMutex = CreateMutex (NULL, TRUE, "Bob"); if (GetLastError() == ERROR_ALREADY_EXISTS) WaitForSingleObject (hMutex, INFINITE); } else WaitForSingleObject (hMutex, INFINITE); __try{ // use the resource protected by the mutex } __finally { ReleaseMutex (hMutex); } ... CloseHandle (hMutex);

105 Scenario di sincronizzazione 3
Porta per n-way Mutex Acquisisce una delle n risorse identiche da un pool di risorse disponibili Si usa l’oggetto Semaphore, che è simile ad un Mutex con un contatore Un Mutex è come un Semaphore che assume solo i valori 0 e 1; quando il Semaphore diventa 0, le chiamate a WaitFor... diventano sospensive, fino a che qualche thread non incrementa il valore del Semaphore

106 Semaphore Objects Interprocess or Intraprocess Named or Unnamed
Counting HANDLE CreateSemaphore( lpsa, cSemInitial, cSemMax, lpszSemName) HANDLE OpenSemaphore( fdwAccess, fInherit, lpszSemName) BOOL ReleaseSemaphore( hSemaphore, cReleaseCount, lplPreviousCount)

107 Uso di Semaphore HANDLE hSem = CreateSemaphore ( NULL, // security , // initial count , // maximum count "Sally"); // global object name ... // Wait for any 1 of 4 resources to be available. WaitForSingleObject (hSem, INFINITE); __try{ // Use the semaphore. } __finally { ReleaseSemaphore (hSem, 1, &lPrevCount) }; CloseHandle (hSem);

108 Scenario di sincronizzazione 4
Sincronizzazione di diversi thread nello stesso processo con un oggetto Mutex il più velocemente possibile, con il minimo overhead (es. inserimento di un oggetto in una coda) Si usa l’oggetto Critical Section, che è un Mutex utilizzabile solo da thread di uno stesso processo

109 Critical Section Meccanismo veloce di condizione mutualmente esclusiva
Memoria allocata dall’utente VOID InitializeCriticalSection(lpcsCriticalSection) VOID DeleteCriticalSection(lpcsCriticalSection) VOID EnterCriticalSection(lpcsCriticalSection) VOID LeaveCriticalSection(lpcsCriticalSection) Protegge l’accesso a dati condivisi da thread dello stesso processo

110 Uso di Critical Section
CRITICAL_SECTION cs; InitializeCriticalSection (&cs); EnterCriticalSection (&cs); __try { // initialize the thread arguments. ta.hWnd = hWnd; ta.lpDIB = lpDIB; ta.rc = *lprc; ta.bFlags = bFlags; ta.pMP = pMP; } __finally { LeaveCriticalSection (&cs); } DeleteCriticalSection (&cs);

111 Thread e code mesaggi: Modello Win32
Application RIT Mouse Device Driver Keyboard Thread Raw Input Event Queues

112 Funzioni API per messaggi e thread
BOOL PostMessage(hWnd, uMsg, wParam, lParam) BOOL GetMessage(lpmsg, hWnd, uMsgFilterMin, uMsgFilterMax) BOOL PostThreadMessage( dwThreadId, uMsg, wParam,lParam) BOOL PeekMessage(lpmsg, hWnd, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg) LRESULT SendMessage(hWnd, uMsg, wParam, lParam) BOOL SendNotifyMessage(hWnd, uMsg, wParam, lParam) BOOL AttachThreadInput(idAttach, idAttachTo, fAttach) DWORD MsgWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout, fdwWakeMask )

113 Thread Definizione di thread Cooperative e preemptive multitasking
Perchè usare thread multipli? Thread overhead Scheduler Creazione di un thread C Run-Time Library Oggetti per la sincronizzazione Thread e code di messaggi

114 Thread Pool

115 Thread Pool Insieme di Thread gestiti dal sistema
Disponibili solo da Windows 2000 in poi Scenari affrontati: Accodare l’esecuzione asincrona di diverse funzioni Chiamare diverse funzioni periodicamente (senza WM_TIMER) Chiamare funzioni quando un oggetto kernel va in stato “segnalato” Chiamare una funzione quando una richiesta di I/O asincrono viene completata

116 Thread Pool – Scenario 1 Scenario: accodare l’esecuzione asincrona di diverse funzioni (ad es. una scrittura “posticipata”) Senza Thread Pool Creazione di un Thread, esecuzione della funzione, distruzione del Thread Con Thread Pool Una chiamata a QueueUserWorkItem

117 Thread Pool – Scenario 1 BOOL QueueUserWorkItem( LPTHREAD_START_ROUTINE pfnCallback, PVOID pvContext, ULONG Flags ); Valori di Flags: WT_EXECUTEDEFAULT WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION

118 Thread Pool – Scenario 2 Scenario: chiamare diverse funzioni periodicamente Senza Thread Pool Un thread per ogni funzione, Sleep(x) tra una chiamata e l’altra WM_TIMER per ogni funzione Con Thread Pool Una chiamata a CreateTimerQueueTimer

119 Thread Pool – Scenario 2 CreateTimerQueue CreateTimerQueueTimer
ChangeTimerQueueTimer DeleteTimerQueueTimer DeleteTimerQueueEx

120 Thread Pool – Scenario 2 BOOL CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, WORD DueTime, WORD Period, LONG Flags ); Valori di Flags: WT_EXECUTEINTIMERTHREAD WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION

121 Thread Pool – Scenario 3 Scenario: eseguire una funzione quando un oggetto kernel diventa segnalato Senza Thread Pool Un thread per ogni funzione/oggetto, WaitForSingleObject prima della chiamata Un thread controlla più oggetti kernel con WaitForMultipleObjects... Con Thread Pool Chiamare RegisterWaitForSingleObject

122 Thread Pool – Scenario 3 RegisterWaitForSingleObject UnregisterWaitEx

123 Thread Pool – Scenario 3 BOOL RegisterWaitForSingleObject( PHANDLE phNewObject, HANDLE hObject, WAITORTIMERCALLBACK Callback, PVOID pvContext, ULONG dwMillisecs, ULONG dwFlags ); Valori di Flags: WT_EXECUTEDEFAULT WT_EXECUTEINWAITTHREAD WT_EXECUTEINIOTHREAD WT_EXECUTEINPERSISTENTIOTHREAD WT_EXECUTELONGFUNCTION WT_EXECUTEONLYONCE

124 Thread Pool – Scenario 4 Scenario: chiamare una funzione quando termina un’operazione di I/O asincrono Senza Thread Pool Creazione di un I/O completion port e gestione manuale di un thread pool Con Thread Pool Una chiamata a BindIoCompletionCallback

125 Thread Pool – Scenario 4 BOOL BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags ); Flags è riservato, deve valere sempre 0 Prototipo LPOVERLAPPED_COMPLETION_ROUTINE: VOID WINAPI OverlappedCompletionRoutine( DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped );

126 Thread Pool Esecuzione di funzioni asincrone
Esecuzione periodica di funzioni Operazioni da eseguire quando un oggetto kernel diventa “segnalato” Operazioni da eseguire al termine di operazioni di I/O

127 Jobs

128 Job Gruppo di processi E’ un oggetto kernel
Disponibile solo da Windows 2000 in poi Crea delle regole per i processi che contiene Può definire dei limiti su: Risorse del sistema Interfaccia utente Sicurezza Può monitorare l’attività dei processi

129 Job – Ciclo di vita Il Job viene creato “vuoto”
Impostare proprietà del Job Un processo viene assegnato ad un Job La relazione Processo-Job è irreversibile Un processo figlio può nascere fuori dal Job del processo padre Se un Job viene terminato, tutti i suoi processi vengono terminati Il Job comunica con l’esterno con le I/O completion port (non segnala su Handle)

130 Job – Ciclo di vita Il nome associato al Job è accessibile fino a che ci sono handle aperti al Job Se tutti gli handle al Job vengono chiusi, il Job resta in vita ma non è più accessibile (verrà distrutto quando tutti i processi all’interno si saranno chiusi)

131 Job - Limiti Limiti sulle risorse di sistema: Process Priority
Consumo CPU Working Set Size Consumo memoria Processor Affinity

132 Job - Limiti Limiti su interfaccia utente
Accesso USER Handle (HWND, HMENU, ...) Creazione/Switch Desktop Modifica impostazioni video Modifica parametri di sistema Clipboard ExitWindows

133 Job - Limiti Limiti sulla security – Token utilizzabili:
No Administrator Tutti i processi con un token uguale Solo token ristretti rispetto a quello del processo Filtro sui token (disabilitazione di alcuni diritti indipendentemente dall’utente impersonato)

134 Job - Monitoraggio Tempo CPU (kernel/user) Page Fault
Numero processi (attivi/terminati) Attività di I/O (operazioni/byte) Elenco processi

135 Job - Funzioni CreateJobObject OpenJobObject AssignProcessToJobObject
TerminateJobObject QueryInformationJobObject SetInformationJobObject UserHandleGrantAccess

136 Jobs Definizione di Job Ciclo di vita Limiti definibili Monitoraggio

137 Comunicazione tra processi (IPC – Interprocess Communication)

138 Comunicazione tra processi
Per comunicare tra loro, due processi devono richiedere dei servizi al sistema operativo: Memory Mapped File (Shared Memory) Object Handles File su disco Socket, Named Pipe e Mailslot RPC (Remote Procedure Call)

139 Memory Mapped File Consente di condividere memoria tra processi diversi E’ una scelta adeguata quando più processi devono accedere contemporaneamente ad informazioni contenute in strutture dati di vaste dimensioni L’accesso simultaneo (almeno in scrittura) va protetto tramite meccanismi di sincronizzazione tra thread Non vi è una notifica istantanea della variazione di un dato da parte di un processo

140 Object Handle Più processi possono accedere ad uno stesso oggetto kernel E’ una tecnica indispensabile per condividere oggetti di sincronizzazione tra processi diversi

141 File su disco E’ un meccanismo che consente la condivisione di informazioni tra programmi in esecuzione anche su macchine diverse e con sistemi operativi diversi Le prestazioni e la scalabilità sono le più basse rispetto alle tecniche esaminate

142 Socket, Named Pipe, Mailslot
Sono dei “canali” di comunicazione tra processi Si possono usare anche tra processi residenti su elaboratori diversi La trasmissione delle informazioni è sequenziale I dati inviati generano delle notifiche ai processi in ascolto: questo consente di evitare tecniche di polling anche su comunicazioni in rete

143 Socket Windows Sockets 2 è l’implementazione Microsoft dell’interfaccia di programmazione definita in “Berkely Sockets” Conosciuta come interfaccia di programmazione per TCP/IP, è utilizzabile anche per altri protocolli E’ il sistema ideale per implementare meccanismi di comunicazione su rete tra sistemi operativi diversi Supporta una comunicazione bidirezionale E’ un meccanismo client/server

144 Socket Il client può risiedere sulla stessa macchina del server, o su una macchina diversa Processo S1 Processo C1 Processo C2 Port 80 Port 1219 Port 1198 socket Computer A Computer B S1: Processo server C1, C2: Processi client

145 Named Pipe Meccanismo di comunicazione client-server
Simile ad un socket, ma indipendente dal protocollo fisico Pipe Server: processo che crea una named pipe Pipe Client: processo che si connette ad una istanza di named pipe La named pipe ha un nome univoco per la macchina in cui è definita, ma possono esistere più istanze della stessa named-pipe Integra la “security” Modalità di funzionamento “message-mode” Server solo su NT/2000, Client su Win9x/NT/2000

146 Named Pipe Il client può risiedere sulla stessa macchina del server, o su una macchina diversa Processo S1 Processo C1 Processo C2 \\S1\pipe\Test named pipe Computer A Computer B S1: Processo server C1, C2: Processi client

147 Pipe Server Sequenza di funzioni API da chiamare: CreateNamedPipe
ConnectNamedPipe ReadFile / WriteFile DisconnectNamedPipe CloseHandle

148 Pipe Client Sequenza di funzioni API da chiamare: CreateFile
WriteNamedPipe SetNamedPipeHandleState ReadFile / WriteFile CloseHandle

149 Named Pipe: API speciali
BOOL TransactNamedPipe(…) Esegue sequenzialmente WriteFile seguita da ReadFile Si usa sul client per semplificare il codice di esecuzione di transazioni sincrone BOOL CallNamedPipe(…) Esegue sequenzialmente WaitNamedPipe, CreateFile, TransactNamedPipe e CloseHandle Si usa sul client per semplificare il codice nel caso in cui per ogni transazione si vuole aprire e chiudere una connessione

150 Mailslot Meccanismo di comunicazione broadcast senza connessione
Mailslot Server: processo che crea una mailslot e legge i dati ad essa inviati Mailslot Client: processo che scrive un messaggio su una mailslot Il nome di una mailslot è univoco per una macchina Nessuna gestione di “security” Modalità di funzionamento “message-mode” Server e Client su Win9x / NT / 2000

151 Mailslot Una macchina può ospitare solo una mailslot con lo stesso nome Processo C1 Processo S1 Processo S2 mailslot Computer A Computer B S1, S2: Processi server C1: Processo client \\.\mailslot\Test

152 Nomi delle Mailslot Creazione mailslot (server):
\\.\mailslot\mailslotname Apertura mailslot per scrittura (client): \\ComputerName\mailslot\mailslotname \\DomainName\mailslot\mailslotname \\*\mailslot\mailslotname

153 Mailslot locali Il Mailslot server deve esistere quando il Mailslot client viene creato Un messaggio può essere lungo fino a 64K I messaggi inviati al server vengono ricevuti una volta I messaggi inviati vengono sicuramente ricevuti, ma non si sa se e quando vengono letti Possono esistere più client che scrivono sullo stesso server, se i client usano gli attributi FILE_SHARE_WRITE | FILE_SHARE_READ nella CreateFile()

154 Mailslot remote Deve esserci almeno un protocollo di rete attivo
Il Mailslot client può essere creato in qualsiasi momento (anche se non esiste un Mailslot server) La scrittura da parte del Mailslot client non genera mai errori Un messaggio inviato ad un dominio può essere letto da più server Compatibilità garantita per messaggi fino a 425 byte Viene inviata una copia del messaggio per ogni protocollo di rete installato (il Mailslot server può ricevere più copie dello stesso messaggio)

155 Mailslot Server Sequenza di funzioni API da chiamare: CreateMailslot
ReadFile CloseHandle

156 Mailslot Client Sequenza di funzioni API da chiamare: CreateFile
WriteFile CloseHandle

157 Remote Procedure Call Consente di eseguire chiamate a funzioni presenti in processi diversi, anche su elaboratori diversi E’ basato sugli standard definiti da OSF (Open Software Foundation) DCE (Distributed Computing Environment) E’ indipendente dal protocollo di rete E’ la base di DCOM

158 Client Run-Time Library
Remote Procedure Call Per ogni chiamata, avviene una transazione coordinata dal sistema operativo, per trasferire al “server” i parametri della funzione, e ricevere da esso i risultati Application Transport Client Stub Client Run-Time Library 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Client Server

159 Comunicazione tra processi
Shared Memory Sockets Named Pipe Mailslot Remote Procedure Call

160 Operazioni di I/O (I/O Manager)

161 Windows NT I/O System Architecture
Devices DMA/Bus Controller Timers Caches, Interrupts CPU Privileged Architecture Software Hardware Applications and Subsystems (User-Mode Instruction Set) I/O Manager Security Monitor Object Manager Local IPC Virtual Memory Process Device Drivers Kernel HAL GDI USER

162 Name Space unico per tutti i Device
Environment Subsystem or DLL I/O System Services File System and Network Drivers I/O Manager Device Drivers User Mode Kernel Mode Video Monitor and Keyboard Printer Network Device Disk Drive Mouse Tape CD-ROM Drive

163 Link simbolici Usati per mappare nomi di Device MS-DOS al Name Space di Windows NT DWORD QueryDosDevice( lpDeviceName, lpTargetPath, ucchMax) BOOL DefineDosDevice( dwFlags, lpDeviceName, lpTargetPath) Esempio D: -> \DEVICE\HARDDISC0\PARTITION2

164 Cache Manager Cache di tutto l’I/O per default
Incrementa le performance dei programmi che effettuano molte operazioni di I/O La dimensione della Cache è dinamica E’ un insieme di oggetti Section Ha il proprio spazio di indirizzamento (di sistema) Usa il Virtual Memory Manager per effettuare la paginazione

165 API per File I/O Si possono usare le seguenti API per accedere ai file: C Run-Time Library Windows 3.1 API (solo per compatibilità) Win32 API

166 Win95-Based Synchronous I/O Processing
WriteFile(file_handle data, ...) WriteFile(file_handle data, ...) Returns Application Win32 Subsystem Call Windows NT Write File Service Return Data User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Complete IRP Return I/O Manager Queue I/O to Device Device Driver Perform I/O Transfer Wait for Completion Device Time

167 Windows NT–Based Synchronous Processing
WriteFile(file_handle data, ..., overlapped) . . . Application <Wait ends> Return I/O Status Call Windows NT Write File Service Win32 Subsystem User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Wait(...) I/O Manager Set File Handle to Signaled State Queue I/O to Device Device Driver Return Handle Interrupt Perform I/O Transfer Interrupt for Service Device . . . Time

168 Asynchronous (Overlapped) I/O Processing
WriteFile(file_handle data, ..., overlapped) . . . <Perform other work> Wait(file_handle) Application <Wait ends> Call Windows NT Write File Service Return I/O Pending Status Win32 Subsystem User Mode Kernel Mode Check Parameters Create IRP Call Device Driver Return I/O Manager Set File Handle to Signaled State Queue I/O to Device Device Driver Return Handle Interrupt Perform I/O Transfer Interrupt for Service Device . . . Time

169 Effettuare Overlapped I/O con Win32
Usare il flag FILE_FLAG_OVERLAPPED quando si apre un file con CreateFile() Effettuare un’operazione di I/O, e mettersi in Wait su: File handle, oppure Event object, oppure Una I/O completion callback

170 Esempio: Overlapped I/O usando Event Object
HANDLE hFile; LPOVERLAPPED lpo; // create and initialize an OVERLAPPED structure lpo = calloc (sizeof(OVERLAPPED), 1); lpo->Offset = 0; lpo->hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); hFile = CreateFile ("filename", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // begin async io WriteFile(hFile, pBuffer, cbBuffer, &nBytesWritten, lpo); // wait for io to complete and get result GetOverlappedResult (hFile, lpo, &nBytesWritten, TRUE); // cleanup CloseHandle (lpo->hEvent); free (lpo);

171 I/O Completion Routine
User-Mode Asynchronous Callback Non è veramente asincrona, perché può essere eseguita solo in corrispondenza di punti di controllo definiti (Control Points) Control Points ReadFileEx, WriteFileEx, WaitForSingleObjectEx, WaitForMultipleObjectsEx, SleepEx

172 Esempio: I/O Completion Routine
VOID WINAPI lpfnIOCompletion ( DWORD dwError, DWORD cbWritten, LPOVERLAPPED lpo) { if (!dwError) lpo->Offset += cbWritten; } ... hFile = CreateFile ("filename", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // create and initialize an OVERLAPPED structure lpo = calloc (sizeof(OVERLAPPED), 1); lpo->Offset = GetFileSize (hFile, NULL); // begin async io with callback WriteFileEx (hFile, pBuffer, cbBuffer, lpo, lpfnIOCompletion); ... // wait for callback to be called on i/o completion SleepEx (INFINITE, TRUE);

173 I/O Completion Port Basato su una coda (I/O Completion Port) di messaggi relativi alle operazioni di I/O asincrone completate (I/O Completion Packet) Uno o più thread (generalmente worker thread) possono prelevare messaggi dalla coda ed eseguire operazioni appropriate Si può controllare il numero massimo di thread attivi che possono processare I/O Completion Packet (eventuali altre richieste concorrenti sospendono il thread richiedente fino a che uno dei thread in esecuzione non completa l’elaborazione del Completion Packet prelevato)

174 Scatter-Gather I/O Meccanismo ad alte prestazioni per lettura/scrittura dati su file Disponibile su NT4.0 SP2 e successivi Usato da SQL Server Legge/scrive dati presenti in zone non contigue di memoria su zone di file contigue, sfruttando il DMA Granularità di pagina (4K / 8K) Funzioni API: ReadFileScatter(…) WriteFileGather(…)

175 Change Notification Oggetto kernel utilizzabile in funzioni di Wait per monitorare il cambiamento del contenuto di una directory FindFirstChangeNotification(…) FindNextChangeNotification(…) FindCloseChangeNotification(…) Nota bene: non si usa CloseHandle(…) per la chiusura dell’handle ottenuto con FindFirstChangeNotification(…)

176 I/O Manager Architettura I/O Manager Elaborazione sincrona dell’I/O
Elaborazione asincrona dell’I/O I/O Completion Routine I/O Completion Port Change Notification

177 Riferimenti

178 Altre Informazioni Dove posso ottenere maggiori informazioni
Developer resources Microsoft Developer Network

179 Windows internals I vostri feedback sono importanti
Compilate il modulo di valutazione Grazie della partecipazione


Scaricare ppt "Windows internals http://www.microsoft.com/italy/msdn/studenti scoriani@microsoft.com."

Presentazioni simili


Annunci Google