[BACK]Return to mpstats.c CVS log [TXT][DIR] Up to [Development] / performer / src / lib / libpfutil

File: [Development] / performer / src / lib / libpfutil / mpstats.c (download)

Revision 1.1, Tue Nov 21 21:39:36 2000 UTC (16 years, 10 months ago) by flynnt
Branch: MAIN
CVS Tags: HEAD

Initial check-in based on OpenGL Performer 2.4 tree.
-flynnt

/*
 * Copyright 1993, 1994, 1995, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 *
 * This source code ("Source Code") was originally derived from a
 * code base owned by Silicon Graphics, Inc. ("SGI")
 * 
 * LICENSE: SGI grants the user ("Licensee") permission to reproduce,
 * distribute, and create derivative works from this Source Code,
 * provided that: (1) the user reproduces this entire notice within
 * both source and binary format redistributions and any accompanying
 * materials such as documentation in printed or electronic format;
 * (2) the Source Code is not to be used, or ported or modified for
 * use, except in conjunction with OpenGL Performer; and (3) the
 * names of Silicon Graphics, Inc.  and SGI may not be used in any
 * advertising or publicity relating to the Source Code without the
 * prior written permission of SGI.  No further license or permission
 * may be inferred or deemed or construed to exist with regard to the
 * Source Code or the code base of which it forms a part. All rights
 * not expressly granted are reserved.
 * 
 * This Source Code is provided to Licensee AS IS, without any
 * warranty of any kind, either express, implied, or statutory,
 * including, but not limited to, any warranty that the Source Code
 * will conform to specifications, any implied warranties of
 * merchantability, fitness for a particular purpose, and freedom
 * from infringement, and any warranty that the documentation will
 * conform to the program, or any warranty that the Source Code will
 * be error free.
 * 
 * IN NO EVENT WILL SGI BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT
 * LIMITED TO DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES,
 * ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THE
 * SOURCE CODE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT OR
 * OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM,
 * OR AROSE OUT OF USE OR RESULTS FROM USE OF, OR LACK OF ABILITY TO
 * USE, THE SOURCE CODE.
 * 
 * Contact information:  Silicon Graphics, Inc., 
 * 1600 Amphitheatre Pkwy, Mountain View, CA  94043, 
 * or:  http://www.sgi.com
 */

/*
 * mpstats.c - MultiPipe Stats
 *
 * $Revision: 1.1 $
 * $Date: 2000/11/21 21:39:36 $
 *
 */

#include <Performer/pf.h> /* IRIS Performer includes */
#include <Performer/pfutil.h> 
#include "stdio.h"

#include "mpstats.h"   /* MPipeStats include         */

/* multiprocess shared data structure */
typedef struct
{
    pfuMPSControl    	    mpsControl;       /* mps control data		 */
    pfuMPSConfiguration     mpsConfig;        /* pipes/channels config	 */
    pfuMPSFrameStamp	   *mpsFrameStamps;  /* user memory stats  buffer */
    int 		    nFrames;
    int			    nSampledPipes;	           /* user input */
} SharedMPipeStats;

SharedMPipeStats *MPS;

/* toolkit definitions */

int
pfuManageMPipeStats(int nFrames, int nSampledPipes)
{
    static int firstMPipeStats=0;
    static int testNum = 0;
    char fname [32] ;
    void *arena;
    
    if(!firstMPipeStats){
	firstMPipeStats = 1;
	
	arena = pfGetSharedArena();
	MPS = pfMalloc(sizeof(SharedMPipeStats), arena);	
	
	/* user data */
	MPS->nFrames = nFrames;
	MPS->nSampledPipes = nSampledPipes;
	MPS->mpsControl.endMPipeStats = 0;
	
	/* internal MPS data buffers */
	pfuCreateMPipeStatsBuffers();
	pfuInitMPipeStats();
	
	pfuRewindMPipeFrameStamps();
    }
    
    if(MPS->mpsControl.frCounter >= MPS->mpsControl.nFrames)
    {
        sprintf (fname, "MPipeStats%d.log", testNum++);
	pfuDumpMPipeStats(fname);
	
	/* reset the stats trace */
        pfuResetMPipeStats() ;
        pfuRewindMPipeFrameStamps() ;
	MPS->mpsControl.endMPipeStats = 0;
        firstMPipeStats = 0;
	
	return(0);  /* give the finish code to the requester */
    }
    else 
	pfuGetMPipeFrameStamp();
    
    return(1);
}

