Deferring User Interrupt Handling
During the time that the Macintosh is handling a page fault, it is critical that
no other page faults occur. Since no other work is explicitly done by the system
while it is handling a page fault, the only code that can cause this to occur is
code that runs as a result of an interrupt. Consequently, the HoldMemory function must be called on buffers or code that are to be referenced by any
interrupt service routine. You must call this function at non-interrupt level
because the MemoryDispatch calls may cause movement of memory and
possible I/O.
The use of procedure pointers (ProcPtrs) in specifying I/O completion routines, socket listeners, and so forth makes it impossible for drivers to
know the exact location and size of all code or buffers that might be referenced
when invoking these routines. However, these routines must still be called only
at a safe time, when paging is not currently in progress. Because the locations
of all needed pages cannot be known, an alternate strategy is used to prevent a
fatal double page-fault condition.
The DeferUserFn routine is provided to allow interrupt service routines to defer, until a safe time, code that might cause page faults. DeferUserFn determines whether the call can be made immediately and, if it is safe, makes
the call. If a page fault is in progress, the address of the service routine and its
parameter are saved, and the routine is deferred until page faults are again
permitted.