Chapter Contents

Previous

Next
Systems Programming with the SAS/C Compiler

Interrupt Handling in SPE

A frequent requirement for systems programming applications is the need to write synchronous or asynchronous exits, such as SPIE or STIMER exits. A C program cannot merely issue the appropriate SVC to define an exit, as an assembler language program does, for the following two reasons:

For example, consider an application that wants to use a C function as a SPIE exit. The function cannot be called directly by the operating system because R13 will not address a usable save area and R1 will not address a C format argument list. Even if it were callable, the C function would not be able to share any data with its caller.

However, it is possible for the exit to call a block of code that establishes (or re-establishes) the C framework and then transfers control to a C function. The code, of course, must be tailored to the specific exit so that the exit's linkage conventions can be honored. In addition, the code has to handle the transfer of control back from the function to its caller. Ideally, the code does no more than necessary to transfer control and does not make any assumptions about the way the calling exit and the called C function transfer data.

In SPE, the bldexit , freeexit , and bldretry functions provide this service. These functions can be used to build exit linkage code that can mediate between the operating system and the C function. (These functions are exclusive to SPE. The standard signal handling functions provide similar services, portably, in the full C framework.)


The bldexit Function

The bldexit function creates a sequence of instructions that establishes linkage between an operating system exit and a C function. bldexit takes two arguments, a pointer to the C function that is to be called and a flag word that describes the required linkage. (The flag word is described in detail in the bldexit function description later in this chapter.) bldexit returns the address of the linkage code, which can then be passed to the SVC that establishes the exit. For instance, suppose a function tmrexit is to be called from an STIMER exit. The following statements call bldexit to create the appropriate linkage and then invoke STIMER:

unsigned intvl = 1000;   /* ten second time interval */
void *exit_addr;         /* pointer to linkage code */

exit_addr = bldexit(&tmrexit, _ASYNCH+_NOR13);

   /* Set up registers for STIMER SVC. */
_ldregs(R0+R1+R15, 0x90000000, &intvl, exit_addr);

   /* Issue STIMER. */
_ossvc(47);

When the timer interrupt occurs, the operating system calls the linkage code built by bldexit . This code saves registers as necessary, re-enters the C framework, and calls tmrexit . When tmrexit returns, the exit linkage code returns control to the operating system. An exit function called by bldexit has the following general definition:

void exit_fun(void **sa, char **poi);

The sa argument addresses a save area where the linkage code saves the contents of all the general registers on entry, in the order 14 through 12. (For example, the contents of register 1 on entry are accessed as sa[3] .) This allows the exit function access to all data passed to the exit. The exit routine can return data to the operating system in any register by modifying the corresponding word in the save area. For example, it can use the following assignment to return 4 in register 15:

sa [1] = (void *) 4;

The poi argument addresses a fullword where the exit can store the point of interrupt (such as an old PSW), if this is meaningful. This information is used by the btrace library function to produce a correct backtrace in the presence of interrupts. There is no reason to store a point of interrupt if you do not call btrace . In some cases, you may not be able to determine a point of interrupt. You can still call btrace in this situation, but the resulting output may be incomplete.


The bldretry Function

Some system exit interfaces, such as SPIE and ESTAE, allow the assembler programmer to request a retry, which causes program execution to resume at a point other than the point of interruption. The SPIE SVC requires the exit to request a retry. Just as defining a C function as an exit does not work, using a C label as a retry address also does not work. bldretry is an interface similar to bldexit , with some differences due to the special requirements for retry routines.

Just as bldexit serves as a mediator between exit linkage and the C function call mechanism, bldretry serves as a mediator between retry linkage and the C longjmp interface. You can think of bldretry as a method of issuing longjmp from an exit function. Of course, the exit must support a retry interface for this to be effective. bldretry is passed two arguments, a jmp_buf defining the retry location and an integer jump code. bldretry builds linkage code for the retry and then returns the address of this code, which can be passed to the operating system to perform the retry.

ESTAE Retry Using setjmp and bldretry shows two code fragments that define a retry location using setjmp and request a retry from an ESTAE exit routine.


ESTAE Retry Using setjmp and bldretry
/* 1. Define post-ABEND retry point. */ if (code = setjmp(ESTAE_jmp_buf)) { /* If ABENDed, retry here. */ } /* normal execution path */ /* 2. Request retry within the ESTAE exit routine. */ SDWA->SDWARTYA = bldretry(ESTAE_jmp_buf, 1); /* Store retry address in SDWA. */ SDWA->SDWARCDE = SDWARETY; /* Tell ABEND to retry. */ return;

In the example, after the return is executed, the retry linkage code is entered. This code performs the equivalent of the following:

longjmp(ESTAE_jmp_buf, 1)

It returns control to the C program at the point where the setjmp function is called.

Unlike bldexit linkage code, bldretry linkage code can be used only once. The code is freed before control returns to the C program.


The freeexit Function

The freeexit function frees the memory used for the linkage code created by bldexit . Obviously, freeexit should not be called until the corresponding exit routine is no longer defined to the operating system.

A complete example of the use of bldexit and bldretry can be found in the source code for the L$UTFPE module. This routine uses the SPIE and ESPIE SVCs to handle computational program checks for the library math functions.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.