int
pfuCreateMPipeStatsBuffers(void)
{
    int i;
    void *arena;
    
    arena = pfGetSharedArena();
    
    /* getting the pipes/channels configuration */
    pfuGetMPipeStatsConfig();
    
    /* allocating frame stamp pointers array, connecting it */
    MPS->mpsFrameStamps = (pfuMPSFrameStamp *)
	pfMalloc(MPS->mpsControl.nFrames * sizeof(pfuMPSFrameStamp),
		 arena);
    
    /* allocating the data stamps, connecting them */
    /* they are intelazed in order to get cache locality */
    for(i=0; i<MPS->mpsControl.nFrames; i++)
    {
	MPS->mpsFrameStamps[i].channels = (pfuMPSChannelStamp *)
	    pfMalloc(MPS->mpsConfig.nChannels * sizeof(pfuMPSChannelStamp),
		     arena);	    	
    }

    return 0;
}


/* internal utility function */

void 
pfuGetMPipeStatsConfig(void)
{
    int i, j, prevpipes;
    void *arena;
    
    arena = pfGetSharedArena();
    
    /* initialize it in function of the user needs */
    MPS->mpsControl.nFrames = MPS->nFrames;  
    MPS->mpsControl.nPipes = MPS->nSampledPipes;
    
    /* getting the channel distribution of the requested pipes */
    for (i=0; i<MPS->mpsControl.nPipes; i++)
	MPS->mpsConfig.nChansPipe[i] = pfGetPipeNumChans(pfGetPipe(i));
    
    /* calculating the total number of channels */
    MPS->mpsConfig.nChannels = 0;
    for (i=0; i<MPS->mpsControl.nPipes; i++)
	MPS->mpsConfig.nChannels += MPS->mpsConfig.nChansPipe[i];
    /* allocating for pointers list of pfChannel and pfFrameStats ptrs */
    MPS->mpsConfig.channels = (pfChannel **) 
	pfMalloc(MPS->mpsConfig.nChannels * sizeof(pfChannel *),
		 arena); 
    MPS->mpsConfig.fstats = (pfFrameStats **)
	pfMalloc(MPS->mpsConfig.nChannels * sizeof(pfFrameStats *),
		 arena);
    
    
    /* Getting the pointers to channels and fstats */
    prevpipes = 0;
    for (i=0; i<MPS->mpsControl.nPipes; i++)
    {
	for (j=0; j<MPS->mpsConfig.nChansPipe[i]; j++)
	{
	    MPS->mpsConfig.channels[j + prevpipes] = 
		(pfChannel *) (pfGetPipeChan(pfGetPipe(i), j));
	    MPS->mpsConfig.fstats[j + prevpipes] =
		pfGetChanFStats(MPS->mpsConfig.channels[j + prevpipes]);
	}
	prevpipes += MPS->mpsConfig.nChansPipe[i]; /* i suppose whole use */
    }
}


int 
pfuDestroyMPipeStatsBuffers(void)
{
    int i;
    
    /* deallocating channel data stamps */
    for(i=0; i<MPS->mpsControl.nFrames; i++) 
	pfFree(MPS->mpsFrameStamps[i].channels);
    
    /* deallocating frame stamp pointers array */
    pfFree(MPS->mpsFrameStamps); 
    
    /* also dealloc the MPSControl structures */
    pfFree(MPS->mpsConfig.channels);
    pfFree(MPS->mpsConfig.fstats);
    
    /* final dealloc */
    pfFree(MPS);

    return 0;
}



