Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!ucsd!pacbell.com!tandem!netcom!resnicks From: resnicks@netcom.COM (Steve Resnick) Newsgroups: comp.os.msdos.programmer Subject: Re: Multi-thread on Ms-dos Message-ID: <1991Mar29.201258.10170@netcom.COM> Date: 29 Mar 91 20:12:58 GMT References: <104499@unix.cis.pitt.edu> <1991Mar22.155529.22@cpqhou.uucp> <10592@uwm.edu> Distribution: comp.sys.ibm.pc.programmer,comp.sys.ibm.pc.misc Organization: Netcom - Online Communication Services UNIX System {408 241-9760 guest} Lines: 70 In article <10592@uwm.edu> markh@csd4.csd.uwm.edu (Mark William Hopkins) writes: >In article <104499@unix.cis.pitt.edu> bill@hpb.cis.pitt.edu (Bill Broadly) writes: >> I need a small C program that allows running more that >>one thread, using setjmp, and longjmp, on a ms-dos machine. Nothing >>pre-emptive needed. > >In article <1991Mar22.155529.22@cpqhou.uucp> pipkinsj@cpqhou.UUCP (Jeff Pipkins @Adv Dev@SE hou ) writes: >>This is a nice thought, but it doesn't work. I actually tried this scenario, >>but the problem is that all threads have the same stack. As soon as any >>one of them do a longjmp(), it throws away a piece of the stack. > >You'll have to elaborate on this one. The longjmp() routine saves the current >stack pointer, and whether a part of the stack is thrown away or not, when >you start up the next thread with another longjmp() the stack pointer is >switched there over to another completely different part of the stack segment >before the previous part of the stack segment has had a chance to get corrupted. > If you don't switch stacks, anything which uses a reasonable amount of stack space will get munged pretty badly. I wrote a multi-thread thingy with Turbo C and assembler. The assembly piece is used to launch the new routine with a new stack. The assembler (for large model code) is: -------------------- Cut Here ---------- Cut Here -------------------------- .model large EXTRN _EndTask:FAR .code PUBLIC _StartTask ; ; Usage: StartTask( void far (*entrypt)(void),char far * Stack) ; ; StartTask sets up a new stack for a particular task, and then calls the ; task entry point. If the newly created task returns, EndTask() is called ; to invalidate the current task, and no more processing occurs. ; _StartTask PROC PUSH BP MOV BP,SP ; Save current stack frame MOV AX,[BP+12] ; Segment Address of New Stack MOV BX,[BP+10] ; Offset Address of New Stack MOV CX,[BP+8] ; Segment Address of entry point MOV DX,[BP+6] ; Offset Address of entry point MOV SS,AX ; Select new stack segment MOV SP,BX ; And set new stack pointer MOV AX,offset CEtsk ; Get IP Value for dummy return PUSH CS ; Make return segment point to here PUSH AX ; Make return offset point to CEtsk PUSH CX ; Push return CS PUSH DX ; Push Return IP RET CEtsk: CALL far ptr _EndTask ; EndTask is a routine which ; invalidates the current thread. _StartTask ENDP END ----------------------------------------------------------------------------- Have fun! :) Steve -- ------------------------------------------------------------------------------- resnicks@netcom.com, steve@camphq, IFNA: 1:143/105.0, USNail: 530 Lawrence Expressway, Suite 374 Sunnyvale, Ca 94086 - In real life: Steve Resnick. Flames, grammar and spelling errors >/dev/null 0x2b |~ 0x2b, THAT is the question. The Asylum OS/2 BBS - (408)263-8017 12/2400,8,1 - Running Maximus CBCS 1.2 -------------------------------------------------------------------------------