Back

FT_IAmIdle()

The NFPAT1A Patch for the Nanforum Toolkit

or how to make your Clipper 5.2 or 5.3 application release time slices when running under Windows NT, Windows 2000 and Windows XP

The original problem


While sitting in wait states waiting for user response, Clipper applications continously poll the keyboard to see if there are any pending keystrokes. This was no problem in the old days when only one application at a time was running on the computer. But when those applications were moved to Windows and were run simultaneously with other applications, the constant polling became a serious problem because it caused the processor to devote 100% of its time to that task. And all other applications trying to run at the same time on the same computer became dead slow.

The solution


Ted Means, one of the fathers of the Nanforum Toolkit, decided to do something about it. So he wrote a function which, when executed, gives up the remainder of the current time slice and lets the operating system use it for other purposes. He called that function FT_IAmIdle(). Used by itself, it releases one time slice, but Ted also wrote another function, FT_OnIdle(), which detects that the foreground task is in an idle state and allows a codeblock to be evaluated.

When he combined the two functions and let FT_OnIdle() call FT_IAmIdle() whenever it detected an idle state, Ted had created an efficient method to automatically release time slices with only one line of Clipper source code in one single place in the application. Unfortunately, the FT_IAmIdle() docs in the Nanforum Toolkit Norton Guide are a bit on the short side, so the correct usage can easily be misunderstood..

The two functions were released in early 1995 and are included in the 3.05 version of the Nanforum Toolkit,which can be found at the Oasis. This solution works fine on Windows 3.x and Windows 95. Please note that version 3.x of the toolkit is designed for Clipper 5.2 and will not work with earlier Clipper versions. Especially, FT_OnIdle() will not work with Clipper 5.0 since it calls several internal Clipper functions which are not present in Clipper versions prior to 5.2.

A new problem on Windows NT - and a second solution


In 1996 it was discovered that FT_IAmIdle() did not work in protected mode on computers running Windows NT. So Ted added some code to FT_IAmIdle() to make it NT compatible. Unfortunately he did not update the version number or the docs in the ASM file itself to reflect the changes and the new arguments he had added, so one has to know what to look for to distinguish this version from the previous one. But he wrote a separate document, called PAT1.DOC, which was included in the ZIP file NFPAT1.ZIP which was made available on the Clipper Forum on Compuserve in September 1996.

PAT1.DOC describes the new arguments, nIntensity and lForceReal, as well as the complete syntax for the combined function call. But it fails to stress that there is only need for one single call in the Clipper source code, so many Clipper programmers have spent a lot of time trying to modify all their GETs before discovering that all that work had been done in vain.

The NAPAT1 patch has not been applied to the downloadable version of NANFOR.LIB available at the Oasis (in NFLIB305.ZIP). Instead it is available as a separate patch in NFPAT11.ZIP (originally NFPAT1.ZIP).

Still a problem on Windows NT - and the final solution


However, FT_IAmIdle() still did not work on Windows NT in protected mode because there was a small bug in the code. This was corrected by Malcolm Shedden of BlinkInc in 1997, and the new version was released on Compuserve as NFPAT1A.ZIP. Again, there were no changes in the version number or in the docs in the ASM file, but yet another separate document, PAT1A.DOC was added to the zip file. Except for the file date, the only way to distinguish this patch from the previous one is to look at line 67 in the ASM file, where the final version says

 dpmiAX EQU [Word BP-18h]

.  In the previous version, the "h" before the closing bracket was missing.

Unfortunately NFPAT1A.ZIP never made it to the Oasis. I picked it up on Compuserve when it was first released, but since the Clipper Forum was discontinued several years ago, this final patch doesn't seem to be available anywhere any more. In response to a large number of requests on comp.lang.clipper in 2001, I have made the NFPAT1A patch available here.

Updating the library or linking the patch separately


If you have a library manager such as Microsoft’s LIB.EXE you can update your NANFOR.LIB according to the instructions in the accompanying PAT1.DOC file. If not, you can instead add IAMIDLE.OBJ separately to your link script. Of course, it has to be put before the call to NANFOR.LIB in the makefile so it replaces the version in the lib, for example:.

...
file main
file iamidle
file this
file that
...
lib clipper
lib extend
lib nanfor
lib cpmi
...

Don't forget CPMI.LIB if you are linking a protected mode application! If you "allocate" or "search" any of your libraries, don't let the link script excerpt above change that. It is only an example.

How to call FT_IAmIdle()


Please remember that the Norton Guide has not been updated, so be sure to read both PAT1.DOC and PAT1A.DOC for info on the necessary arguments and other usage tips. And again, all it takes to put FT_IAmIdle() to work is one single line at the top or your application:

FT_OnIdle({||FT_IAmIdle(<nIntensity>,<lForceReal>)})


where a <nIntensity> setting of around 30 is usually a good choice (you can test anything you like between, say, 10 and 100 and watch the CPU usage graph in Performance Monitor), and  <lForceReal> must be set to TRUE to make FT_IAmIdle() work on NT-class operating systems.

This single line takes care of all instances of all the different wait states throughout the application. There is absolutely no need to make any other changes in the source code, no need to modify any gets, no need to use any of the available inkey() replacements, etc, etc.

If you are out of practice with code the block syntax, I would suggest that you don't type the function call line into your application. Instead cut and paste the line below and then change the  <nIntensity>  setting if you want a different value:

FT_OnIdle({||FT_IAmIdle(30,.T.)})

Finally...


... yes, the NFPAT1A patch really works. It has been tested on Windows NT4, Windows 2000 and Windows XP with excellent result. And it works equally well on the DOS-based Windows 9x/Me versions. I have also had reports that it works with Citrix Terminal Server and on computers with dual processors.

However, there is one type of Clipper application which does not benefit from the combination of FT_OnIdle() and FT_IAmIdle(), and that is applications that are built around a main loop which checks for a key press with inkey(), processes the key, perhaps does a few other things and then starts over and checks for another key - forever racing around that loop a zillion times per second. Since the idea behind FT_OnIdle() is to detect idle states, it will not work in this environment. The reason is of course that there are no idle states in such an application.

Links:


NFLIB305.ZIP The Nanforum Toolkit library file (from the Oasis). Unpatched!!!
NFPAT11.ZIP The first patch (from the Oasis). Included for reference only.
NFPAT1A.ZIP The final patch (from my site). This is the patch you should use.
The Oasis Go to The Oasis main page
In case you want to talk to me about the NFPAT1A patch and related subjects
(no general Clipper support questions please)
Back Go back to the Engwall InfoTech Clipper Pages main page

This document was last revised on 2007-10-01