Stuart Cheshire, October 1993. Revised November 1996.
This is a summary of an email conversation with Apple engineers during October 1993. As of November 1996, laptop computers continue to become more popular, but to my knoweldge no power management API such as the one I describe here is yet in development.
If you wish you can skip the motivation section and jump straight to the API description.
One reason I like programming the Mac is that it gives the application programmer a lot of control. It is a lot of work to write a really good Mac program, which puts a lot of people off, but if you are prepared to do that work then there is a lot of scope to do a really excellent job of it. Unix takes the opposite approach -- it makes it really easy to write really mediocre programs with command line interfaces (no menus, no windows, no clipboard, no multi-language international resources etc.) but makes it almost impossible to write really good programs. I think the debate between cooperative and non-cooperative multitasking characterises the whole thing. Good Mac programs can take CPU time when they need it, and relinquish it when the don't, to best utilize the resources of the system. Unix does not allow that. The Unix kernel gives CPU time to the programs in the order and the amount it decides. Really bad programs on Unix can't foul the system up like on a Mac, but really good programs cannot make sensible use of the resources, because they are not allowed to.
Since most Macintosh programmers are prepared to do this extra work to strive for perfection, I think it is really important that Apple provides facilities to allow these programs to "go the extra mile".
One example of being PowerBook-aware is my LaserWriter print accounting software that Stanford uses. When you put a PowerBook to sleep, my user authenticator pays attention to the AppleTalk transition queue events, and cleanly closes its connections. When you wake the PowerBook up again, my software reopens its connections again. It does everything with chained asynchronous calls so as not to slow down the PowerBook wake up sequence. I care about doing it RIGHT, and being "PowerBook-disk-aware" is another part of that.
The fundamental problem here (of the Power Manager monitoring disk access) is an age-old problem of computer science, of virtual memory, disk caching, tape archiving, on-demand connection setup etc. The problem is that you want to know what the user will do NEXT -- what command they will execute, what file they will access, which service they will connect to -- based only on what they have done before. "Least Recently Used" resource management is frequently a pretty poor predictor of what is going to be used again "most soon", which is the real question. When I hit Cmd-S to save a file, what I want is for the disk to be spinning ten seconds BEFORE I save it, so that it is quick to save, not for it to continue spinning AFTER I have saved the file. After I have saved it, there is a good chance that I will NOT touch the disk again for another ten minutes, so ideally we shouldn't keep it spinning. Of course predicting user actions is difficult, if not impossible, and you don't want to make the user select a "Spin up disk" menu command prior to saving in order to achieve this effect. Selecting a menu command takes as long as just hitting Cmd-S and waiting five seconds for the disk to spin up.
HOWEVER, it DOES NOT take an application program five seconds to make a system call. You CAN offer application programs the facility to inform the system that they will be accessing a file shortly, so that the disk can be already spun up when it happens.
Having the PowerManager snoop on file accesses may be the only way to
approximate the user's future access patterns, but it is NOT the only way
to know an application's future file access behaviour. I'd like to see a
way for applications to cooperate more closely with the File Manager and
the Power Manager to improve PowerBook behaviour.
The API I'd like to see:
The call should not be defined in terms of "THE disk", since there may be more than one. I would define the call in terms of the file's WDRefNum -- ie the VRefNum as you would pass to FSOpen when you wanted to open the file. This would uniquely identify the disk (or other device) being accessed.
(This same mechanism might also have use in mediating access to file servers over ARA -- I don't have ARA so I don't know what it's facilities for on-demand connection to file servers are like.)
Some issues to think about: What if the disk is about to spin down in a tenth of a second and a fsPowerManagerIgnore open call is made? It is probably wrong to go ahead and spin down the disk. Perhaps the semantics of fsPowerManagerIgnore (or fsApplicationGenerated, or whatever you call the flag) should be that, since this is a PowerBook aware application, the disk should be kept spinning for as long as that file is open, and when it is closed, the system returns to checking the inactivity timer to decide when to spin the disk down. The assumption is that the application programmer is aware of what he or she is doing, and will open the file, use it, and then close it as quickly as possible. You may want to put a second, separate, inactivity timeout on fsPowerManagerIgnore files too, if you are paranoid and want to guard against ignorant programmers.
Also, if the disk is not spinning, a 'fsPowerManagerIgnore' call should return an error code, since a power-aware application should not be making such a call if the disk is not spinning.