Re: pfBuffer::merge follow up

New Message Reply Date view Thread view Subject view Author view

Nicolas Gauvin (nicolas++at++cae.ca)
Tue, 13 Feb 1996 14:14:17 -0500


After reading all the problems that people seems to be having
with pfBuffers I started doing some investigations on my side. I added
a very simple paging system to simple.C. After trying things around, here
are my findings:

First pfBuffer::merge() seems to be very fragile. As reported
earlier, parents need to be created before their children otherwise
we end up with the infamous 'nb_clean' crash. This single constraint
can cause limitations in the design of an efficient paging system and
I wouldn't be surprised that some of the loaders that are shipped
with Performer 2.0 do not respect it.

However even when I created simple Performer nodes myself
in the correct order I still ended up with 'nb_clean' crashes much
like those reported by Scott Friedman.

I investigated a bit further and I have found that pfBuffer::merge()
will undoubtly crash if I have requested more than one bufferAddChild
before calling it. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The only workaround I have found for this is to call pfBuffer::merge()
after each and every bufferAddChild requests instead of using a single call
once all children have been created and added with various bufferAddChild.

Attached to this message is a version of simple.C that illustrates
the problem and workaround. The original simple.C with its Makefile is
found in /usr/share/Performer/src/pguide/libpf/C++

This workaround however has a cost associated to it as reported in
the pfBuffer man pages:

  " pfBuffer::merge will adversely impact the APP process, "
  " proportional to the number of pfBuffer::addChild and "
  " pfBuffer::removeChild requests. "

In a realistic database paging system many tiles may need to be
suddenly paged in. If I have to call pfBuffer::merge for each of
them, performance of the APP process will degrade.

In my opinion these bugs are important enough to justify a fix.
Especially if we consider that previous beta versions of Performer
seemed to have a better working pfBuffer::merge.

I would be interested to know if there is a plan in that regard.

I know that distributing patches for a big product like Performer must
be a major pain especially with all those versions of the libraries but if
it's not done then we are stuck with a database paging system barely usable.

So far I have been really impressed and satisfied with the quality of
the Performer 2.0 release. However the bugs related to pfBuffer are
the first ones I have found that can really cause me problems.

-- 
     ___/     |       ___/ Nicolas Gauvin	   e-mail: nicolas++at++cae.ca
    /       / |      /     Software Developper	   voice: (514) 341-2000 x2275
   /       /  |     __/    CAE Electronics Ltd.    fax:   (514) 340-5496
  /       ___ |    /	   8585 Cote De Liesse, P.O. Box 1800
_____/  _/   _| _____/     Saint-Laurent, Quebec, Canada, H4L-4X4

// // Copyright 1995, Silicon Graphics, Inc. // ALL RIGHTS RESERVED // // UNPUBLISHED -- Rights reserved under the copyright laws of the United // States. Use of a copyright notice is precautionary only and does not // imply publication or disclosure. // // U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: // Use, duplication or disclosure by the Government is subject to restrictions // as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights // in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or // in similar or successor clauses in the FAR, or the DOD or NASA FAR // Supplement. Contractor/manufacturer is Silicon Graphics, Inc., // 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. // // Permission to use, copy, modify, distribute, and sell this software // and its documentation for any purpose is hereby granted without // fee, provided that (i) the above copyright notices and this // permission notice appear in all copies of the software and related // documentation, and (ii) the name of Silicon Graphics may not be // used in any advertising or publicity relating to the software // without the specific, prior written permission of Silicon Graphics. // // THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, // EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY // WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. // // IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, // INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, // WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY // THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE // OR PERFORMANCE OF THIS SOFTWARE. // // // simpleC.C: simple Performer program for programmer's guide // // $Revision: 1.10 $ // $Date: 1995/11/22 14:35:21 $ //

#include <stdlib.h>

#include <Performer/pf/pfChannel.h> #include <Performer/pf/pfLightSource.h> #include <Performer/pf/pfNode.h> #include <Performer/pf/pfScene.h>

#include <Performer/pfutil.h> #include <Performer/pfdu.h>

#include <Performer/pf.h> #include <Performer/pf/pfBuffer.h> #include <Performer/pf/pfDCS.h> #include <Performer/pf/pfGeode.h> #include <Performer/pr/pfGeoSet.h>

// DBase passdata stucture containing only the Performer scene struct DBaseData { pfScene* scene; };

// // Usage() -- print usage advice and exit. This // procedure is executed in the application process. // static void Usage (void) { pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage: simpleC file.ext ...\n"); exit(1); }

