190 likes | 244 Views
Windows CE. Portable Modular Real-time Small footprint Embedded market. OS Spectrum. General Purpose. Real-time. General Purpose Large Footprint Longer Interrupt Latency Det/Non-det. Sched. Memory Protection Rich API Soft real-time. Specialized, Small Footprint,
E N D
Windows CE • Portable • Modular • Real-time • Small footprint • Embedded market
OS Spectrum General Purpose Real-time General Purpose Large Footprint Longer Interrupt Latency Det/Non-det. Sched. Memory Protection Rich API Soft real-time Specialized, Small Footprint, Short Interrupt latency, Deterministic scheduling, No memory protection, Limited API, Hard realtime requirements CE
Requirements and Features • 32-bit • 350 KB minimum memory • ROM-able • Processes, kernel mode threads, inter-task communication and sync. • Pre-emptive kernel • Priority scheduling and priority inheritance • Paging Memory management • File System support • Interrupt latency = 90-170 us, no nested interrupts • Networking stacks, Device drivers, GUI, etc.
Win32 Applications Add-ons (OLE, Java, …) Shell Core System API File System Communications Kernel Graphics, Windowing and Event Subsystem Device Manager OEM Adaptation Layer Native Drivers Stream Interface Drivers OEM Hardware Overall Architecture
Processes • Each appln. runs as a process • Process = address space + threads + kernel objects of that process (mutex, events, file descriptors, …) • Address space = code+data+stack+heap • Address space isolation makes a system more robust • But makes context switching expensive • CE restricts no. of processes to 32.
Threads • Lightweight counterpart of processes • Entities within a process that are only associated with a stack (no code/data/heap) • Switching is cheap • Several threads within a process can cooperate to provide concurrency • Makes it easier to program non-blocking programs. • When a process is created, there is 1 primary thread, starts executing WinMain() in .EXE file. • You can create more threads subsequently if needed.
Creating a Process Rc = CreateProcess( TEXT(“Hello.exe”), // Appln. Name NULL, // Command Line Args NULL, // Process attributes NULL, // Thread attributes FALSE, // Handle inheritance 0, // Special flags NULL, // Environment NULL, // Current directory NULL, // Startup info &ProcInfo); // Get info about created process Returns TRUE if successful, FALSE if failed. Handle is used to denote process in OS calls GetCurrentProcess(), GetCurrentProcessId()
Creating Secondary Threads HANDLE hThread = CreateThread( NULL, //Thread attributes 0, // Specify stack size funcName, // Thread starts there ¶m, // Parameters 0, // Special creation flags &threadId); // Thread ID GetCurrentThread(), GetCurrentThreadId(). Unlimited number of threads
Scheduling • Preemptive scheduler • Each thread is assigned a priority • Normally a thread is created with priority THREAD_PRIORITY_NORMAL • Priority levels • THREAD_PRIORITY_TIME_CRITICAL (real-time apps) • THREAD_PRIORITY_HIGHEST (Device drivers) • THREAD_PRIORITY_ABOVE_NORMAL (very responsive applns.) • THREAD_PRIORITY_NORMAL (most applns.) • THREAD_PRIORITY_BELOW_NORMAL (secondary, less important) • THREAD_PRIORITY_LOWEST (backup, file download, etc.) • THREAD_PRIORITY_ABOVE_IDLE (Disk maintenance utils) • THREAD_PRIORITY_IDLE (rarely used)
A single queue for each level • Scan from the highest priority to lowest priority queues • As soon as you find a non-NULL queue, schedule thread at its head. • After time-quantum you put it at the end of that queue and repeat (round-robin within each queue)
Priority Inversion Problem • Consider 2 threads T1 and T2 where T1d is running currently and T2 is blocked on I/O, and priority(T2) > priority(T1) • Say T1 acquires a critical section • I/O is now complete and T2 becomes ready • T2 is immediately scheduled, and it in turn asks for the critical section (say it is a spinning request) • Problem: T1 will not be scheduled to release the critical section for T2 to process => Higher priority thread will not progress till lower priority thread is scheduled
Solution • When T2 becomes awake and asks for critical section, temporarily boost the priority of T1 to be that of T2 • Once T1 is done with critical section it reverts back to its old priority. • (NOTE: This problem can occur even in blocking request implementations)
Need for Synchronization • Race conditions can occur when multiple activities (threads in this case) read and write shared variables possibly leading to states that the user did not intend • Guard statements (critical section) with synchronization constructs to restrict the possible executions.
Synchronization Constructs in CE • Critical section objects • Mutex objects • Event objects • Interlock functions
Critical section object • Only one thread can be allowed (to executed) in a critical section object at a time. • A process can have any number of critical section objects. • These objects are not sharable across processes.
Critical section object usage CRITICAL_SECTION m_CritSect; EnterCriticalSection(&m_CritSect); …… Critical section code goes here …… LeaveCriticalSection(&m_CritSect); InitializeCriticalSection(&m_CritSect) and DeleteCriticalSection(&m_CritSect) calls.
Mutex Objects • Similar to critical section objects with the difference being that they can be used across processes as well. HANDLE m_hMutex; M_hMutex = CreateMutex( NULL; // security attributes FALSE; // Not owned by any thread NULL); // Name if used across processes WaitForSingleObject(m_hMutex,INFINITE); …. Critical section … ReleaseMutex(m_hMutex);
Event Objects • Has signalled and non-signalled states • You can either automatically reset it after the waiting process gets a signal or can manually reset it. • Can also be used across processes.
Interlocked Functions • Atomic functions to implement some simple operations • InterlockedIncrement(&count) – Reads the count variable and increments it • InterlockedDecrement(&count) • InterlockedExchange(&v1,&v2) – returns value in v1 and sets v1=v2.