🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.os2.programmer
Article #1540

Re: Horses!

#1540
From: Alan Ballard
Date: Fri, 28 Sep 1990 06:01
61 lines
3168 bytes
In article <90270.152726TURGUT@TREARN.BITNET> TURGUT@TREARN.BITNET (Turgut Kalfaoglu) writes:

>... Here is the curiosity: if I put a
>DosSleep(0L) in the main()'s loop where the beginthread is called five
>times to create the five horses, everything is fine. If I remove that,
>five horses are created, but they each receive the same index number (5),
>and they move together too! (so only one horse appears on display). It
>roughly looks like this:
>
>for (j=0;j<5;j++)  {
>  if (_beginthread(horse,NULL,4096,&j) == 0)  {
>     printf("Error");
>     exit(1);
>  }
>  DosSleep(0L);
>}
>I remove the DosSleep and it no longer works!
>
>Any ideas?  Is it a bug in OS/2 1.1 that got corrected with 1.2 ?

Nope, its a bug in your version of the program.  You're passing the address
of the variable j.  There are no guarantees about when the new processes
will actually get to execute.  Without the DosSleep, the main thread
keeps running, for a while, and by the time the other threads
get to pick up the parameter it has already changed back in the main
thread.  DosSleep with a parameter of zero gives the threads a chance
to run for one time slice, so they pick up the value at that time and each
get the appropriate value. 

To do this properly, you need to either pass the parameter by value, as it 
was in the original version or use semaphores to properly synchronize
the startup so that each thread gets its parameter before the main
thread goes on to start the next.

Norton/LaFore's version of this program contains a C coding bug in the 
stack initialization, by the way (which may be the reason you switched
to _beginthread?) 
The line 
   stkptr = (int far *)malloc(STACK_SIZE) + STACKSIZE;
should replaced with some variant of
   stkptr = (int far *)((char far *)malloc(STACK_SIZE) + STACK_SIZE);

I've found Norton/LaFore good for getting the basic idea of the OS/2
kernel services, but it is rather casual about IPC issues in many
of the multi-threaded processes.  The requires synchronization is only
done in places where it is the subject of the example; lots of other 
critical sections are really needed to make the programs 
behave as described. 

>Also I noticed that if the main() ends, even with DosExit(0,0),
>all threads are killed, which is contrary to Peter Norton's book..
 
I seem to recall this was a change between 1.0 and 1.1 (or maybe
between 1.1 and 1.2).  When the main thread exits, all threads exit.



Alan Ballard                   | Internet: ballard@ucs.ubc.ca
University Computing Services  |   Bitnet: USERAB1@UBCMTSG
University of British Columbia |    Phone: 604-228-3074
Vancouver B.C. Canada V6R 1W5  |      Fax: 604-228-5116
Technical Details
Message-ID: <9778@ubc-cs.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!van-bc!ubc-cs!cheddar.ucs.ubc.ca!ballard
References: <90270.152726TURGUT@TREARN.BITNET>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!van-bc!ubc-cs!cheddar.ucs.ubc.ca!ballard
From: ballard@cheddar.ucs.ubc.ca (Alan Ballard)
Newsgroups: comp.os.os2.programmer
Subject: Re: Horses!
Message-ID: <9778@ubc-cs.UUCP>
Date: 28 Sep 90 06:01:45 GMT
References: <90270.152726TURGUT@TREARN.BITNET>
Sender: news@cs.ubc.ca
Reply-To: ballard@cheddar.ucs.ubc.ca (Alan Ballard)
Organization: UBC Computing Centre, Vancouver, B.C., Canada
Lines: 61