void
pfuInitMPipeStats(void)
{
    int i;
    
    for (i=0; i<MPS->mpsConfig.nChannels; i++)
    {
	/* be sure that we all stats are disabled*/
	pfFStatsClass(MPS->mpsConfig.fstats[i],
		      PFSTATS_ALL, PFSTATS_OFF);
	
	/* enable the PFTIMES stats */
	pfFStatsClass(MPS->mpsConfig.fstats[i],
		      PFFSTATS_ENPFTIMES, PFSTATS_SET);
	
	/* enable the HIST mode */
	pfFStatsClassMode(MPS->mpsConfig.fstats[i],
			  PFFSTATS_PFTIMES,
			  PFFSTATS_PFTIMES_HIST, PFSTATS_SET);
	
	/* statistics accumulation and averaging is disabled */
	pfFStatsAttr(MPS->mpsConfig.fstats[i], PFFSTATS_UPDATE_FRAMES, 0.0f);
    }        
}



void 
pfuResetMPipeStats(void)
{
    int i;
    
    for (i=0; i<MPS->mpsConfig.nChannels; i++)
    {
	/* be sure that we all stats are disabled*/
	pfFStatsClass(MPS->mpsConfig.fstats[i], PFSTATS_ALL, PFSTATS_OFF);
    }
}



pfFStatsValPFTimesApp dts_app;
pfFStatsValPFTimesIsect dts_isect;
pfFStatsValPFTimesCull dts_cull;
pfFStatsValPFTimesDraw dts_draw;

int 
pfuGetMPipeFrameStamp(void)
{
    int i;
    
    /* read app and isect frame data*/
    pfMQueryFStats(MPS->mpsConfig.fstats[0],
		   AppQuery,
		   MPS->mpsFrameStamps[MPS->mpsControl.frCounter].app,
		   0);  /* it could be the size in a future release */
    pfMQueryFStats(MPS->mpsConfig.fstats[0],
		   IsectQuery,
		   MPS->mpsFrameStamps[MPS->mpsControl.frCounter].isect,
		   0); /* it could be the size in a future release */
    
    /* read cull and draw frame data per channel*/
    for(i=0; i<MPS->mpsConfig.nChannels; i++)
    {
	pfMQueryFStats(MPS->mpsConfig.fstats[i],
		       ChanCullQuery,
		       MPS->mpsFrameStamps[MPS->mpsControl.frCounter].channels[i].cull,
		       0); /* it could be the size in a future release */
	pfMQueryFStats(MPS->mpsConfig.fstats[i],
		       ChanDrawQuery,
		       MPS->mpsFrameStamps[MPS->mpsControl.frCounter].channels[i].draw,
		       0); /* it could be the size in a future release */
    }
    
    /* control status */
    MPS->mpsControl.frCounter++;
    if (MPS->mpsControl.frCounter > MPS->mpsControl.nFrames)
    {
	MPS->mpsControl.endMPipeStats = 1;
	return(0);
    }
    return(1); 
}



void
pfuRewindMPipeFrameStamps(void)
{
    MPS->mpsControl.frCounter = 0;    
}


/* AWAITING SHARON pfDrawStats_NEW */

/*ARGSUSED*/
void 
pfuDrawMPipeStats(int drawchannel)
{
    /* passing the stats channel, n_channels and fstat pointer list */
    
    /* pfDrawStats_NEW(MPS->mpsConfig.channels[drawchannel] ,
       MPS->mpsConfig.fstats,
       MPS->mpsConfig.nChannels);*/
    
}

