connect.c 3.88 KB
/*
 * Copyright 1995, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
 * the contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in subdivision (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, DOD or NASA FAR Supplement. Unpublished -
 * rights reserved under the Copyright Laws of the United States.
 *
 * 
 *  Connect to game, transfer profile data to host
 */

#include <sys/u64gio.h>

#ifdef __sgi
#include <bstring.h>
#endif
#include <errno.h>
#include <limits.h>
#include <ramrom.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <ultraerror.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <rdb.h>
#ifndef __sgi
#include "ultrahost.h"
#endif

#include "gperf.h"

#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif

static char errMessage[256];


/*
 *  Global histogram pointer, number of histograms, and overflow count
 */
static gPerfHisto   *Gph = (gPerfHisto *)NULL;
static int          u64fd;

/*
 *  Initialize 
 */
int
profServerInit(void)
{
    u8   sig = RDB_PROF_FLUSH_SIG;

#ifdef __sgi
    if ((u64fd = open(DEV_U64_PROFILE, O_RDWR | O_NOCTTY)) < 0) {
#else
    if ((u64fd = uhOpenGame("/tmp/u64_profile")) < 0) {
#endif
        sprintf(errMessage, "unable to open %s", DEV_U64_PROFILE);
        perror(errMessage);
        exit(1);
    }


    if (!ServerMode) {
		printf("Sending flush signal from gperf\n");
        if (write(u64fd,&sig, 1) < 0) 
        {
            sprintf(errMessage, "error writing flush");
            perror(errMessage);
            return(-1);
        }
    }
    return 0;
}

u32 profReadWord(void)
{
    u32  ct = 0;
    u32  result;
    u8   *cPtr = (char*)&result;

    while(ct < sizeof(int))
    ct += read(u64fd, &cPtr[ct], sizeof(int) - ct);

    return(ntohl(result));
}
    

/*
 *  Get flushed profile data
 */
int
profServer(void)
{
    u32    numSections;
    u32    tperiod;
    u32    overflow;
    u32    i;
    u32    curprof;
    u8     sig = RDB_PROF_ACK_SIG;
    u8     *readPtr;
    s32    totalBytes, bytesThisBlock,ct;

    while(1)
    {
        numSections = profReadWord();
        tperiod = profReadWord();
        overflow = profReadWord();
        Gph = (gPerfHisto *)malloc(sizeof(gPerfHisto) * numSections);
        curprof = 0;
        
        for(i = 0; i < numSections; i++)
        {
            Gph[curprof].start = profReadWord();
            Gph[curprof].numEntrs = profReadWord();

            totalBytes = Gph[curprof].numEntrs * sizeof(u16);
            Gph[curprof].histo = (u16 *) malloc(totalBytes);
            readPtr = (u8*)Gph[curprof].histo;
            
            write(u64fd,&sig,1);
            
            while(totalBytes > 0)
            {
                bytesThisBlock =  MIN(totalBytes,PROF_BLOCK_SIZE);
                ct = 0;
                while(ct < bytesThisBlock)
                    ct += read(u64fd, &readPtr[ct], bytesThisBlock - ct);
                
                readPtr += bytesThisBlock;
                totalBytes -= bytesThisBlock;
                write(u64fd,&sig,1);
            }
            
            curprof++;
        }


        /* okay to parse histogram here */
        report(numSections, Gph, tperiod, overflow);

        /* discard histogram data */
        if (Gph) 
        {
            for (i = 0; i < numSections; i++) 
            {
                if (Gph[i].histo)
                    free(Gph[i].histo);
            }
            free(Gph);
        }
        
    }

    return(0);
}