*DECK FREEMEM 
USETEXT COMCBEG 
USETEXT COMRMEM 
USETEXT COMRQUE 
PROC FREEMEM; 
# TITLE  FREEMEM - FREE UP UNUSED MEMORY. # 
  
      BEGIN  # FREEMEM #
  
# 
**    FREEMEM - FREE UP UNUSED MEMORY.
* 
*     THIS PROCEDURE SCANS THROUGH THE UNUSED RHF QUEUE ENTRIES 
*     TO DETERMINE IF THERE IS FIELD LENGTH THAT CAN BE 
*     RELEASED.  IF ALL MEMORY IS UNUSED, SET THE GOIDLE FLAG TO
*     INDICATE THERE ARE NO ACTIVE CONNECTIONS AND TO ALLOW RHF 
*     TO GO INTO THE IDLE STATE.
* 
*     PROC FREEMEM. 
* 
*     ENTRY   - (INITIALFL) - FWA OF QUEUE ENTRIES. 
*               (FIELDLEN) - LWA OF QUEUE ENTRIES.
* 
*     EXIT    - GOIDLE TRUE, IF ALL MEMORY UNUSED.
* 
*     PROCESS - WHILE NOT END OF QUEUE ENTRIES
*                     AND QUEUE ENTRY IS EMPTY
*               DO
*                 INCREMENT FL TO DECREASE. 
*               ROUND DOWN FL TO DECREASE TO A MULTIPLE OF 100B.
*               IF THERE IS MEMORY TO RELEASE 
*                OR ALL MEMORY UNUSED 
*               THEN
*                 FOR EACH QUEUE ENTRY ON FREEQ 
*                 DO
*                   IF ENTRY IS WITHIN NEW FL 
*                   THEN
*                     INCREMENT ENTRIES REQUEUED COUNT. 
*                     PLACE ENTRY BACK ON FREEQ.
*                   ELSE
*                     INCREMENT ENTRIES RELEASED COUNT. 
*                 IF ALL QUEUE ENTRIES RELEASED 
*                 THEN
*                   CALL MEM TO RELEASE EXCESS FL.
*               IF ALL QUEUE ENTRIES ON FREEQ CHAIN 
*               THEN
*                 SET GOIDLE TRUE.
# 
  
# 
****  PROC FREEMEM - XREF LIST BEGIN. 
# 
  
      XREF
        BEGIN 
        PROC CALLSYS;                # MAKE RA + 1 REQUESTS # 
        PROC DEQUEUE;                # DELINK ENTRY FROM QUEUE #
        PROC QUEUE;                  # PLACE ENTRY ON QUEUE # 
        END 
  
# 
****  PROC FREEMEM - XREF LIST END. 
# 
  
  
      ITEM TEMPQ      I;             # TEMPORARY FREEQ POINTER #
      ITEM FLTOREL    I;             # FIELD LENGTH TO RELEASE #
      ITEM ENTREL     I;             # NUMBER OF ENTRIES RELEASED # 
      ITEM ALLEMPTY   B;             # ALL QUEUE ENTRIES EMPTY FLAG # 
      ITEM ENTRQUED   I;             # NUMBER OF ENTRIES REQUEUED # 
      ITEM TTLQEN     I;             # TOTAL NUMBER OF ENTRIES IN FL #
  
      ARRAY MEMCALL [0:0] S(1); 
        BEGIN 
        ITEM MEMNAME    C(00,00,03) = ["MEM"];
        ITEM MEMRCL     B(00,19,01) = [TRUE]; 
        ITEM MEMADDR    I(00,42,18);
        END 
  
      ARRAY MEMPARM [0:0] S(1); 
        BEGIN 
        ITEM MEMWD      I(00,00,60) = [0];
        ITEM MEMWORDS   I(00,00,30); # FIELD LENGTH REQUESTED # 
        ITEM MEMCOMPL   B(00,59,01); # MEM COMPLETE # 
        END 
  
      CONTROL EJECT;
  
      P<QU$ADDRESS> = FIELDLEN - QU$LENGTH - 4; 
  
      TTLQEN = (FIELDLEN - INITIALFL) / QU$LENGTH;
  
      ENTRQUED = 0; 
      ENTREL = 0; 
      FLTOREL = 0;
  
      ASLONGAS P<QU$ADDRESS> GE (INITIALFL - 4) 
           AND QU$TYPE EQ QT$EMPTY
      DO
        BEGIN 
        FLTOREL = FLTOREL + QU$LENGTH;
        P<QU$ADDRESS> = P<QU$ADDRESS> - QU$LENGTH;
        END 
  
      IF FLTOREL EQ (FIELDLEN - INITIALFL)
      THEN
        BEGIN 
        ALLEMPTY = TRUE;
        END 
  
      ELSE
        BEGIN 
        ALLEMPTY = FALSE; 
        END 
  
# 
*     NOTE - WHEN RELEASING N WORDS OF MEMORY (WHERE N IS A MULTIPLE
*     OF 100B), THERE MUST BE (N / 10B) CONSECUTIVE FREE QUEUE
*     ENTRIES, STARTING WITH (CURRENT FL - 10B). (SEE ROUTINE GETFREE)
# 
  
      FLTOREL = (FLTOREL - O"10")/O"100" * O"100";
  
      IF FLTOREL NE 0 
        OR ALLEMPTY 
      THEN
        BEGIN 
        TEMPQ = FREEQ;
        FREEQ = 0;
        ASLONGAS TEMPQ NE 0 DO
          BEGIN 
          DEQUEUE(LOC(TEMPQ));
          IF P<QU$ADDRESS> LT (FIELDLEN + 4 - FLTOREL - QU$LENGTH)
          THEN
            BEGIN 
            ENTRQUED = ENTRQUED + 1;
            QUEUE(LOC(FREEQ));
            END 
  
          ELSE
            BEGIN 
            ENTREL = ENTREL + 1;
            END 
  
          END 
  
        IF ENTREL EQ (FLTOREL/O"10")
          AND FLTOREL NE 0
        THEN
          BEGIN 
          MEMCOMPL = FALSE; 
          MEMWORDS = FIELDLEN + 4 - FLTOREL;
          MEMADDR = LOC(MEMPARM); 
          CALLSYS(MEMCALL); 
  
# 
*         NOTE - THAT (FIELDLEN + 4 - FLTOREL) WILL BE A MULTIPLE OF
*         100B (SEE ROUTINE GETFREE).  MEMWORDS IS ROUNDED UP HERE AS 
*         A SAFETY PRECAUTION FOR FUTURE CONSIDERATIONS.
# 
  
          MEMWORDS = (MEMWORDS + O"77") / O"100" * O"100";
  
          FIELDLEN = MEMWORDS - 4;
          END 
  
        END 
  
      IF TTLQEN EQ (ENTREL + ENTRQUED)
      THEN
        BEGIN 
        GOIDLE = TRUE;
        END 
  
      END  # FREEMEM #
  
      TERM
