gw_logo_08.gif (1982 bytes) 
Last edit: 05-03-17 Graham Wideman
Data Acquisition
Multitasking Discussion
Article created: 99-06-16


The Basics

In order to understand timing issues under Windows it's necessary to understand how multitasking works for these operating systems.

The operating system views each application and service as a process, which may incorporate 1 or more threads of execution.  A key part of the OS is the mechanism which runs applications and services, and provides the approximate effect of running them all at once (multitasking) by allocating time slices to each in turn according to priority levels.  The W95/98/NT/2000 operating systems are refered to as preemptive mulitasking because at regular intervals the OS "preempts" whichever thread is running in order to reevaluate which is the most deserving thread.

So, of great pertinence to the subject of timing are the following issues:

Process and Thread Priorities

Overall thread priority is determined by three factors:

An exhaustive table of priority combinations is given in the MSDN reference above.   I've summarized the resulting overall priorities in the following table.

  Process "Priority_Class"
Thread Priority Idle Below_Normal
Normal Above_Normal
High RealTime
Idle 1 1 1 1 1 16
Lowest 2 4 5 Bg / 7 Fg 8 11 22
Below_Normal 3 5 6 Bg / 8 Fg 9 12 23
Normal 4 6 7 Bg / 9 Fg 10 13 24
Above_Normal 5 7 8 Bg? / 10 Fg 11 14 25
Highest 6 8 9 Bg? / 11 Fg 12 15 26
Time_Critical 15 15 15 15 15 31


Bg and Fg indicate Background and Foreground. "Bg?" means that the MSDN chart doesn't specifically indicate background, but elsewhere provides a value for Foreground.


The table above doesn't include the details of the Boost mechanism, see the MSDN reference for details.  In brief, the scheduler may boost the priority of certain threads under certain circumstances, including the thread being part of a process that came to the foreground, or it's a thread that just became ready. The boost strategy varies by OS, and may be impacted by user settings.

Priority Inversion

Each OS includes a strategy to avoid getting stuck when a a high-priority thread is waiting for a low-priority thread that can't get a time-slice. See MSDN for details.

Other interesting features:

Scheduler Granularity

On what interval does the scheduler check the time, and take a look at the process/thread queue?   This will determine several items of interest to us:

Scheduler time-slice granularity (quantum)  is discussed in the System Internals references and elsewhere.  They report that, it's generally a multiple of 20 ms.  Here's the table, according to System Internals site:

Quantum size [ms] according to System Internals

Platform None Low Max
NT 4 Workstation 20 40 60
NT 4 Server 120 120 120

Of interest:

However, this misses some crucial points:

Setting Scheduler to High Res:  Scheduler granularity has some "normal" value, but can be set to a higher-resolution value by using the timeBeginPeriod and timeEndPeriod functions. Indeed, on a generic PC running W95 or NT4, it can be set to 1 millisec.

Scheduler Granularity Normally 10 millisec?  Contrary to what's written elsewhere, I found that the normal scheduler granularity appears to be 10 millisec, both in NT Workstation, and on Win95.  You can use my SkedGran demo app to see what you get.

Scheduler Period Regular?   Supposing that the scheduler is using 10 millisec periods, what happens if a thread finishes before its time slot is used up? Presumably the scheduler just checks the queue, assigning the next thread 10 millisecs, and so forth.  This means that the the times that the scheduler gets control will not necessarily be evenly spaced, often being 10 millisecs apart, but sometimes shorter.

Other Notes

1. Regardless of the millisec-level scheduling that you can get for your application code most of the time, under Win95 or NT you can't get it all the time.   This may be good enough for what you want to do -- but to evaluate this you'll probably need to build an app that monitors and reports how consistently your app's code gets scheduled in your target environment -- and reports on the distribution of delays that it sees.

2. Does code scheduled in a driver fare any better?  This presumably depends on how the scheduler shares time with drivers, and how driver priority works relative to application priority -- topics I haven't explored.  If someone has a brief explanation on this, let me know!



[Up to:  Data Acquisition Topics]

Go to:  gw_logo_08.gif (1982 bytes)