From: ao950 AT FreeNet DOT Carleton DOT CA (Paul Derbyshire) Newsgroups: comp.os.msdos.djgpp Subject: Re: Coding Challenge Date: 3 Nov 1997 07:21:11 GMT Organization: The National Capital FreeNet Lines: 182 Message-ID: <63ju17$p7d@freenet-news.carleton.ca> References: <345D06C6 DOT D67 AT fake DOT com> Reply-To: ao950 AT FreeNet DOT Carleton DOT CA (Paul Derbyshire) NNTP-Posting-Host: freenet5.carleton.ca To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk group (group AT fake DOT com) writes: > A Challenge to all DJGPPers: > > For quite some time we have had LWP and its addition like JTLWP and > PDMLWP to provide multithreading within a single executable. Although > these > libs provide for multithreading with in an exec. there is no facility > for > handling command line multitasking of more than one executable in > traditional > Unix style. Good idea. > The Challenge: > > Write a taskmanager for DOS/DJGPP. > > ( hereafter I will refer to the taskmanager as djmtask ) > > Specifications: > > 1) djmtask would server the djgpp community in general and > would be GLP. djmtask would be made for the community by > the community. One version of djmtask could be chosen > by community consensus as the standard we could all use. You mean GPL right? And I hope you mean after one version is chosen as standard, future versions can exist as long as they are backward compatible with that one. I wouldn't want it to stagnate, even if it manages the miracle of being bug-free right off the bat, in case new features or other improvements are desired. > 2) djmtask would act like a secondary kernal. once started > from the dos command line djmtask would, start Protected > mode, take over command line reading and be responsible > for starting all other executables thereafter. This leads to one possible line of attack. A. Make something that stubedits DJGPP apps to start djmtask right after cwssdpmi and run the rest through it, then people can make "stand-alone" exe's that can be run directly from command.com without an extra step, to get started. (Optional) B. Make it a DJGPP app... C. With LWP... D. And some command interpreter that E. Starts a new LWP thread for each app that is run, and run a function that runs the app, in the new thread; F. Programs written for it must be DLXs such that it is a DLX load and a function call to run the app in E; G. They must call lwp_yield() (sp?) periodically to be friendly, and H. May have threads of their own, as long as they manage the threads reasonably. > 3) djmtask command line interface should conform to standard > linux/unix properities as follows > a) "program.exe &" starts process in background This must be implemented in D. > b) "pid.exe " lists processes and their id #s IDs must be assigned in E. int main (void) { // djmtask main() static unsigned next_pid; . . . //Time to assign a PID int exectask (char *name, int argc, char **argv) { // This runs inside a forked task task t; t.name=name; t.pid=next_pid; t.argc=argc; t.argv=argv; t.env=env; // Global? next_pid++; task_list.push_front(t); // task_list is a deque or something similar return t.launch(); // This loads a dlx called name.dlx and runs a // function of it caled int dlmtask_main (int argc, char **argv, char // *env); it returns the return value of dlmtask_main, which is returned to // the command shell. dlmtask_main deliberately takes after main() in // C/C++.) } Also, it'd be best if the shell is NOT built into dlmtask itself, but is another DLX that is specified perhaps on the dlmtask command line and thus there can be alternatives, like a bash-alike, a csh-alike, a command.com-alike (yuch!)... > c) ALT key plus F1-F10 key switches between 10 virtual > command line terminals. Keyboard interrupts? Might screw up DLXs that use libc input functions. hm. Keyboard interrupt chained? Sees these keys, puts up a flag for dlmtask to see, otherwise, calls the normal interrup? heh. might work. > d) programs may call djmtask to start a completely new > process. Note: this does not start a new "thread" > Threads are still handled internally by the exec. > using LWP or an altered version thereof. They can just call a function fork() that is a global function in dlmtask, assuming DLX allows calls back into the main, which it should (if it doesn't, then we need a better dynamic-link thing for this line of attack). The use of "fork()" makes it POSIX compliant I think. > e) "kill #" ends process id # kill() must be in dlmtask, and resumably uses my deque and sends an lwp kill or a signal or something. > 4) General properties and reasonable limitations; > djmtask may work with non-reentrant lib code > in any way found most useful/stable. > Disabling multiprocessing during BIOS etc. non-reentrant > functions, > using only co-operative yielding etc.. Well, this is handled by using LWP. Then they become the solutions for these in LWP. > 5) Extras > Provide for a common data area, ie. clipboard Also buffers for piping and so forth. These can be global areas new'ed in djmtask at startup, perhaps dynamically resized as needed. (STL container type algorithms.) > Provide for a common graphics environment by sharing *screen > pointer. Use allegro and whims. > This is a community project as much as a challenge so working > in groups > could be beneficial. Well, here I'm contributing much information and ideas for various design issues to everyone for free. :-) One issue: exception handling. Signal handling etc. We may create something like this in djmtask itself: #include in fork() ... set task signal handlers to djmtask generic handlers. Set SIG_DFL to same. void djmtask_yield (void) { set_signal_handlers_to_default_DJGPP_handlers(); lwp_yield(); set_signal_handlers_to_task_handlers(); } Now generic djmtask handlers must somehow kill the app, print a message/dialog, and return to djmtask, NOT exit djmtask too. Also, it would be necessary to create a djm_exit() function. This would have to look up the stack of the thread for the djmtask_main call, and insta-return from them all, kill any child threads etc. This could be called by djmtask_yield if a "soft kill" was done, using some flag. (A "hard kill" or "kill -9" presumably will terminate the threads LWP-style.) The exception handlers would do it too. Or they'd throw a C++ exception and there'd be, in fork(), something like try { return call_task_main(argc,argv,env); } catch (char const *message) { display_exception_message(message); return 255; } -- .*. Where feelings are concerned, answers are rarely simple [GeneDeWeese] -() < When I go to the theater, I always go straight to the "bag and mix" `*' bulk candy section...because variety is the spice of life... [me] Paul Derbyshire ao950 AT freenet DOT carleton DOT ca, http://chat.carleton.ca/~pderbysh