// Very simple DBase callback that alternatively // pages in and out two simple Performer branches // and illustrates the pfBuffer::merge problem // as well as a workaround. void DBaseFunc( void* _data ) { DBaseData* data = (DBaseData*) _data; static pfBuffer *buffer = NULL; static int loaded = FALSE; static pfDCS* dcs1; static pfDCS* dcs2; printf("DBaseFunc called:\n"); if ( buffer == NULL ) { buffer = new pfBuffer; buffer->select(); } if ( loaded == FALSE ) { // create a typical dcs with geode and geoset // parents must be created before their children dcs1 = new pfDCS; data->scene->bufferAddChild(dcs1); pfGeode* geode1 = new pfGeode; dcs1->addChild(geode1); pfGeoSet* geoset1 = new(pfGetSharedArena()) pfGeoSet; geode1->addGSet(geoset1); // The work around I have found to the dying DBASE process // is to call pfBuffer::merge for each and every bufferAddChild. // This is has a COST as reported in the pfBuffer man pages: // " pfBuffer::merge will adversely impact the APP process, " // " proportional to the number of pfBuffer::addChild and " // " pfBuffer::removeChild requests. " // BUG WORKAROUND: call merge for first bufferAddChild pfBuffer::merge(); // create a second dcs with geode and geoset dcs2 = new pfDCS; data->scene->bufferAddChild(dcs2); pfGeode* geode2 = new pfGeode; dcs2->addChild(geode2); pfGeoSet* geoset2 = new(pfGetSharedArena()) pfGeoSet; geode2->addGSet(geoset2); // BUG WORKAROUND: call merge again for second bufferAddChild() pfBuffer::merge(); loaded = TRUE; printf(" Tiles paged IN\n\n"); } else { data->scene->bufferRemoveChild(dcs1); pfAsyncDelete(dcs1); data->scene->bufferRemoveChild(dcs2); pfAsyncDelete(dcs2); // when doing only 'bufferRemoveChild' // a single pfBuffer::merge() at the end seems to be enough. // bufferRemoveChild don't seem to cause the // same problem as bufferAddChild() on pfBuffer::merge(); pfBuffer::merge();

loaded = FALSE; printf(" Tiles paged OUT\n\n"); } pfDBase(); }

int main (int argc, char *argv[]) { float t = 0.0f; if (argc < 2) Usage(); // Initialize Performer pfInit(); // Set up a separate DBASE process pfMultiprocess( PFMP_FORK_DBASE ); // Load all loader DSO's before pfConfig() forks pfdInitConverter(argv[1]);

// initiate multi-processing mode set in pfMultiprocess call // FORKs for Performer processes, CULL and DRAW, etc. happen here. // pfConfig(); // Append to Performer search path, PFPATH, files in // /usr/share/Performer/data */ pfFilePath(".:/usr/share/Performer/data"); pfNode *root = pfdLoadFile(argv[1]); if (root == NULL) { pfExit(); exit(-1); } // Attach loaded file to a new pfScene pfScene* scene = new pfScene; scene->addChild(root); // Create a pfLightSource and attach it to scene scene->addChild(new pfLightSource); // Configure and open GL window pfPipe *p = pfGetPipe(0); pfPipeWindow *pw = new pfPipeWindow(p); pw->setWinType(PFPWIN_TYPE_X); pw->setName("IRIS Performer"); pw->setOriginSize(0,0,500,500); pw->open(); // Create and configure a pfChannel. pfChannel *chan = new pfChannel(p); chan->setScene(scene); chan->setFOV(45.0f, 0.0f); // determine extent of scene's geometry pfSphere bsphere; root->getBound(&bsphere); chan->setNearFar(1.0f, 10.0f * bsphere.radius); // set up DBASE callback and passdata pfDBaseFunc( DBaseFunc ); DBaseData* data = (DBaseData*) pfAllocDBaseData( sizeof(DBaseData) ); data->scene = scene; // Simulate for twenty seconds. while (t < 20.0f) { pfCoord view; float s, c; // Go to sleep until next frame time. pfSync(); // pass data to DBASE callback pfPassDBaseData(); // Initiate cull/draw for this frame. pfFrame(); // Compute new view position. t = pfGetTime(); pfSinCos(45.0f*t, &s, &c); view.hpr.set(45.0f*t, -10.0f, 0); view.xyz.set(2.0f * bsphere.radius * s, -2.0f * bsphere.radius *c, 0.5f * bsphere.radius); chan->setView(view.xyz, view.hpr); } // Terminate parallel processes and exit pfExit(); return 0; }


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:52:24 PDT

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