SkeduloSkopeLogo V0.7ß

Massively multithreaded
OS/2 Scheduler in action
exhibitor for developers.

Note: This project is far from complete, for various reasons but primarily because I have been unable yet to resolve certain behaviours of the OS/2 Control Program API. The source code is commented with the problems, and any constructive input is welcome.

OS/2 is about multitasking and it does it incomparably better than you know what and  Linux. OS/2 is also about multithreading, which is much of a likeness, but still different. SkeduloSkope started as a little hack to investigate why processes whose priority I boosted with the ReNice add-on for Watchcat, still failed to run as expected. And also because I saw some documentation from a normally impeccable source that was obviously wrong, but I wouldn't have wanted to challenge without solid proof to the contrary ! As it grew I discovered more subtleties of the scheduler until it became  a very instructive mini-app. While a single instance gives good insight into inter-thread scheduling, to gain insight into inter-process scheduling one needs to run 2 or 3 instances simultaneously.

Sliding bar

!Warnings:
Skeduloskope does not perform any undocumented "tricks" so it should run without causing any damage to your system. However, it does unusual things. Like running more than a thousand threads; like running a large number of Time Critical threads. Do not even think of running it if you are also running some application that needs regular access to the CPU, like writing a CD or running your pet heart-lung machine. It has often hung itself in development on my system but never interfered with other apps I might have had running. Nevertheless, before you first start it, as you should do with any new app you run anyway, make sure all your work is saved first in case you have to reboot. Use a small value for the first parameter until you know what effect it has. OS/2 will not respond to any keys, not even PAUSE, ^C, C-A-D or WatchCat keys while running TimeCritical threads (at least not any time soon). So if you enter large values on a slow machine, you might need to press hardware reset, cycle the power or go shopping !! of course.
It may happen, why I cannot tell, but suspect the scheduler code (because a similar thing can happen with just any other old app) that the program will just hang sometimes, hundreds of threads scheduled but the system won't let them run. This won't interfere with your system (apart from using up your available threads) but it cannot be killed except by reboot.

This is why it's ßeta: In the 160x38 mode, some priority levels, apparently random but always the same on my machine, will hang the app. If you look at the screen when it is ready to run, you'll see some "teeth missing" from the display, and if you inspect the source code you'll see IF statements to prevent those particular priority levels from using the display. If you know what causes this behaviour and how I can get it fixed, please let me know.

! Warnings for more serious implementers:
Running better than the default 80x25 "mode",  especially running several instances, allows one to get a better feel for the scheduler, but many a Config.SYS will not allow you sufficient threads. This is fixed by changing the THREADS= line in your Config.SYS. I believe the default is 1024 but see what yours is first and REM it to remember what it was should you want to go back before entering a new value. Ensure you can start your system with stiffies/maintenance partition/bootable CD/or any other alternative means before you fiddle with your THREADS= line. TIP: When you next reboot your system, press Alt-F1 when booting starts, then F2 to see if \OS2\BOOT\Config.X  still boots your system. If it does not, you can copy your current working Config.SYS over there.

The MAXWAIT= line also affects scheduling; The value is given in seconds (default=3) which is fair for a slow 386 but the minimum, 1, is hardly appropriate for today's machines. While watching the display for FS and Reg threads you will notice they all run a little, periodically; the period is what you specify for MAXWAIT here. TIP: You might as well change permanently to MAXWAIT=1 unless you're running an i386.

My system has THREADS=1312 so it is likely yours will handle that too, but beware, specifying too large a number will use up GDTs that other parts of the system need. When you boot with too large a number for THREADS=, you'll see messages from many device drivers not being able to load. Don't keep on pressing enter, your system won't run. Press C-A-D, restart from your alternative means and tedit config.sys to reduce the number. When you are through with , it may be a good idea to reduce your THREADS= setting to something like 512 or 384. Even power-users hardly ever have more than 200 threads going at once and it does use up a limited resource, GDTs (Global Descriptor Table entries, to be precise) as well as address space (would you believe it, 4GB and we're running short !) as well as just plain old RAM.

Blue Bar

The parameters

            e.g.    "SkeduloSkope 1000 2000"

There are two, both integer numbers from 0 to 231 ( but realistically, no more than about 1 000 000 ).

There are two distinct categories of priorities under OS/2:

  1.  The TimeCritical and the Idle classes share the characteristic that there are no priority boosts; thus a TC+3 thread will not get any CPU while there are "ready" TC+4 and better threads.
  2. The ForegroundServer and Regular classes use a complex algorithm to determine who should run. For this reason, one would want a small number for the first category (they run in a simple order from top to bottom) so that it runs quickly;To adequately observe the other two classes though, one would want a large number so that they run for longer.
The numbers and the period of observation they afford are of course directly related to CPU speed. So for a 386SX16 !! you would probably not want to go beyond 200 800 for a start; On your new GHz Athlon those numbers will get you only a few seconds worth of display, so try 2000 5000 at first and perhaps 1000 20000 later to see the priority boosts.

The program
What it does is to start some threads at all the possible priority levels and then to display them running for your observation. Three "modes" are supported: Normal 80x25 VIO window size (will also run F.S.), 160x20+ and 160x37+. In the 80x25 mode, 256 threads (two per level) is started and prepared "ready to run" and blocked on an event semaphore which gets posted as soon as you press a key. This pause also gives one the opportunity to start more instances of SkeduloSkope (regardless of their "mode"), which, on detecting a "Master" instance already owning the semaphore, will block all it's threads on the same evsem so all the threads of all the instances eventually start together, provided you don't start the master before all the slaves are ready. The 160x20 mode uses 3 threads per priority level (and more significant digits) to afford a more detailed display. The 160x37 mode use 6 threads per priority level, but it is kludged not to hang.
Each thread (and thus priority level) has a given place on the display where it displays it's diminishing number when it has the CPU. The space is labeled with the priority e.g. R07 indicates regular+7. There are also a few help screens when the program is run without parameters.
Thread MetaCode follows:

  REPEAT
        GotoXY(X,Y) ;
        Write(N);
        DEC(N);
  UNTIL N<0;

Blue Bar

Here is the full package SkeduloSkope-0.7.zip(37k),  or  the source code SkeduloSkope.PAS(14k)  or  SkeduloSkope.pas.gz(5k) or download the binary SkeduloSkope.EXE(28k) to your Desktop and run it for an intro.
Here is a screenshot(54k) of 1152 threads in three processes ready to run. The display was 1024x768x16 and each individual VIO window is in 160x21 mode with a font size of 10x6. If you have 4OS2, there is LP.CMD , LP1.CMD , LP2.CMD and LP3.CMD to duplicate this for you.
Blue Bar

Last modified 2002 May 06