PL/I example of storage management

Following is an example of how to manage storage for an Enterprise PL/I for z/OS or a PL/I for MVS & VM program using callable services.
*PROCESS MACRO;
 CE90STO: PROC OPTIONS(MAIN);

    %INCLUDE  CEEIBMAW;
    %INCLUDE  CEEIBMCT;
 /*******************************************************/
 /*Module/File Name: IBMSTOR                            */
 /*******************************************************/
 /* FUNCTION : CEE3RPH - set report heading             */
 /*          : CEECRHP - create user heap               */
 /*          : CEEGTST - obtain storage from user heap  */
 /*          : CEEZCST - change size of storage block   */
 /*          : CEEFRST - free this piece of storage     */
 /*          : CEEDSHP - discard user heap              */
 /*  This example illustrates the use of the Language   */
 /*  Environment storage callable services in a PL/I    */
 /*  program.                                           */
 /*                                                     */
 /*  1.  A report heading is set for display at the     */
 /*      beginning of the storage or options report.    */
 /*  2.  A user heap is created.                        */
 /*  3.  Storage is allocated from the user heap.       */
 /*  4.  The size of allocated storage is changed.      */
 /*  5.  The allocated storage is freed.                */
 /*  6.  The user heap is discarded.                    */
 /*                                                     */
 /*******************************************************/

    DCL NULL    BUILTIN;
    DCL ADDRESS PTR  INIT(NULL); /* ADDRESS OF STORAGE    */
    DCL NEWSIZE REAL FIXED BINARY(31,0)
                     INIT(2000); /* NEW STORAGE SIZE      */
    DCL RPTHEAD CHAR(80)
                     INIT('USER DEFINED REPORT HEADING');
    DCL HEAPID  REAL FIXED BINARY(31,0)
                     INIT(0);    /* HEAP ID FOR CEECRHP   */
    DCL HPSIZE  REAL FIXED BINARY(31,0)
                     INIT(1);    /* HEAP SIZE FOR CEECRHP */
    DCL INCR    REAL FIXED BINARY(31,0)
                     INIT(0);    /* HEAP INCREMENT        */
    DCL NBYTES  REAL FIXED BINARY(31,0)
                     INIT(4000); /* SIZE OF REQUIRED HEAP */
    DCL 01 FC,                      /* Feedback token */
           03 MsgSev    REAL FIXED BINARY(15,0),
           03 MsgNo     REAL FIXED BINARY(15,0),
           03 Flags,
              05 Case      BIT(2),
              05 Severity  BIT(3),
              05 Control   BIT(3),
           03 FacID     CHAR(3),    /* Facility ID */
           03 ISI                   /* Instance-Specific Information */
                        REAL FIXED BINARY(31,0);
    
    DCL OPTS    REAL FIXED BINARY(31,0)
                     INIT(0);    /* HEAP OPTIONS          */
    PUT SKIP LIST('PL/I Storage example is now in motion');
    
    /****************************************************/
    /* Call CEE3RPH to set user defined report heading  */
    /****************************************************/
    CALL CEE3RPH ( RPTHEAD, FC );
    IF  ^ FBCHECK( FC, CEE000)  THEN  DO;
       PUT SKIP LIST ( 'Error ' || FC.MsgNo
          || ' in setting Report Heading');
       STOP;
       END;
    /****************************************************/
    /* Call CEECRHP to create user heap                 */
    /****************************************************/
    CALL CEECRHP ( HEAPID, HPSIZE, INCR, OPTS, FC );
    IF  FBCHECK( FC, CEE000)  THEN  DO;
       /*************************************************/
       /* Call CEEGTST to get storage from user heap    */
       /*************************************************/
       CALL CEEGTST ( HEAPID, NBYTES, ADDRESS, FC );
       IF  FBCHECK( FC, CEE000)  THEN  DO;
          /**********************************************/
          /* Call CEECZST to change the size of block   */
          /**********************************************/
          CALL CEECZST ( ADDRESS, NEWSIZE, FC );
          IF  FBCHECK( FC, CEE000)  THEN  DO;
             CALL FREE_ALL;
             PUT SKIP LIST ( 'PL/I Storage Example program ended');
             END;
          ELSE  DO;
             PUT SKIP LIST('Error ' || FC.MsgNo
                || ' in changing size of storage');
             STOP;
             END;
          END;
       ELSE  DO;
          PUT SKIP LIST( 'Error ' || FC.MsgNo
             || ' in getting user storage' );
          STOP;
          END;
       END;
    ELSE  DO;
       PUT SKIP LIST ('Error' || FC.MsgNo
          || ' in creating user heap');
       STOP;
       END;

    /* Logical end of Main program CE90STO */
 FREE_ALL:  PROC;

    /****************************************************/
    /* Call CEEFRST to free this piece of storage       */
    /****************************************************/
    CALL CEEFRST ( ADDRESS, FC );
    IF  FBCHECK( FC, CEE000)  THEN  DO;
       /*************************************************/
       /*   Call CEEDSHP to discard user heap           */
       /*************************************************/
       CALL CEEDSHP ( HEAPID, FC );
       IF  ^ FBCHECK( FC, CEE000)  THEN  DO;
          PUT SKIP LIST ( 'Error ' || FC.MsgNo
             || ' discarding user heap');
          STOP;
          END;
       END;
    ELSE  DO;
       PUT SKIP LIST ( 'Error ' || FC.MsgNo
          || ' freeing storage from heap');
       STOP;
       END;

 END FREE_ALL;

 END CE90STO;