The following program calls CEEHDLR to register a user-written
condition handler for the out-of-storage condition, calls CEEGTST
to allocate heap storage, and calls CEECZST to alter the size of the
heap storage requested.
*Process macro;
/***********************************************************/
/* */
/* CECNDXP - Call the following Language Environment */
/* services: */
/* - CEEHDLR - Register user condition handler */
/* - CEEGTST - Get heap storage */
/* - CEECZST - Change the size of heap element */
/* - CEEHDLU - Unregister user condition handler */
/* */
/* 1. A user condition handler CEENDHD is registered. */
/* 2. A large amount of HEAP storage is allocated. */
/* 3. A subroutine, Sub, is called which is known to */
/* require a large amount of storage. It is not known */
/* whether the storage for Sub is available during */
/* this run of the application. */
/* 4. If sufficient storage for Sub is not available, */
/* a storage condition is generated. */
/* 5. CECNDHD gets control and sets resume at the */
/* next instruction following the call to Sub. */
/* 6. A test for completion of Sub is made after */
/* the subroutine call. If Sub did not complete, */
/* a large amount of storage is freed, and Sub */
/* is invoked a second time. */
/* 7. Sub runs successfully once it has enough */
/* storage available. */
/* */
/* Note: In order for this example to complete */
/* successfully, the FREE suboption of the HEAP */
/* runtime option must be in effect. */
/* */
/***********************************************************/
Cecndxp: proc options(main);
/**************************************************/
/* Important elements are found in these includes */
/* - feedback declaration */
/* - fbcheck macro call */
/* - condition tokens such as CEE000 */
/* - entry declarations such as ceehdlr */
/**************************************************/
%include ceeibmct;
%include ceeibmaw;
dcl Cecndhd external entry;
dcl 1 fback feedback;
dcl token fixed bin(31);
dcl newsize fixed bin(31);
dcl (heapid, hpsize) fixed bin(31);
dcl addrss pointer;
dcl ran char(1);
/*********************************************/
/* Register a user-written condition handler */
/*********************************************/
token = 97;
Call ceehdlr(Cecndhd, token, fback);
If fbcheck (fback, cee000) then
display ('registered user handler');
else
display ('CEEHDLR failed with message number ' ||
fback.MsgNo);
/*********************************************/
/* Allocate some HEAP storage, and then call */
/* subroutine Sub. When Sub becomes active, */
/* an out-of-storage condition arises if */
/* the region is too small. */
/*********************************************/
heapid = 0;
hpsize = 500000;
call ceegtst (heapid, hpsize, addrss, fback);
If fbcheck (fback, cee000) then ;
else
display ('CEEGTST failed with message number ' ||
fback.MsgNo);
ran = 'x';
ran = sub();
if ran ¬= 'r' then
do;
/*******************************************/
/* If Sub did not run, reduce the size of */
/* allocated storage and call Sub a 2nd */
/* time. */
/*******************************************/
newsize = 2000;
call ceeczst (addrss, newsize, fback);
If fbcheck (fback, cee000) then ;
else
display ('CEECZST failed with message number '
|| fback.MsgNo);
display ('Call subroutine for the 2nd time');
ran = sub();
end;
/*********************************************/
/* Unregister the user condition handler */
/*********************************************/
Call ceehdlu (Cecndhd, fback);
If fbcheck (fback, cee000) then ;
else
display ('CEEHDLU failed with message number ' ||
fback.MsgNo);
/*********************************************/
/* Internal subroutine Sub */
/*********************************************/
Sub: proc returns (char(1));
dcl big(3000000) char(1);
big(2999999) = 'B';
return('r');
end sub;
end Cecndxp;
When any condition occurs in CECNDXP, the user condition handler
CECNDHD in the following program receives control and tests for the
out-of-storage condition. If the out-of-storage condition has occurred,
then CECNDHD calls CEEMRCR to return to the instruction in the main
program after the subroutine call that produced the out-of-storage
condition.
*Process macro;
/****************************************************/
/* */
/* Cecndhd - Call CEEMRCR to move the resume cursor */
/* relative to the handle cursor */
/* */
/* Cecndhd is a user condition handler that is */
/* registered by the program Cecndxp. Cecndhd gets */
/* control from the condition manager and tests */
/* for the STORAGE condition. If a storage */
/* condition is detected, the resume cursor is */
/* moved so that control is returned to the caller */
/* of the routine encountering the STORAGE */
/* condition. */
/* */
/****************************************************/
Cecndhd: Proc (@condtok, @token, @result, @newcond)
options(byvalue);
%include ceeibmct;
%include ceeibmaw;
/* Parameters */
dcl @condtok pointer;
dcl @token pointer;
dcl @result pointer;
dcl @newcond pointer;
dcl 1 condtok based(@condtok) feedback;
dcl token fixed bin(31) based(@token);
dcl result fixed bin(31) based(@result);
dcl 1 newcond based(@newcond) feedback;
dcl 1 fback feedback;
dcl move_type fixed bin(31);
dcl resume fixed bin(31) static initial(10);
dcl percolate fixed bin(31) static initial(20);
dcl promote fixed bin(31) static initial(30);
dcl promote_sf fixed bin(31) static initial(31);
/* Check if this is the out-of-storage token */
if fbcheck (condtok, cee0pd) then
do;
display ('Sub not run: out of storage');
/* Call CEEMRCR to move resume cursor */
move_type = 0;
call ceemrcr (move_type, fback);
If fbcheck (fback, cee000) then
do;
result = resume;
end;
else
do;
result = percolate;
end;
end;
else /* something besides out-of-storage */
do;
result = percolate;
end;
end Cecndhd;