[comp.os.msdos.programmer] TC++ coroutines with setjmp/longjmp.

noren@dinl.uucp (Charles Noren) (09/10/90)

Last night at home, reading my TC++ manuals, I came across the good old
setjmp/longjmp library calls.  I've never used them before because of
the inherently non-portable and non-structured nature of the calls.
However, now I am curious about the feasibility of faking a primitive
"multi-tasking" application in TC++ with setjmp/longjmp.  I know that
these functions can be used in setting up coroutines, and the manual
mentions the possibility of several stacks (with appropriate caveats of
not to use the overlay system).

What I would like to do (on my humble 8088 system with only 640K -- I
remember the days when I had an 8080 with 48K and felt like a king, but
I digress) is setup a 4 "process" (maybe more, maybe less) system, where
each "process" follows the discipline of voluntarily calling a function
that would save the context (via setjmp) and then executes a scheduler
which would choose (arbitrary choice, does not matter how for this
discussion) one of four setjmp contexts in which to perform a longjmp
to.  Has anyone tried this sort of thing and have any pointers to share?
I was thinking for having each "process" have its own stack.  I haven't
RFTM enough to find out how to do this in TC++ (prefer to stay in C/C++,
but will do some TASM if necessary) or what the dangers are.  I would
like to implement this in different memory models and would like some
words of wisdom on what I need to do and look out for.

This is merely a recreational home exercise, no urgency, and if there
are no replies I will hack (kids and wife permitting) until I find out
something.  I also want to stick with MS-DOS (3.X -- 3.1 is what I have)
even though there are some very fine DOS alternatives that will do what
I want.

Thanks,


-- 
Chuck Noren
NET:     dinl!noren@ncar.ucar.edu
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 971-7930

milton@zebra.ecn.purdue.edu (Milton D Miller) (09/11/90)

In article <1727@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>
>Last night at home, reading my TC++ manuals, I came across the good old
>setjmp/longjmp library calls.  I've never used them before because of
>the inherently non-portable and non-structured nature of the calls.
>However, now I am curious about the feasibility of faking a primitive
>"multi-tasking" application in TC++ with setjmp/longjmp.  I know that
>these functions can be used in setting up coroutines, and the manual
>mentions the possibility of several stacks (with appropriate caveats of
>not to use the overlay system).
>
>What I would like to do (on my humble 8088 system with only 640K -- I
>remember the days when I had an 8080 with 48K and felt like a king, but
>I digress) is setup a 4 "process" (maybe more, maybe less) system, where
>each "process" follows the discipline of voluntarily calling a function
>that would save the context (via setjmp) and then executes a scheduler
>which would choose (arbitrary choice, does not matter how for this
>discussion) one of four setjmp contexts in which to perform a longjmp
>to.  Has anyone tried this sort of thing and have any pointers to share?
>I was thinking for having each "process" have its own stack.  I haven't
>RFTM enough to find out how to do this in TC++ (prefer to stay in C/C++,
>but will do some TASM if necessary) or what the dangers are.  I would
>like to implement this in different memory models and would like some
>words of wisdom on what I need to do and look out for.
>


The Setjmp/Longjmp calls in TC (not TC++) have been used to implement
this type of multitasking, in fact it is the basis of Phil Karn's
KA9Q/NOS TCP/IP package.   

Rumor has it, however, that the TC++ setjmp/longjmp are broken,
ie they save the state in the wrong order and therefore it can not
be restored, but it is possible to patch the library to reorder
a few instructions to fix it (I don't have a copy of TC++ to look at).

At the heart of NOS is the non-preemptive multi-tasking kernel,
which maintains ready queues, etc and relies on the tasks to
call pwait to sleep (there is also a mode where the current process
will yield but not wait for an event, functions to wake up other
processes, etc.)

So anyway, setjmp/longjmp as the heart of a multitasker is doable,
although bug fixes might be required.   

(BTW, supposedly the MSC 6.? manual says the Setjmp/Longjmp don't
save enough state to be used for this purpose)

Best of luck,
milton

mlord@bwdls58.bnr.ca (Mark Lord) (09/12/90)

In article <1727@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>
>Last night at home, reading my TC++ manuals, I came across the good old
>setjmp/longjmp library calls.  I've never used them before because of

One thing to do is get the patches for turbo c++ 1.0, which include
a bug fix for the setjmp function.  They are available from simtel,
in the turbo-c directory:

	pd:<msdos.turbo-c>tcppt1.zip
-- 
 ___Mark S. Lord__________________________________________
| ..uunet!bnrgate!mlord%bmerh724 | Climb Free Or Die (NH) |
| MLORD@BNR.CA   Ottawa, Ontario | Personal views only.   |
|________________________________|________________________|

sidney@saturn.ucsc.edu (Sidney Markowitz ) (09/12/90)

In article <1990Sep10.234937.12444@ecn.purdue.edu>
  milton@zebra.ecn.purdue.edu (Milton D Miller) writes:

>So anyway, setjmp/longjmp as the heart of a multitasker is doable,
>although bug fixes might be required.   

setjmp, as distributed in TC++ version 1.0 does not save the di
register, but this is fixed, along with a number of other problems, in
Borland's patches.

The patches are available from Borland tech support, from their tech
support forum on Compuserve (GO BPROGB and get TCPPT1.ZIP in Lib 3),
via anonymous ftp from wsmr-simtel20.army.mil in pd:<msdos.turbo-c> or
from wuarchive.wustl.edu in mirrors/msdos/turbo-c, or by email in
xxencoded form from listserv@ucf1vm.cc.ucf.edu by sending it a mail
message that contains the line "get tcppt1 xxe turboc-l" (without the
quotes) as its text.

--sidney markowitz <sidney@saturn.ucsc.edu>

dwg@bpdsun1.uucp (David W. Glessner) (09/12/90)

In article <1990Sep10.234937.12444@ecn.purdue.edu> milton@zebra.ecn.purdue.edu (Milton D Miller) writes:
> [ stuff about setjmp/longjmp for multi-tasking kernel ]

>(BTW, supposedly the MSC 6.? manual says the Setjmp/Longjmp don't
>save enough state to be used for this purpose)

MSC 5.1 setjmp() does _not_ save enough state.  Specificially SS, ES,
and flags.  Multiple "processes" with their own stack (e.g. possibly from
malloc()) will also confuse the run-time stack checking routine __chkstk.

I'm not sure about MSC 6.0.

I've ported parts of KA9Q's NOS to MSC and have modified setjmp(),
longjmp(), and __chkstk to work properly.  E-mail for the gory details.
--
David	WU9A	quintro!bpdsun1!dwg@lll-winken.llnl.gov
		uunet!tiamat!quintro!bpdsun1!dwg