Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!relay.nswc.navy.mil!oasys!oasys.dt.navy.mil!science From: science@oasys.dt.navy.mil (Zimmermann) Newsgroups: comp.sys.mac.system Subject: Re: Why I Would Like "True Multitasking" Keywords: multi-tasking Message-ID: <8774@oasys.dt.navy.mil> Date: 28 Jun 91 11:55:56 GMT References: <1991Jun28.005152.5815@cs.sfu.ca> Sender: news@oasys.dt.navy.mil Organization: David Taylor Research Center, Bethesda, Md. Lines: 122 I agree 100% ... I too would like easy multitasking for simple programs written in THINK C. (It would be nice if the multitasking included a measure of protection from my program locking up the machine, but I guess that's beyond the realm of what's possible for the next few years (System 8?).) But a little library function to call sporadically, perhaps, to handle events generated by other programs in a natural way, wouldn't seem to be too tough to write, for somebody who knew Mac internals to a fair degree. Better yet, but no doubt tougher to produce, would be an interrupt-driven routine which would break in on a running program (as the THINK C debugger does) and give some time slots to other processes. But writing one of those would probably be a job for a wizard at Symantec with access to the compiler's inner workings. MacForth programs, many many years ago, had simple multitasking that Don Colburn designed into the language (and this was pre-MultiFinder, note!) so that whenever one program running executed a particular routine (either calling it voluntarily, or automatically when asking for disk or keyboard/screen I/O) control passed on to the next in the tasking loop ... worked nicely within the little universe of Forth programs, and allowed a lot of productive work to go on at once. I am particularly interested myself in building big free-text inverted index database files in background ... it takes several minutes per megabyte to parse and sort pointers to all the words in a text file (on current-genearation Macintoshes), and doing this kind of process in background is an ideal way to operate. I can already do it nicely that way on UNIX machines --- so why can't I on the Mac? Actually, a few years ago, I did just this, exceedingly crudely, in a program called "MultIndexer", what I called a "MultiFinder-tolerant" (since it wasn't "friendly"!) way to do background index-building. What the heck ... I doubt that it will work any more, but here is the key routine, "check_events()", which I scattered calls to throughout my numbercrunching/quicksorting program. Maybe somebody kind can tell me whether an update or modification or analogue to this type of thing could still work these days?! -------------THINK C code follows-------------------- /* function to check for user interruption of operations (for use in the * Macintosh version of this program only) ... call SystemTask() to give * desk accessories a bit of time, and then check for non-null events * with GetNextEvent() ... if something comes along, let the user choose * to exit the program or to carry on if it's a keystroke .... otherwise, * just ignore the event for now. Call this pretty often, for multifinder * compatibility.... the 'greed' parameter (default -5) tells how often * to give other jobs a chance. greed = -1 is most generous; as greed * gets more negative, longer intervals elapse before giving up control. */ #ifdef LIGHTSPEED void check_events () { EventRecord my_event; char cmd[256], *gets(); extern long greed; void exit(); static unsigned long trigger_time = 0; if (TickCount () < trigger_time) return; trigger_time = TickCount () - greed - 1; SystemTask (); if (GetNextEvent (everyEvent, &my_event)) { switch (my_event.what) { case nullEvent: case mouseDown: case mouseUp: case keyUp: case autoKey: case updateEvt: case diskEvt: case activateEvt: case networkEvt: case driverEvt: case app1Evt: case app2Evt: case app3Evt: case app4Evt: default: break; case keyDown: fprintf (stderr, "Quit indexing now?\n"); gets (cmd); if (cmd[0] == 'y' || cmd[0] == 'Y') exit (0); break; } } } #endif ----------------------end of C code--------------------- As you can see, it's crude, but it did work; I typically set the "greed" parameter to give up control every 0.1 second or so, with decent results. To update this, I wonder if there would have to be new events added to the list, or new calls made to new Toolbox routines? Note that this thing using the above function only was able to switch to another process under MultiFinder if the user clicked on the little icon at the right-hand end of the menubar ... the routine did NOT properly recognize mouse clicks on other processes' windows. That needs to be fixed. And since under System 7 nowadays one has to pull down the menu at the right end of the menubar, rather than just click on the icon, to switch foreground jobs, I expect that further surgery is needed to make the check_events() function work.... Any suggestions/ideas/comments? Tnx for reading this far, Mom ... am sure you're the only one left.... :-) Best, ^z Mark Zimmermann, "science@oasys.dt.navy.mil"