Subj : Time Release code for OS/2?
To   : Mike Luther
From : David Noon
Date : Mon Dec 17 2001 11:19 am

Hi Mike,

Replying to a message of Mike Luther to All:

ML> Can someone help me through a native OS/2 way to give up time release
ML> slices for keyboard I/O in both OS/2 16 and 32 bit programs?

The idiomatic approach is to use blocking calls to the Kdb...() API routines.
This eliminates the need to release timeslices. These are 16-bit API calls, but
there are two 32-bit libraries available to support 32-bit programs using these
APIs without thunking, one of which actually works and was written by JdeBP.

If you want to cook a pig's breakfast, you can use the DosSleep() API.

[code snipped]
ML> Do you think it is necessary to follow the same procedure in C/C++
ML> work with, say the WatCom or GPP compilers as in the above?

Absolutely not. Under OS/2, you should never touch the DS register unless you
*really* know what you are doing. [Moreover, pushing and popping DS are
unnecessary for those particular interrupts under DOS.]

You can only use INT 15H/AH=86H under DOS or raw BIOS-binary execution, which
means VDM or VMB when running under OS/2. There is a better way under VDM/VMB,
and that is to use INT 28H instead; your "Windows" code's use of INT
2FH/AX=1680H was also quite popular under VDM/VMB execution prior to Warp 4.
However, such a design is riddled with "DOSthink" and produces a poorly
performing OS/2 program.

For native OS/2 software, whether 16-bit or 32-bit, you must use either the
Kbd...() group of API calls, or DosDevIOCtl() to talk to the keyboard driver
directly.

For 16-bit code, you would normally use the Kbd...() API approach. You can run
your resulting 16-bit program through the binder and have it attach INT 21H
support to the Kbd..() API calls when run in DOS mode. You would need to check
the _osmode global variable before starting any threads, as threading is not
supported under DOS (of course).

For 32-bit code, you can still use the Kbd...() API, but your code must either
"thunk" to 16-bit to use the IBM system DLL, or use a 32-bit DLL instead. I
would generally recommend the latter approach, and Jonathan's CONAPI.DLL works
very well. If you don't mind coding your I/O at the IOCtl level, you can also
use the DosDevIOCtl() API.

Another option is to use PM instead. I don't know whether you are prepared to
go along the GUI path, as this would mean completely separate program designs
for DOS and OS/2.

ML> Obviously this a programming issue and I'll take it elsewhere if off
ML> topic here.

[moderating]
It seems to be quite OS/2-specfic in its programming thrust, so I reckon it is
on topic.

ML> However even OS/2 native programs have the lack of time
ML> slice release protection even as released.

An OS/2 program should not need to yield timeslices.

ML> Based on what does or does not show up here I'll expand what I learn
ML> inot the specialty areas.  I posted the above into the UseNet C++
ML> group as a more general help request and was told it was totally
ML> off-topic

I could well believe that, as there is nothing C++ about it. What there is
linguistically is entirely covered by C, and that is usually sufficient to
raise the hackles of C++ purists.

ML> and that I ought to find a decent modern compiler other
ML> than WatCom for the only reply which was posted ... sigh.

The Watcom compiler is still perfectly serviceable for what you want.

I think you need to address the broader issue of OS/2 program design.

Under OS/2, the majority of API calls that perform I/O block inside the device
driver. This eliminates the need to release timeslices. If you need to have
program execution proceed concurrently with I/O then you should use multiple
threads. In this scenario, you would have a thread that just sits waiting for
the keystroke to arrive from the keyboard; it would not poll! The concurrent
execution is performed in some other thread. Thus, the keyboard thread would
spend the bulk of its life doing absolutely nothing.

Peter Fitzsimmons once posted in this echo that the role of a thread was to do
nothing and do it extremely well. That is sage advice indeed.

Once your keyboard thread collects a sensible looking keystroke, it can then
communicate to the other thread(s), such as by posting an event semaphore or by
simply setting a Boolean flag, that the other thread(s) need to take some
alternative course of action.

So, apart from collecting keystrokes, what does your program do?

Regards

Dave
<Team PL/I>

--- FleetStreet 1.25.1
* Origin: My other computer is an IBM S/390 (2:257/609.5)