Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Free use of contingency routines

&pagelevel(5)&pagelevel

For special requirements that are not covered by the signal() and raise() functions, appropriate BS2000 functions for eventing can be freely programmed. Such requirements include, for example, a greater number of events (only two events can be defined with raise() and signal()) or inter-task communication (raise() and signal() permit eventing only within a single task).

Functions for actual eventing, such as starting event-driven processing and sending and receiving signals, must be implemented in Assembler program sections with the appropriate BS2000 macro calls (POSSIG, SOLSIG, ENAEI).

The macros for enabling, disabling and terminating contingency processes (ENACO, DISCO, RETCO) must not be used in the Assembler program section. Instead of these macros, the C library functions cenaco() and cdisco() must be called. cenaco() and cdisco() not only enable and disable contingency routines, but also perform specific actions that are required to ensure that the consistency of the C runtime stack is maintained.

The contingency routine itself can be written in C or in Assembler. Termination of this routine must be effected by means of a "normal" return (with return() or longjmp() in C, and with @EXIT in Assembler).

Contingency routine in C

When the routine is started, a structure parameter is passed to it. This parameter is declared in the header file cont.h as follows:

struct contp
{
int     comess;         /* contingency message */
evcode  indicat;        /* information indicator */
char    filler[2];      /* reserved for int. use */
evcode  switchc;        /* event switch */
int     pcode;          /* post code */
int     reg4;           /* register 4 */
int     reg5;           /* register 5 */
int     reg6;           /* register 6 */
int     reg7;           /* register 7 */
int     reg8;           /* register 8 */
};
#define evcode     char
#define _normal    0       /* evceventnormal */
#define _abnormal  4       /* evceventabnormal */
#define _nmnpc     0       /* evcnocomessnopostcode */
#define _mnpc      4       /* evccomessnopostcode */
#define _nmpc      8       /* evcnocomesspostcode */
#define _mpc       12      /* evccomesspostcode */
#define _etnm      0       /* evcelapsedtimenocomess */
#define _etm       4       /* evcelapsedtimecomess */
#define _disnm     16      /* evceventdisablednocomess */
#define _dism      20      /* evceventdisabledcomess */

If the structure parameter described above is to be evaluated, the C routine must provide a formal parameter for a structure of type contp and could be constructed as shown below:

#include <cont.h>
void controut (struct contp contpar)
{
...
   return ...;
}

The C routine can be terminated in one of the following two ways:

  • with the return statement, which causes the program to be continued at the point of interruption or

  • by calling the lonjmp() function, in which case the program is resumed at the position defined by a setjmp() call.

Contingency routine in Assembler

The contingency routine must be written in Assembler if, for example, further BS2000 macro calls are to be made in it (such as SOLSIG for renewal of the contingency routine).

A structured ILCS Assembler program for a contingency routine is structured something like this:

PARLIST  DSECT
COMESS   DS     F
IND      DS     C
FILLER   DS     CL2
EC       DS     C
...
CONTROUT @ENTR  TYP=E,ILCS=YES
USING  PARLIST,R1
...
SOLSIG
...
@EXIT

The RETCO macro must not be invoked in the contingency routine.
The return must be effected with the @EXIT macro.