void 
pfuDumpMPipeStats(const char *filename)
{
    int i, j;
    int ii[10];
    double dd[10], ddd[16];
    
    FILE *fid;
    
    fid = fopen(filename, "w");
    if (!fid) fprintf(stderr, "Failure on opening MPipeStats dump file\n");
    
    /* creating the dump file header for mpscope */
    
    ii[0] = MPS->mpsControl.nFrames;
    ii[1] = MPS->mpsControl.nPipes;
    ii[2] = MPS->mpsConfig.nChannels;
    ii[3] = MPS->mpsConfig.nChansPipe[0];
    ii[4] = MPS->mpsConfig.nChansPipe[1];
    ii[5] = MPS->mpsConfig.nChansPipe[2];
    fprintf(fid, headerFormat, ii[0], ii[1], ii[2], ii[3], ii[4], ii[5]);
    
    /* creating the time stamps */
    
    for (i=0; i<MPS->mpsControl.nFrames; i++)
    {	
	ii[0] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].frame;		
	dd[0] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].start;		
	dd[1] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].enterSync;	
	dd[2] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].afterClean;	
	dd[3] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].afterSync;	
	dd[4] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].pfFrameStart;	
	dd[5] = MPS->mpsFrameStamps[i].app[PREV_MPSFRAME].pfFrameEnd;	
	
	ii[1] = MPS->mpsFrameStamps[i].isect[PREV_MPSFRAME].frame;
	dd[6] = MPS->mpsFrameStamps[i].isect[PREV_MPSFRAME].start;
	dd[7] = MPS->mpsFrameStamps[i].isect[PREV_MPSFRAME].end;
	
	ddd[0] = (MPS->mpsFrameStamps[i].isect[PREV_MPSFRAME].end -
		  MPS->mpsFrameStamps[i].isect[PREV_MPSFRAME].start) * 1000.0f;
	
	/* saving in file */ 
	fprintf( fid, appCounterFormat, frameString, i);
	fprintf( fid, appFormat,  appString, absoluteString, ii[0], dd[0], dd[1], dd[2], dd[3], dd[4], dd[5]);
	fprintf( fid, isectFormat, isectString, absoluteString, ii[1], dd[6], dd[7], relativeString, ddd[0]); 
	
	for (j=0; j<MPS->mpsConfig.nChannels; j++)
	{
	    ii[0] = MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].frame;	
	    dd[0] = MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].beginUpdate;
	    dd[1] = MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].endUpdate;
	    dd[2] = MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].start;
	    dd[3] = MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].end;
	    
            ddd[0] = (MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].end - 
		      MPS->mpsFrameStamps[i].channels[j].cull[PREV_MPSFRAME].start) * 1000.0f;
	    
	    ii[1] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].frame;
	    dd[4] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].start;
	    dd[5] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].end;
	    dd[6] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawStart;
	    dd[7] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawEnd;
	    dd[8] = MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].afterSwap;
	    dd[9] = (MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawEnd - 
		     MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawStart);
	    
            ddd[1] = (MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].end - 
		      MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].start) * 1000.0f;
	    /* predraw channel callback */
	    ddd[2] = (MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawStart - 
		      MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].start) * 1000.0f;
	    /* pfDraw */
	    ddd[3] = (MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawEnd -
		      MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawStart) * 1000.0f;
	    /* postdraw channel callback */
	    ddd[4] = (MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].end -
		      MPS->mpsFrameStamps[i].channels[j].draw[PREV_MPSFRAME].pfDrawEnd) * 1000.0f;	    
	    
	    /* dumping in file */
	    fprintf( fid, channelsFormat1, cdString, j, i, absoluteString, ii[0], dd[0], dd[1], dd[2], dd[3]);
	    fprintf( fid, channelsFormat2, ii[1], dd[4], dd[5], dd[6], dd[7], dd[8]);
	    fprintf( fid, channelsFormat3, relativeString, ddd[0], ddd [1], ddd[2], ddd[3], ddd[4]); 
	}	
    }
    
    fclose(fid);
}