[comp.unix.aux] Why doesn't this simple two line program work

lantz@Apple.COM (Bob Lantz) (01/04/91)

Tony,

You wrote:

>Here is a simple program that works fine when the value 20 is replaced by a
>smaller integer. But when 20 or more lines are printed the program does not
>do anything - it just hangs forever.

>main()
>{
>    register int j;

>    for (j = 0; j < 20; j++)
>	write(1, "Why doesnt this program work for 20?\n", 37);
>}


>Pretty simple program huh? It is shorter than the commands to compile and link
>it.  It is linked to run under A/UX in the MacOS environment (naturally it
>runs fine as a pure UNIX program).

>What am I doing wrong?

You aren't calling WaitNextEvent, EventAvail, or any of the other traps
which give control back to MultiFinder and allow CommandShell to run.

Programs which run in the MacOS environment must be MultiFinder-friendly;
this means, generally, that they must not make blocking system calls.
In your case, you are writing a bunch of data which never gets read by
CommandShell, so your write blocks.  This can be fixed by putting
an EventAvail call in your write loop so CommandShell can run.

This is not necessary (nor, in fact, will it work) for programs which
aren't linked with the Mac libraries and which do not attach to the Mac
environment.

>Cheers,
>Tony Cooper
>sramtrc@albert.dsir.govt.nz

Bob Lantz
A/UX Team

sramtrc@windy.dsir.govt.nz (01/04/91)

Here is a simple program that works fine when the value 20 is replaced by a
smaller integer. But when 20 or more lines are printed the program does not
do anything - it just hangs forever.

main()
{
    register int j;

    for (j = 0; j < 20; j++)
	write(1, "Why doesnt this program work for 20?\n", 37);
}


Pretty simple program huh? It is shorter than the commands to compile and link
it.  It is linked to run under A/UX in the MacOS environment (naturally it
runs fine as a pure UNIX program).

cc -I/usr/include/mac -B /usr/lib/big/ -O -DAUX -c main.c
ld /usr/lib/maccrt0.o /lib/crt2.o main.o /usr/lib/low.o -lmac_s -lld -lmr \
-lc_s  /lib/crtn.o /usr/lib/low.ld

I have played with this one for days and I can't figure it out. MacsBug shows
that it hangs at the trap 0 that is used for the write system call. One way to
get it to work for some cases is to pipe the output somewhere eg a.out | cat,
but more complicated programs print nothing when this method is used (even
though they don't hang). I have played with all sorts of initialisation stuff
like noEvents = 1, InitWindows() InitGraf() and stuff like that but to no avail.

What am I doing wrong?

Cheers,
Tony Cooper
sramtrc@albert.dsir.govt.nz

sramtrc@windy.dsir.govt.nz (01/08/91)

>>What am I doing wrong?
> 
> You aren't calling WaitNextEvent, EventAvail, or any of the other traps
> which give control back to MultiFinder and allow CommandShell to run.
> 
> Bob Lantz
> A/UX Team

Thanks, Bob, for making me Multifinder aware. I read up on MultiFinder
and I have a rough understanding of it now and I got the program running.
My problem was (actually my real problem is that I'm a UNIX programmer
not a MacOS one) that I thought that the example qdsamp.c in /mac/src
was MultiFinder-correct and when I used its event loop I still got the
same blocking on write. So I figured it was not a MultiFinder problem.
Also I thought that setting noEvents = 1 avoids the need for event stuff.
The problem with the qdsamp.c is that it uses the value zero for the sleep
parameter in WaitNextEvent. Zero ticks is not enough time to let
Commandshell do the printing. It is necessary to use a value of about
5 or more. The tricky part is that if the value is not large enough then
eventually the deficit will accumulate and the program will hang again.
So you have to have a large value for safety and that means extra time
is wasted while being asleep. Funny stuff. I couldn't get it to work
using EventAvail - it didn't give Commandshell enough time.

MultiFinder is weird - a program can hog the cpu even while it is asleep.
But I can see a use for that type of multitasking in UNIX. When a window
system is running it should be able to grab as much cpu time as it needs
and only let other processes use its idle time. Then window response is
always the same speed and other process don't suffer since the window
system is still using the same number of cpu seconds per minute as it
was under preemptive multitasking. I wonder how System 7 does it.

I guess I should invest in some copies of Inside Mac and the A/UX Toolbox
manual (I have the 1.0 and 1.1 manuals but it was getting too expensive
to shell out for a third manual set).

I have always thought that the Mac was a fascinating machine. Now with
the UNIX kernel underneath it it is even more so.

Tony Cooper
sramtrc@albert.dsir.govt.nz