From: db3l@ans.net (David Bolen)
Subject: Re: Request for info about kernel pre-emption and priorities
Date: Wed, 12 Aug 1992 12:34:59 GMT
Organization: Advanced Network & Services, Inc. - Elmsford, NY

In article <1992Aug10.233636.24891@ttinews.tti.com> terence@tanru.tti.com ( Terry) writes:

>First off, is the kernel really multi-threaded and can it be pre-empted.  I
>know there's a number of threads for the WPS but is the underlying base
>kernel multi-threaded.  On a related note, can the kernel be pre-empted;
>for another kernel entry or in favor of a high-priority user thread.
>
>I believe the answer is yes.

I believe so to - multiple threads may enter the kernel concurrently.  If they
are for completely unrelated system calls they should truly execute in
parallel, but for related calls, there is probably a variety of internal
synchronization and blocking that occurs in order to prevent resource clashes.
If this weren't true, OS/2 multitasking wouldn't be much more than what
Windows does in terms of preventing multiple tasks from entering into the
"single-threaded, non-reentrant" DOS kernel.

In terms of preemption, a lower priority thread that is executing a kernel
call may be suspended in favor of a higher priority thread even if that thread
will issue kernel calls.  However, if the higher priority thread requires
access to resources that the lower priority thread already has locked (either
through semaphores or internal kernel locking), the higher priority thread
will get blocked until the resource is released by the lower priority thread.

This "preemption" can occur either through the basic scheduling interrupt
(32x/sec), or by a process releasing a resource that a higher priority thread
is waiting on.  For example, if a low priority thread sits in a loop, it will
still get interrupted every 31.25ms, and if during one of those interrupts a
higher priority thread is ready to run, the CPU will be given to that task
rather than to the low priority thread.  If, on the other hand, the low
priority thread has a semaphore lock that a higher priority thread wants, when
the low priority thread issues the semaphore release call, that call will
never return, but control will switch directly to the high priority thread
(rather than waiting for the next scheduler interrupt of the lower priority
thread).  The TIMESLICE parameter in CONFIG.SYS come into play when tasks
at the same priority are competing for the CPU, which is handled by a
"round-robin" scheduling mechanism.

In OS/2 1.x, I believe the time latency from when a high priority thread
became "ready to run" (either resource released, or the thread was unblocked
due to some other mechanism, such as a timer firing) until it got control of
the CPU was guaranteed to be <1ms.  Not the greatest in terms of real-time
operation, but not bad for a multitasking OS.  I'm not how much, if at all,
that figure has been adjusted for v2.0.

>About process priorities, there's three major categories with 32 levels
>per category but if a process is starved for CPU, does it's priority get
>artifically raised so it gets the CPU.
>
>I believe the answer to this one is no.

It depends on the category of the thread's priority.  Note that the OS/2
scheduler knows only about threads, so all of the priority and task switching
issues occur at the thread level, rather than process.

There are 4 priority categories, or classes (my names may not exactly match
the official names):

     Idle		Lowest priority class.  Only runs when no other
			thread has a higher priority.  No dynamic variation.

     Normal/Regular	Standard priority class.  Most threads run within
			this priority.  Allows dynamic variation.

     Fixed-High/	Recently added class (I think with OS/2 1.3).  Fixed
     Foreground Server	priority level.  No dynamic variation.

     Time-Critical	Highest priority class.  No dynamic variation.

Every category is split into 32 priority levels.  Threads are dispatched within
the system first according to their priority class, and then according to the
level within the class.  Thus, Fixed-High level 0 is still higher than Regular
level 31.  Within a class, threads at the same priority level are dispatched
in a round-robin fashion, according to TIMESLICE config.sys parameters.

In the Regular class, threads may have their priority levels dynamically
varied (unless PRIORITY=ABSOLUTE is set in config.sys).  Threads are assigned
a base level within the class, and may have a delta applied to that base in
order to raise or lower their priority.  When dynamic variation is enabled,
regular class threads that do not get the CPU for MAXWAIT seconds (as set in
config.sys) will have a delta applied to their base level, in order to give
them a higher priority and a better chance of running.  At the same time,
threads that consume a large amount of CPU will have a negative delta applied,
in order to free up the CPU for other threads.

This dynamic adjustment does not occur in any of the other classes (or at
least it didn't under OS/2 1.3, and I don't think that changed).

--
-- David
--
/-----------------------------------------------------------------------\
 \              David Bolen             \  Internet: db3l@ans.net      /
  |   Advanced Network & Services, Inc.   \   Phone: (914) 789-5327   |
 / 100 Clearbrook Road, Elmsford, NY 10523  \   Fax: (914) 789-5310    \
\-----------------------------------------------------------------------/
Newsgroups: comp.os.os2.misc