Possible memory leak in Performer2.2 .

New Message Reply Date view Thread view Subject view Author view

Oyvind Roa (oyvind.roa++at++ks-t.no)
Thu, 14 May 1998 12:55:03 +0200


I am currently working on a project where we have
a large geospecific database which has been tiled.
The application should be able to run for at least
8 hours, where the user might contiguously fly
around in the terrain. This might lead to several
hundred tiles being loaded and removed during a
session in the DBase process.

My problem is that the application slowly consumes more
and more memory, until the shared arena goes full.
I have been able to isolate the problem down to a small
test program (attached), actually using "pftown.pfb"
to simulate my real terrain tiles. The symthoms are the
same for my real tiles and "pftown.pfb".

I expect that there is something which is not allocated
shared in the loader (using the standard .pfb loader) which
is not freed when I remove the tile, or is it due to memory
fragmentation of the arena.

Does some of you know immediately what my problem is, or
alternatively how should I proceed to find out where the
memory goes ?

Environment :

Workstation : 8 cpu Onys2 InfiniteReality, 2 pipes
OpSys : IRIX6.4
Software : ProDev7.2
              Performer2.2

Test program :
-----------------------

#include <stdlib.h>
#include <strings.h>

#include <Performer/pf.h>
#include <Performer/pfdu.h>
#include <Performer/pfutil.h>
#include <stdio.h>
#include <math.h>

/* Function prototypes */

void updateDBase(void *data);
void windowSetup(char *title);
void channelSetup(void);
void handleEvents(void);

/* Type declarations */

typedef struct {
    pfGroup *group;
} SharedData;

/* Global variables */

SharedData *shared = NULL ;
pfChannel *chan = NULL ;
pfScene *scene = NULL ;
int exitFlag = 0;

int main(int argc, char *argv[])
{

  void *arena ;
  pfLightSource *light;

  /* Set the shared arena size to approx. 100MByte
     to get an overflow earlier than with the default
     one. The program runs out of shared memory
     after approx. 90 loads */

  pfSharedArenaSize(100000000L) ;
  pfInit() ;
  pfuInitUtil() ;

  arena = pfGetSharedArena();
  shared = (SharedData *)pfMalloc(sizeof(SharedData), arena);

  /* Configure the database paging to run in an async. subprocess */
  pfMultiprocess(PFMP_APP_CULL_DRAW | PFMP_FORK_DBASE);

  pfdInitConverter("pfb") ;

  /* Forks CULL and DRAW and DBase */
  pfConfig() ;

  /* Create a X-window, and associate it with pipe 0 */
  windowSetup(argv[0]);

  /* Creat a scene */
  scene = pfNewScene() ;

  /* Add a light source to the scene */
  light = pfNewLSource();
  pfAddChild(scene, light);

  /* Hook all the tiles in under a top group node */
  shared->group = pfNewGroup();
  pfAddChild(scene, shared->group);

  /* Create an setup a channel */
  channelSetup();

  /* Register DBase callback */
  pfDBaseFunc(updateDBase);

  /* Set framerate to 30Hz */
  pfFrameRate(30.0f) ;
  pfPhase(PFPHASE_LIMIT) ;

  while( !exitFlag) {
     pfSync() ;
     pfFrame() ;
  }

  pfuExitUtil() ;
  pfExit() ;

  exit(0) ;
}

/* Max number generated by rand() (2^16 - 1) */
#define MAX_RAND 32767.0

/* Max number of tiles simultanously loaded */
#define MAX_TILES 9

/* updateDBase() is called async. by pfFrame()
in the forked DBase process. */

void updateDBase(void *data)
{
  extern SharedData *shared;

  static pfNode *Tiles[MAX_TILES] ;
  static pfBuffer *buf = NULL;
  static int nLoads = 0 ;
  static int nLoaded= 0 ;
  int num ;

  if (!buf) {
    /* Clear the Tiles array */
    bzero(Tiles, sizeof(pfNode *)*MAX_TILES) ;

    /* Create and select a new pfBuffer to work with. */
    buf = pfNewBuffer();
    pfSelectBuffer(buf);

    /* Set the PFFILEPATH */
    pfFilePath(".:./pftexture");
  }

  /* Generate a random number from 0 to MAX_TILES-1 */
  num = (int)(((float)rand() / MAX_RAND) *
             ((float)MAX_TILES - 0.00001)) ;

  /* Check if the randomly selected tile is already loaded */
  if (Tiles[num]) {

    /* Remove the scenegraph subtree representing this tile */

    pfBufferRemoveChild(shared->group, Tiles[num]);
    pfAsyncDelete(Tiles[num]);
    Tiles[num] = NULL ;
    printf("Removed tile %d\n", num) ;

    /* Decrement how many tiles currently loaded. */
    nLoaded-- ;

  } else {

    /* Load a new instance of the town, and put it into the
       scenegraph under the selected tile number. */

    Tiles[num] = pfdLoadFile("town.pfb") ;
    pfBufferAddChild(shared->group, Tiles[num]);

    printf("Loaded tile %d\n", num) ;

    /* Increment number of loads done. */
    nLoads++ ;
    /* Increment how many tiles currently loaded. */
    nLoaded++ ;
  }

  printf("Number of loads ==> %d\n", nLoads) ;
  printf("Number of tiles loaded ==> %d\n", nLoaded) ;

  /* Merge the newly loaded tile (if any) into the scene. */
  pfMergeBuffer();

  /* Carry out the asynchronous deletion requests if any pending */
  pfDBase();

}

void windowSetup(char *title)
{
  pfPipe *pipe;
  pfPipeWindow *win;

  pipe = pfGetPipe(0);
  win = pfNewPWin(pipe);
  pfPWinName(win, title);

  pfPWinSize(win, 1000, 1000);

  pfPWinType(win, PFPWIN_TYPE_X) ;
  pfuInitInput(win, PFUINPUT_X) ;

  pfOpenPWin(win);
}

void channelSetup()
{
  extern pfChannel *chan ;
  pfPipe *pipe;
  pfCoord view;

  pipe = pfGetPipe(0);
  chan = pfNewChan(pipe);
  pfChanScene(chan, scene);

  pfChanNearFar(chan, 1.0f, 5000.0f) ;
  pfChanFOV(chan, 60.0f, -1.0f) ;

  /* Position the channel where it is known to
     see part of the loaded database */
  pfSetVec3(view.hpr, 0.0f, -20.0f, 0.0f);
  pfSetVec3(view.xyz, 3000.0f, 3000.0f, 50.0f);
  pfChanView(chan, view.xyz, view.hpr) ;

}

-----------------------
  
Oyvind Roa
Senior Software Engineer

Kongsberg Defence & Aerospace A/S Phone: (+47) 32723253
P.O. Box 1003 Fax: (+47) 32286902
N-3601 Kongsberg Email: oyvind.roa++at++kongsberg.com
Norway
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
            Submissions: info-performer++at++sgi.com
        Admin. requests: info-performer-request++at++sgi.com


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:57:24 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.