Handler Execution



next up previous
Next: Reliability Up: Implementation Previous: Differing Address Space

Handler Execution

In the traditional networking stacks, asynchronous notification is accomplished by using signal driven I/O. Upon arrival of a message, the OS can deliver a previously defined signal to designated process. In the AM implementation, this process will register an active message dispatch handler. This handler will first check whether data is waiting to be read, since anyone could have delivered the signal. Next, it will look up the address of the corresponding request handler, using the address identifier as an offset into the array of request handler addresses. If the tag is not bound to a request handler function, a ``sink'' function should be executed that simply removes the packet from the network. If the tag is bound, the dispatcher invokes the request handler with any arguments optionally packed into the message and a pointer to the message itself. The user's handler is then allowed to run to completion, optionally sending a reply AM to the originator.

It is conceivable that the user would wish to have option of declaring critical sections. This is especially important to consider when the user's process is performing system calls, most of which can be interrupted by a signal. Guarding against this situation usually requires watching for a special return code. If this code is returned, the call must be invoked until a different code returned. Systems conforming to the 4.2 BSD release of Unix do this automatically. However, given the wide variety of platforms we wish to support, this cannot be relied upon. If the user does choose to make system calls while communication is taking place, those calls must not reference any buffer whose contents are suspect. Aside from the nuisance to the user, repeated system calls can cause unnecessary process suspension and context switching delays. Two solutions to this problem are available. The first is a true lockout, where the kernel actually prevents the signal from being delivered until the user indicates that it is ok to do so. The second solution, recommended for debugging and I/O-intensive applications, is to do away with asynchronous notification completely and poll for all messages. Currently, all active messaging implementations used polled I/O, mainly because the polling function also performs the check for stale requests. Where polling is chosen over interrupts, the request and reply calls should automatically pollgif the network at the beginning and end of every call. However, the user must be careful not to ignore the network in computation-only loops. Hence, an explicit call to poll the interface is provided. To achieve widespread acceptance, the burden on the user of AMs must be minimal. Thus, a function could be provided that can register an alarm handler that performs this polling on a regular interval.

Theoretically, active messages are executed immediately upon arrival. As mentioned before, these messages simply remove the data from the network and integrate it into the ongoing computation. An arbitrary time limit could be imposed on the handlers to prevent deadlock and aid in debugging. However, this should be available only as a compile time switch to the library, since the management of many alarms is quite expensive.



next up previous
Next: Reliability Up: Implementation Previous: Differing Address Space



Jack Dongarra
Tue Feb 7 21:45:39 EST 1995