Chapter Contents |
Previous |
Next |
Systems Programming with the SAS/C Compiler |
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.