From: ACUS02@waccvm.corp.mot.com (David McAnally)
Subject: Re: Bug in CMS 6 - 'XEDIT' - Insuff. memory - Awk!
Organization: Motorola
Date: 6 Nov 1992 21:26:54 MST

>------------------------- Original Article -------------------------
>From: tgtchb@tb3.chem.tue.nl (Harold C.L. Baur)
>
>Hi there,
>
>I am not sure wether this is the right place to post this to, but for
>the heck of it, here it is:
>
>I am one of 5 people maintaining a multi user dungeon adventure, which is
>written in Rexx. Lately, we noticed the game frequently crashed due to
>insufficient memory. This somehow seemed related to some routines used to
>back up and edit player stats. The way we change the datafiles is (I think)
>a common one: by QUEUEing Xedit commands, and calling the 'XEDIT' from the
>game at runtime. Now, what we THINK is that after leaving the editor, the
>memory allocated to load it (and/or the files to be edited), is not released.
>After a couple (many) of these calls to the XEDITor, the parent process (the
>game) crashes *sniff*... OK. Anybody any clue/comment/idea on this?
>
>Virtually,
>           Haribo - God of coding and editing in MUDA.
>
>

Here's one mehod of obtaining the approximate virtual memory available to
REXX.  Call it as an external function (ie. mem=MEMORY() ).  It ain't the
desired way, but if the system won't tell you....

Regards,
David McAnally
Specialist, Computer Applications

 Motorola
 MCS Applications Engineering
 MD R3148                             Internet: acus02@waccvm.corp.mot.com
 8220 East Roosevelt Road             IBM IINMAIL ID: USMOTWTT
 Scottsdale AZ 85257                  NeXT Mail:  acus02@ems13.corp.mot.com


/* REXXCOMP: SLINE NOPR */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* 11/06/92 Version 1.1 - MEMORY EXEC                                  */
/* Originally written/provided by John Yoakum.                         */
/* Modified by David McAnally - Motorola                               */
/*                                                                     */
/* REXX consumptive memory analysis for VM/CMS.                        */
/* Reports approximate available/free virtual memory                   */
/* by consuming a known "bite" of memory repetatively until storage    */
/* is exausted, resulting in a REXX error.  A SIGNAL condition catches */
/* this and goes to a subroutine where the available memory exhausted  */
/* is caculated.   This isn't meant to be real acurate, but can be     */
/* used to estimate available free memory for REXX programs.           */
/* What else can one do if VM/CMS or REXX functions don't tell you?    */
/* I use it sometimes in a REXX XEDIT macro to estimate if I have      */
/* enough free memory to load a file and perform other processes.      */
/*                                                                     */
/* I recommend compiling with IBM REXX Compiler to save system         */
/* resources and time.  This isn't the cheapest method of getting      */
/* this information.                                                   */
/*                                                                     */
/* Results can be returned as a function, in the stack or on the       */
/* screen.                                                             */
/*                                                                     */
/* Command:                                                            */
/*                                                                     */
/* MEMORY fork appetite ( options                                      */
/*                                                                     */
/* where:                                                              */
/*                                                                     */
/*   fork = kbytes to eat per iteration.Defaults to 10 (10K)           */
/*   appetite = iterations to eat memory. Defaults to GLUTTON or all.  */
/*   options = STACK                                                   */
/*                                                                     */
/* Examples:                                                           */
/*                                                                     */
/*   EXEC MEMORY                                                       */
/*                                                                     */
/*   (in a REXX exec)                                                  */
/*                                                                     */
/*   avail_memory = memory()                                           */
/*                                                                     */
/* Additional Notes:                                                   */
/*                                                                     */
/*   We have seen memory exahustion on WAKEUP servers and other        */
/*   applications that run for an extended period of time (days).      */
/*   It is a good idea to LOGOFF/LOGON or IPL these server apps        */
/*   periodically to avoid virtual memory problems like this.          */
/*                                                                     */
/*   Things that can free up virtual memory include HX, EXECDROP and   */
/*   NUCXDROP.                                                         */
/*                                                                     */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  Parse Source . calltype .
  rc = 0
  i = 0
  x = 0
  knife = 1024                       /* default Kbyte size             */
  spoon = 10                         /* default Morsel size            */
/* lets get started                                                    */
  parse upper arg fork appetite . '(' option .
  if datatype(fork,w) ^= 1
    then
    fork = spoon
  if datatype(appetite,w) ^= 1
    then
    do
      appetite = 'GLUTTON'
      aunit = ''
    end
  else
    aunit = 'K'
/* set error traps for when memory is exhausted                        */
  SIGNAL ON FAILURE NAME FAILURE
  SIGNAL ON ERROR NAME ERROR
  SIGNAL ON HALT  NAME HALT
  SIGNAL ON SYNTAX NAME SYNTAX
/* consume memory                                                      */
  bite = fork*knife
  food = copies('*',bite)
  if datatype(appetite,w) = 1
    then
    do i = 1 to appetite
      eat.i = copies('*',bite)
    end i
  else
    do i = 1 to 999999
      eat.i = copies('*',bite)
    end i
  select
    when option = 'STACK'
      then
      push fork*i 'K Free Storage available.'
    when calltype='FUNCTION' Then nop
    otherwise
      do
        say ' '
        say 'Requested' appetite||aunit 'Free Storage available.'
        say ' '
      end
  end
  exit rc
/* diagnose errors                                                     */
ERROR:
  nop
HALT:
  nop
FAILURE:
  nop
SYNTAX:
  drop eat.
  if rc = 5
    then
    do
      select
        when calltype='FUNCTION' Then return fork*i
        when option = 'STACK'
          then
          push fork*i 'K Free Storage available.'
        otherwise
          do
            say ' '
            say fork*i||'K Free Storage available.'
            say ' '
          end
      end
      exit 0
    end
  else
    do
      say 'REXX error' rc 'in line' sigl ':' errortext(rc)
      exit rc
    end
  return
Newsgroups: comp.lang.rexx