Skip to main content
gamedev.net
🔒 Locked

dos multithread

Started by EvilCrap May 18, 2001 at 8:25 AM 18 replies 9.2k views
Original Post
EvilCrap
EvilCrap
hello how do i mutlithread in dos,? i would prefer methods from scratch, opposed to header files, but either is ok. basically, i realize that i would have to create a thread class, and cycle through my threads in a loop. how though, do i tell a thread to goto a specific function or line, execute it, and then return, or update asecond structure? this is my boggle -sending commands to the processor, and fetching a complete command. i have not studied thread header files, etc, listings would be excillent. thanks, Nick
DSutherland
DSutherland
If your compiler supports createthreadex then you could use that, but the problem is that dos is not a multitasking operating system so there is usually no support for threads.

Doug Sutherland
mhkrause
mhkrause
To multithread in DOS, you would have to write a function, like this:

void SwapContext(thread_t a, thread_t b)
{
// Save state of thread a.
// Restore state of thread b.
}

Thread A would call this function, but thread B would return from it.

Writing context-swapping code is very challenging, it is incredibly easy to get it wrong. It must be done in assembly language (since you have to be certain of the contents of every single machine register.)

Each thread you create in the system would be represented by a "thread_t" structure. Among other things, this structure would hold a thread context. This context is the state of the CPU, all registers, the program counter, etc. When you create a new thread, you''d initialize its context to point to some generic thread start function. You''d have an object in your system, the dispatcher, which would be responsible for keeping track of all the threads.

Eventually, a thread will call SwapContext and yield the CPU to the next thread selected by the dispatcher.

This can happen in several ways. A thread can voluntarily yield the CPU. The way this happens is the thread calls some system API which gives up the CPU. This may be explicit yield of the PCU, it may be a wait on some object (like a mutex), or the thread may initiate an IO request that takes some time, like reading from disk.
A cooperative multitasking system implements only voluntary yields. Since this does nothing to ensure fairness, nearly every modern OS (even MacOS now with OS X) implements preemptive multitasking. Each thread is given a slice of time to execute, and is rescheduled when its time is done. To do this, you need to trap a timer interrupt, which is set to fire every x ms (usually 1 - 20 ms). In this timer interrupt, SwapContext is called to switch CPU threads.
This is about all the detail I can hope to go into in a single response to this forum.
If you''re really serious about this, I''d recommend shelling out some money for some books. Inside Windows 2000 is a good overview of a real-world operating system. Operating Systems: Principles and Practice is another good book that is a bit more "academic."
EvilCrap
EvilCrap
thanks for ur responses

i have working knowledge of c++, basic asm , registers.

i understand that id have to have a thread class--

cant the registers be fetched/set from functions like int86, decreasing any requirement for asm?

also, im guessing that there is a register which stores the location for execution ?

so basically, if i make a class, inwhich i represent all registers, i can swap threads by storing, and then re-populating the registers?

if this is so, how do i create a new thread, i mean, what values would i stick in the registers, and im guessing id stick a function-pointer in the location register??
EvilCrap
EvilCrap
thanks for ur responses

i have working knowledge of c++, basic asm , registers.

i understand that id have to have a thread class--

cant the registers be fetched/set from functions like int86, decreasing any requirement for asm?

also, im guessing that there is a register which stores the location for execution ?

so basically, if i make a class, inwhich i represent all registers, i can swap threads by storing, and then re-populating the registers?

if this is so, how do i create a new thread, i mean, what values would i stick in the registers, and im guessing id stick a function-pointer in the location register??
mhkrause
mhkrause
quote:

cant the registers be fetched/set from functions like int86, decreasing any requirement for asm?



Saving CPU state and the restoring the CPU state of another thread must be a single atomic action. There is no standard function available on the DOS platform that does this. (In Windows and Unix, there are some functions available that do this, for user-level threads, or fibers.) You''d have to write your own. This function is heavily OS specific anyway, as it usually refers to data in the thread object.

quote:

if this is so, how do i create a new thread, i mean, what values would i stick in the registers, and im guessing id stick a function-pointer in the location register??



PC should be set to a thread wrapper function. You must allocate a stack, and set the stack pointer to point to that. Set up the stack and the registers for a normal function call to thread wrapper function. Set up the hand off invariant by disabling interrupts, or by raising the interrupt level to disable any context-swapping.
Shannon Barber
Shannon Barber
no you don''t need a class
You need a new OS

You can use threads from a console under Win32

http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/winbase/prothred_3mgj.htm

