Blocking versus Busy Wait (was Re: Give up time slice)

Peter Funk pf at artcom0.north.de
Thu Oct 4 04:56:12 AEST 1990


johnk at telxon.UUCP (John E. Kabat Jr.) writes:
[...]
jk> Sample code (pseudo code)

jk>   while (1)
jk>   {
jk>         check I/o with no wait
jk>         check IPC queue with no wait
jk>         if (no input)
jk>                 nap(100)
jk>    }

Uhh... busy wating. :-(  One of the basic rules in programming on a 
multitasking OS is : Don't use BUSY WAITING.

Normally the 'select(S)' (resp. 'select (2)') system call is intended 
for problems, where one process has to wait for several independent 
input channels.  In your example of course you can't use 'select', since 
'select' is not applicable to IPC.  May be others also don't want to 
rely on such a dubios thing as the 'select' system call. 
  (The 'select' system call is implemented in SCO Xenix since 
   release 2.3., earlier releases have no select.  'select' also 
   requires a little bit of support within the device driver, which 
   makes things worse, when you are relying on third party device 
   drivers for some kind of exotic plug-in board: A very common
   situation in the PC market)

Fortunatelly there is another more portable approach to avoid
busy waiting :  Have a seprarate process for each logical input channel.

Your example above may be coded as shown below (also pseudo code used here) :

    me=fork();
    if (me == 0) {
         while (1) {
	     /* I/O client process : */
	     Wait on input (Blocking Read);
	     Send signal to the other process;
	     /* If the read input data should be transmitted to the other
		process this may be done here (e.g. using a pipe) */
         };
    } else {
	 while (1) {
	     /* Master process : */
	     Wait on IPC Queue;
	     if (errno = EINTR) {
		 no IPC occured : Read from I/O channel
	     } else { 
		 consume IPC data from queue
	     }
	 }
    };

Look's a bit more complicated, although I've left out much of the usually
necessary error checking.  But the use of "busy waiting" or "select" are 
both completely avoided.  To make this approach really work, you should 
spend some careful thoughts on the following topics :
* Think about the 'copy on write' strategy for shared memory pages
  of forked processes.  The I/O consumer processes should be forked
  before you malloc megs of dynamic structures.
* Think about a special software layer encapsulating this kind of
  process communication.  So you may use 'select' or some other
  kind of not so portable hacking inside this layer, without
  having a great impact on your complete software package, when
  you later ran into the need of having to port your package to another 
  less comfortable platform.
    One way to think about process communication on a higher and
  more abstract level is the so called client/server approach.  
  There are commercial packages available, which make
  the developers task to deal with with IPC much more easier.
  (Some people told me, that they think: "System V IPC is one
  great bug" ;-)  
* On SCO Xenix, Sys V shared memory in conjunction with Sys V
  semaphores provide a really fast way of inter process communication.
  (Much faster than pipes).
We have successfully used the approach described above in 
our home grown window system. (Which is a "little bit" smaller, faster
and easier to use than X11 ;-))
  
-- 
Peter Funk \\ ArtCom GmbH, Schwachhauser Heerstr. 78, D-2800 Bremen 1
Work at home: Oldenburger Str.86, D-2875 Ganderkesee 1 /+49 4222 6018 (8am-6pm)
>> PLEASE Don't send BIG mails (oversea) ! I've to pay for it : $0.3/kB
   Don't use the bang path of this news article for mails (They will bounce).
   Only the address 'pf at artcom0.artcom.north.de' will work. Thank You ! <<



More information about the Comp.unix.xenix.sco mailing list