The revelation of St. f0dder the Divine



Same warning as usual, if you want sense in assembler programming, go
to CLAX.

The next item in a series of sermons delivered from the Gospel
according to f0dder comes in an area of low level programming
techniques available to almost any programmer who ever worked on a
computer. The technique is the use of a polling loop for performing a
range of tasks common in computers where you periodically test for a
result.

Out of a long list of things that are illegal, immoral and fattening,
will rot your socks, make your hair fall out and leave you in failure
of compliance to many of the publicaly stated "One True Way"
methodology lists, you can now in compliance to the Gospel according to
f0dder, abandon such fundamental techniques as "POLLING LOOPS" and
commit you code design to bundled high level techniques.

The topic of this often repeated sermon from the Gospel according to
f0dder was the use of a Windows system API, WaitForSingleObject() and
while the Gospel according to f0dder was preached hard and often those
"damned pagans" still refused to be "born again" into the kingdom of
enlightenment according to the Gospel according to f0dder.

Now while there is probably nothing wrong with the API
WaitForSingleObject() or more efficiently WaitForSingleObjectEx() where
you avoid the wrapper and save a slight overhead in making the internal
call to NTDLL.DLL, it still suffers the clunky and less flexible format
of high level code when coding something as trivial as a polling loop
has none of the irritations and alows you to multiple things in a very
simple and efficient way.

A standard system defined Window message loop is a very good example of
performing multiple tasks in a polling loop. The GetMessage() API calls
the system and simply does not return unless there is a message in the
que so that app sits there suspended when it is not doing anything.
This is pretty standard stuff for a message driven windowing system.

Now when there is a message available that is passed through the
message loop, it gets fed first to TranslateMessage() and then if you
want to perform keystroke processing, you poll for certain key
combinations within the main polling loop and respond as you see fit.
If you need to do so, you can defeat the final DispatchMessage() which
passes the message to the WndProc or similar procedure and loop back to
GetMessage() and get the next message. You do things like this to
remove default keys for controls so you can process you own key
combinations.

Now the offending polling loop according to the Gospel according to
f0dder was this.

@@:
invoke GetExitCodeProcess,pr_info.hProcess,ADDR xc
invoke Sleep, 1
cmp xc, STILL_ACTIVE
je @B

In order, it tests for an exit code from a running process, yields
processor time back to the operating system, compares the exit code to
a constant then polls again if it does not match. Having the right toys
makes testing the efficiency of this technique very easy. The
Sysinternals guys post an excellent tool for testing just this type of
operation, it is called "Process Explorer" and it tells you all sorts
of interesing things about the OS you ae running.

Run a polling loop of the type above and the process takes so little
processr time that it does not display any percentage of processor
time. The real culprit is system idle that takes up about 93% of
processor usage at idle and the other culprit is the system interrupts
that take up 7% while the machine is just sitting there doing nothing.
These percentages will vary depending on how much stuff your box runs
at idle.

Now perform the same task using WaitForSingleObjectEx() and the numbers
don't change but what little overhead that is involved is shifted from
the app to the system interrupts, a perfect example of you get nothing
for nothing when it comes to polling for events. These things don't
happen by immaculate conception or magic or the actions of the fairies
or anything else.

Now this says that there is nothing wrong with using
WaitForSingleObjectEx() if it will in fact perform the task you require
but its more complicated and a rather clunky to use where a polling
loop is more flexible, simpler and a lot clearer to understand.

If for example you need to delegate a task to an external process that
may be a slow one or that risks locking up for some reason, its very
simple to just add a key test within the polling loop so that if the
user think the delegated process has locked up, they can press escape
and exit the loop. Then if the programmer think that the user may end
up bored or uninformed with a slow external process, he can easily add
a millisecond display that is run from the same polling loop.

Ypu can probably do all of these things by chasing down the high level
API calls for catching signal states of a range of tasks from the
operaing system but its a case of why bother with the additional
complexity and code size when you can roll your own in a simpler,
clearer and more flexible code design that is just as efficient as
anything else. This is just another application of the KISS principle
or if you like the more technical description, the application of
Occam's Razor, never do more than you need to do.

Sad to say for the Gospel according to f0dder, Occam's razor cuts its
throat every time.

Regards,

hutch at movsd dot com

.



Relevant Pages

  • Re: Alternative process termination notification in a GUI
    ... > Now note that this technique will bring howls of protest at using a ... > polling loop from the Gospel according to f0dder, ...
    (alt.lang.asm)
  • Re: Bugs in donkey.lib
    ... More waffle. ... > There's no excuse whatsoever for using the polling loop, ... forget the Gospel according to f0dder. ... The Gospel according to f0dder speaks with a forked tongue yet again. ...
    (alt.lang.asm)