Processes and Threads
Because Windows CE is based on the Win32 API, it has full support for processes and threads. Visual C++ (and even Visual Basic 5) programmers might already be familiar with these concepts. Essentially, a process consists of one or more threads of execution, where a thread is the smallest unit of execution. Windows CE allows a maximum of 32 processes; however, the number of threads is limited only by available memory. It is possible to create threads using Visual Basic, but this is not advisable because the Visual Basic run time is not "thread safe"- that is, if two threads within the same process were to call a Visual Basic routine at the same time, some fairly nasty things might happen. However, because I know that some of you will try it, and because it is very applicable to C++ development, the section "Visual Basic Development" later in this chapter describes the thread-handling API calls. If you have trouble remembering the difference between processes and threads, you might find the diagram in Figure 5-3 helpful.
Figure 5-3 Windows CE processes and threads
The ability to assign priorities to a thread is a major requirement, especially for an operating system that will host real-time applications. Windows CE allows a thread to be assigned one of eight priority levels, as shown in Table 5-1.
Table 5-1 Thread Priorities
|0 THREAD_PRIORITY_TIME_CRITICAL||Used primarily for real-time threads and processing, such as device drivers. Priority 0 threads are not preempted-once started, a thread process will continue to completion. The operating system will not interrupt the thread.|
|2 THREAD_PRIORITY_ABOVE_NORMAL||Kernel threads normally run at these levels, as do normal applications.|
|5 THREAD_PRIORITY_LOWEST||Used in instances in which it doesn't matter how long the functionality takes to complete. These will usually be background tasks, probably without their own user interface. An example might be of a thread that periodically checks to see if you have any new mail. Threads on these priority levels can expect to be interrupted often.|
The Windows CE operating system is preemptive and as such must allocate a time slice for each thread. This is done in a "round-robin" fashion. The default time slice for a thread is 25 milliseconds, except for priority 0 threads. A priority 0 thread, once started, will retain the processor until it yields control. The scheduling mechanism uses an algorithm whereby the highest priority thread is always allocated time first. This process is better illustrated by Figure 5-4.
Figure 5-4 Thread preemption in Windows CE
Windows CE handles thread priority inheritance (a requirement of real-time systems we will discuss shortly) using a method called Priority Inversion. It is possible that a thread on a lower priority might lock a resource required by a thread on a higher priority. When this condition occurs Windows CE promotes the lower thread task to the level of the higher priority thread until the resource has been released. The Win32 API has full support for thread priority assignments. In version 2 of the Windows CE operating system the default time slice is configurable on the MIPS platform.
An additional requirement currently being developed is to increase the number of priority bands, possibly to as many as 256. This has been a frequent request from OEMs and IHVs in order to enhance real-time flexibility. Because of the way in which the preemptive multitasking works in Windows CE, it is possible to guarantee the time it will take for a thread to execute on the highest priority, an important factor in a real-time system.