lupini@cs.sfu.ca (Peter Lupini) (06/28/91)
Hi, First of all, let me say that I think the mac is a *fantastic* machine - I use my IIci for all my research, plus a little graphic arts on the side. But...without wanting to start up the whole "true" multi-tasking debate, here is what I miss most about the current mac system: I write many programs each day as part of my research. Usually, these are numerically intensive tasks. When I used to do this on an Amiga, I could just write my program, run it, and then open a new window and keep working. I could even assign a priority to my "background" task so that I could do useful work in the foreground. With the Mac, I use THINK C. But when I run a program, I have no way of doing this. I must wait until the program has completed execution. I can't even switch to my terminal session and work on the remote machine. I guess my definition of "True Multi-tasking" is that I can write a program without knowing anything about multi-tasking, and run it in the background. So here are my questions: 1) Am I missing something obvious here? I am assuming that I have to make my program "multi-finder" aware or something, and make it be smart about not taking all the cpu time while it is running. This seems to be an incredible pain when I'm just writing quick 'n dirty programs which may be used for only a week or so. 2) Does apple have plans to modify the operating system so that this is possible? 3) Am I the only one who has this problem? I would have thought that anyone who uses the mac to write programs that are not specifically for the mac user interface (eg. most of my interface consists of a unix-type command line!) would run intot this problem. Any answers/comments would be appreciated!
science@oasys.dt.navy.mil (Zimmermann) (06/28/91)
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"
bc@Apple.COM (bill coderre) (06/29/91)
lupini@cs.sfu.ca (Peter Lupini) writes: |So here are my questions: |1) Am I missing something obvious here? I am assuming that I have to make my | program "multi-finder" aware or something, and make it be smart about not | taking all the cpu time while it is running. This seems to be an incredible | pain when I'm just writing quick 'n dirty programs which may be used for | only a week or so. Peter: Without getting into a big argument about what "true multitasking" is ("I dunno, but I knows it when I sees it") let me just give you a pragmatic answer about writing your programs. The bad news is: yes, you do have to write your programs in a special way to allow Multifinder to switch them to the background. The good news is: it isn't that hard to do, it ends up being pretty much what you might think of doing in a non-multitasking OS, and the code is available as templates and easily re-used. The "Programmers Guide to Multifinder" from APDA provides the precise details of how to do it, but so do several articles in MacTutor, MacTechQuarterly, and other mac programming journals. Code is available from APDA, from ftp.apple.com (I believe, I haven't checked recently), and from those magazines. I also believe that The Macintosh Programming Primer (volume 1, c or pascal version) provides some sample code and explanations about the methodology required. The basic strategy revolves around the program's Main Event Loop. In the "usual" form of this loop, the program checks to see if any events are pending by calling GetNextEvent, then dealing with them. In the Multifinder-friendly app, the program calls WaitNextEvent, and then chooses what to do with events it receives belonging to it, determined by whether or not it is "busy calculating". The simple approach is to set a global flag (like gBusyCalculating) when you have finished setting up to do the calculation. When the Main Event Loop sees the flag set, it ignores most events (except, for example, a command-period keypress), and instead calls a routine that does a small amount of the calculation in question (for example, DoOnePixel). By tuning the parameters to WaitNextEvent, you can determine just how much of your CPU will be eaten by the background processing. This method requires a little code, but not a whole lot. Indeed, I have a standard Mac Main Event Shell that I add to code I'm porting from Unix that provides all the necessary operating system support code I need. It even provides an acceptable user interface for no particular extra charge. There are obviously more issues to multitasking in the MacOS than I've covered, but don't think it's very hard to do at all. bill coderre who actually wrote Mac code before Apple hired him
peirce@outpost.UUCP (Michael Peirce) (06/29/91)
You forget that the Mac was not designed to be a *programmers* computer, rather it was designed to be a *users* computer. On the original Mac you couldn't even program on it - you had to compile your code on a Lisa, then bring it over. The trade off is that to make easy to use programs, it's often somewhat of a pain to program. Having said that, you might check into using MPW. MPW *was* meant to be a programmer's environment - even if it had to sacrifice some Mac-ness. With MPW there's more to master than with THINK C, but it provides a nice command line environment - not unlike a Unix or VMS system. And, here's really why I recommend it to you, you can write non-Mac-like programs as an MPW tool that MultiTasks without dealing with event loops. All you need to do is sprinkle calls to SpinCursor() throughout your code. Not only does this spin the cursor, but using a little magic it takes care of all the event stuff for you enough that you can switch to other programs in MultiFinder and run other Apps (like terminal sessions) while your CPU bound non-Mac-like program churns away. The MPW shell will contain all your program's output (from either printf or writeln calls) and you can even redirect it (like in Unix or VMS). If you've used "big" machines, you'll feel right at home in MPW. Try, you might even like it... -- michael -- Michael Peirce -- outpost!peirce@claris.com -- Peirce Software -- Suite 301, 719 Hibiscus Place -- Macintosh Programming -- San Jose, California 95117 -- & Consulting -- (408) 244-6554, AppleLink: PEIRCE
frain@cis.ksu.edu (Jerry Frain) (06/30/91)
peirce@outpost.UUCP (Michael Peirce) writes: >You forget that the Mac was not designed to be a *programmers* computer, >rather it was designed to be a *users* computer. Gee, I always thought that programmers *are* users. >On the original >Mac you couldn't even program on it - you had to compile your code >on a Lisa, then bring it over. Boy that makes me feel so much better. Maybe we need to add a card reader device driver to MacOS to make programming even more fun. >The trade off is that to make easy >to use programs, it's often somewhat of a pain to program. It doesn't have to be that way. However, that is the way computer evolution tends to go -- learn how to do it with much sweat and tears and blood, then make an easier way to do it with the benefit of hindsight. --Jerry Frain, frain@cis.ksu.edu
ingemar@isy.liu.se (Ingemar Ragnemalm) (06/30/91)
peirce@outpost.UUCP (Michael Peirce) writes: >You forget that the Mac was not designed to be a *programmers* computer, >rather it was designed to be a *users* computer. On the original >Mac you couldn't even program on it - you had to compile your code >on a Lisa, then bring it over. The trade off is that to make easy >to use programs, it's often somewhat of a pain to program. With the Think compilers around, and the tools available to modularize the code better, I don't think the Mac is a pain to program. However, trying to program in Megamax C or TML Pascal (pre-MPW) was a pain, especially without the "modularizing" tools (OOP libs, TransSkel, MacApp etc). (I wouldn't mind protcted memory when programming, though.) -- Ingemar Ragnemalm Dept. of Electrical Engineering ...!uunet!mcvax!enea!rainier!ingemar .. University of Linkoping, Sweden ingemar@isy.liu.se
krk@cs.purdue.EDU (Kevin Kuehl) (07/01/91)
In article <frain.678267470@orion> frain@cis.ksu.edu (Jerry Frain) writes:
Gee, I always thought that programmers *are* users.
I think you missed Michael's point completely. Just because a
programmer is a user does not mean a user is a programmer. For
instance when I use my Mac at home I have completely different needs
than when I program my Sparc in my office. I don't really need (or
want) the overhead of a preemptive scheduler on my Mac but I wouldn't
be without it on my Sparc. Not because the Sparc is so much faster,
but because of the nature of the work I do on the machine.
It doesn't have to be that way.
Sure it doesn't. But so far I have not seen a computer that is both
really easy to use and really easy to program (I assume from
complaints that the Mac is hard to program). The NeXT's I have worked
on come closer than most, but I still don't find them as easy to use
as my Mac.
--
Kevin Kuehl
krk@cs.purdue.edu
keith@Apple.COM (Keith Rollin) (07/01/91)
In article <54465@apple.Apple.COM> bc@Apple.COM (bill coderre) writes: >lupini@cs.sfu.ca (Peter Lupini) writes: >|So here are my questions: >|1) Am I missing something obvious here? I am assuming that I have to make my >| program "multi-finder" aware or something, and make it be smart about not >| taking all the cpu time while it is running. This seems to be an incredible >| pain when I'm just writing quick 'n dirty programs which may be used for >| only a week or so. > >Peter: Without getting into a big argument about what "true >multitasking" is ("I dunno, but I knows it when I sees it") let me >just give you a pragmatic answer about writing your programs. > >The bad news is: yes, you do have to write your programs in a special >way to allow Multifinder to switch them to the background. I missed the rest of Peter's post, but it seems to me that the "bad news" as Bill puts it is not really relevent. In order to live with MultiFinder, you just have to call GetNextEvent like you would in every other application anyway. You only have to "write your programs in a special way" if you want to be an Exceptionally Good Citizen. If Peter is writing throw-away code, then he doesn't need to do this. Of course, if you use a class library like MacApp or TCL, then you don't even have to think about any of this; the class library will handle it for you. -- ------------------------------------------------------------------------------ Keith Rollin --- Apple Computer, Inc. INTERNET: keith@apple.com UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith "But where the senses fail us, reason must step in." - Galileo