Magmai Kai Holmlor
- The disgruntled & disillusioned
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
brilliant
brilliant
You do can;
In real mode,use MicroThread V2.5, I just forget where to download, but search in google please.
If you like, I have the library, wrote in pure c/c++, no asm codes, and very easy to understand. send you by email.
Since I have to modify some codes, I have not compile it to library, there maybe a bug in destroy mailbox function.
In PMode, perhaps FSU Pthread is a good choice, POSIX Threads.But I cannot make it because of lack of a header file, or some other reasons. Download it from:
http://www.informatik.hu-berlin.de/~mueller/ftp/pub/PART/pthread.zip

Ilici
Ilici
multithreading in DOS is like multitasking.

to change between threads u have to save each threads state. switching can be done in 2 ways:
- timer based (when t = 0 goto next thread) (preemptive i think linux uses this)
- threads tell the system when they can be switched (i think windows uses this for multitasking) (forgot the name )

u'll have to save for each thread the registers and make sure that the threads dont mess up each others memory.
memory allocation should be smth the system does (make a malloc syscall)

the switching proc should look like this

{
restore regs AX, BX, CX, DX;
restore regs DS, ES, GS, SS;
restore other regs;
far jump to saved mem location (this will set IP and CS)
}

also i think the machine state register Cr0 should be saved.

it's like making ur own OS. i suggest u DONT use ProtectedMode coz things get uglyer. (memory handling becomes harder, just stick to the old SEG:OFF, u wont probably need more than 1mb memory)

the program has to be responsible for loading the threads (i suggest from com files coz exe is more complicated), switching them and responding to interrupts sending data to the current thread. also it should do IO. syscalls should be a good thing. (u could do them hooking interrupt 0x21 and using unused command codes. if the command code is used just revert to the old int 0x21 handler. or just hook int 0x21 completly, but save the handler so u dont have to write ur own stuff for IO).

very interesting ideea multithreading DOS programs. but why?

this DOS stuff is really cool. back to the old days!

EDIT:

about ur questions:

when creating a new thread u just load it, link it to the thread list and jump to it's code. the thread itself should be responsible for setting the registers at start.
the program should take care of allocating memory for the threads code, data and stack.

heres how to save the regs:

struct tRegs
{
unsigned rAX, rBX, rCX, rDX;
unsigned rCS, rDS, rES, rGS;
unsigned rBP, rDI, rSI, rSP;
} regs;

asm {
mov regs.rAX, ax;
mov regs.rBX, bx;
//others also, u get the picturel;
//i have no ideea how to save IP, maybe u should google for that. the BC++7.0 compiler wont even recognize IP reg symbol
}

/*ilici*/

[edited by - Ilici on May 17, 2003 3:35:25 PM]
bjmumblingmiles
bjmumblingmiles
Whats with all the DOS lately? Man...if you really want to make things hard for yourself program a modern low-level platform like GBA or TI calculators...looks like we''ll soon have PSP, too!
My point is, why take a step backwards? Soon people will be asking how to bias vacuum tubes for their brand new mainframe (takes up their whole basement). lol...btw, this isnt a flame, just a rant.

Brian J
Brian J
kieren_j
kieren_j
** The simple answer is: ** you can''t.

DOS isn''t a multithreading operating system. However, you can do interesting things using the timer interrupt (called at 18fps?) other than that, it wouldn''t be using DOS.

If you''re trying to make an operating system or something that runs without DOS, it''s a different story.. there are many "OS-building" websites can help you with that.
Arild Fines
Arild Fines
DOS is dead. Let''s all spit on it''s grave - it was worthless to begin with.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
ApochPiQ
ApochPiQ
Multithreading in pure DOS is stupid given that you can run a multithreaded console app in Windows and make things a hell of a lot easier on yourself.

If you''re dead set on doing it, check out "The Craft of C" by Herb Schildt. He has an entire chapter (and working source code) for building your own multitasking kernel in real mode DOS with C.
Ilici
Ilici
DOS is NOT dead !

just because now we have windows XP and vs.net doesnt mean we can forget about DOS.

u people who think DOS is dead probably never had the pleasure of programming it. now go use the "restart in MS-DOS mode option" !!.

DOS will never die. u people probably dont know that DOS was the first PC operating system and people have used it for a longer time than they used windows.



/*ilici*/
Ilici
Ilici
for u guys with XP a DOS boot disk will do the trick
Arild Fines
Arild Fines
quote:
Original post by Ilici
just because now we have windows XP and vs.net doesnt mean we can forget about DOS.

Yes it does.



AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
HellRaider
HellRaider
quote:
DOS will never die. u people probably dont know that DOS was the first PC operating system and people have used it for a longer time than they used windows.

DOS was not the first PC operating system, although it was a standard for some time.
Genagen
Genagen
As far as I know dos4gw extender has thread functionality under the dos (in cooperation with watcom C++ that is distributed for free now).

Also you can use asm library made by mister Pytel. It is great library written in pure asm and I have used it in my dos assembler project long long time ago. Just try to google it ;-) or send me a mail. I will try find this library in my archives.

Greet

PCHe

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.