diff options
author | Dan Wells <dwells@cs.uiuc.edu> | 1998-10-26 20:07:31 (GMT) |
---|---|---|
committer | Dan Wells <dwells@cs.uiuc.edu> | 1998-10-26 20:07:31 (GMT) |
commit | 4d5f1b72de9f2439904975da411dea4f8095fe7b (patch) | |
tree | cf7eff933c1ee729881d77f6e419df3de13be688 /pablo/PabloHDF_SDDF.c | |
parent | f7545efc76fdb4e3fb7e93b93f0e404a3a651081 (diff) | |
download | hdf5-4d5f1b72de9f2439904975da411dea4f8095fe7b.zip hdf5-4d5f1b72de9f2439904975da411dea4f8095fe7b.tar.gz hdf5-4d5f1b72de9f2439904975da411dea4f8095fe7b.tar.bz2 |
[svn-r796] Pablo instrumentation support files.
Diffstat (limited to 'pablo/PabloHDF_SDDF.c')
-rw-r--r-- | pablo/PabloHDF_SDDF.c | 1028 |
1 files changed, 1028 insertions, 0 deletions
diff --git a/pablo/PabloHDF_SDDF.c b/pablo/PabloHDF_SDDF.c new file mode 100644 index 0000000..af57200 --- /dev/null +++ b/pablo/PabloHDF_SDDF.c @@ -0,0 +1,1028 @@ +/* + * This file is an extension to NCSA HDF to enable the use of the + * Pablo trace library. + * + * Developed by: The TAPESTRY Parallel Computing Laboratory + * University of Illinois at Urbana-Champaign + * Department of Computer Science + * 1304 W. Springfield Avenue + * Urbana, IL 61801 + * + * Copyright (c) 1995 + * The University of Illinois Board of Trustees. + * All Rights Reserved. + * + * PABLO is a registered trademark of + * The Board of Trustees of the University of Illinois + * registered in the U.S. Patent and Trademark Office. + * + * Author: George Xin Zhou (xzhou@cs.uiuc.edu) + * Contributing Author: Jonathan M. Reid (jreid@cs.uiuc.edu) + * + * Project Manager and Principal Investigator: + * Daniel A. Reed (reed@cs.uiuc.edu) + * + * Funded by: National Aeronautics and Space Administration under NASA + * Contracts NAG-1-613 and USRA 5555-22 and by the Advanced Research + * Projects Agency under ARPA contracts DAVT63-91-C-0029 and + * DABT63-93-C-0040. + * + */ +/*======================================================================* +// File: PabloHDF_SDDF.c * +// Purpose: support use of Pablo trace library to analyze HDF * +// performance * +// Contents: * +// HDFinitTrace_SDDF: initialize SDDF tracing * +// HDFendTrace_SDDF: end SDDF tracing * +// startHDFtraceEvent: record start of HDF procedure * +// endHDFtraceEvent: record end of HDF proc * +// preInitHDFProcTrace: called by HDFinitTrace_SDDF to set up SDDF * +// interface function calls * +// initHDFProcTrace: called by HDFinitTrace_SDDF to initialize data * +// structures used in tracing HDF procedures. * +// writeHDFProcRecordDescriptors: * +// generates the record descriptors for the HDF * +// procedure entry/exit event families. * +// HDFprocEventRecord: generates trace records for events which are * +// to produce procedure entry or exit event family * +// trace records. * +// findHDFProcEvent: retruns procedure entry/exit index * +// _hdfTraceEntryDescriptor: * +// Generate a SDDF binary format record descriptor * +// for HDF procedure entries * +// _hdfTraceExitDescriptor: * +// Generate a SDDF binary format record descriptor * +// for the HDF procedure exits * +//======================================================================*/ +#include <stdio.h> + +#ifdef HAVE_PARALLEL +#include "mpi.h" +#endif + +#undef HAVE_PABLO +#include "H5private.h" +#define HAVE_PABLO +#include "H5config.h" +#include "ProcIDs.h" + +#include "SystemDepend.h" +#include "SDDFparam.h" +#include "TraceParam.h" +#include "Trace.h" +#include "HDFTrace.h" +void HDFendTrace_SDDF(void); +void startHDFtraceEvent(int eventID); +void endHDFtraceEvent(int , int , char *, int ); +int preInitHDFProcTrace( void ); +int initHDFProcTrace( int , int * ); +int writeHDFProcRecordDescriptors( void ); +int findHDFProcEvent( int ) ; +TR_RECORD *HDFprocEventRecord( int, TR_EVENT *, CLOCK, HDFsetInfo *, unsigned ); +TR_RECORD *miscEventRecord( int , TR_EVENT *, CLOCK, void *, unsigned ); +void _hdfTraceEntryDescriptor( void ); +void _hdfTraceExitDescriptor( void ); +void _hdfMiscDescriptor( void ); +void _hdfProcNameDescriptor( void ); +int setEventRecordFunction( int, void * ); +void HDFtraceIOEvent( int, void *, unsigned ); +void initIOTrace( void ); +void enableIOdetail( void ); +void disableLifetimeSummaries( void ); +void disableTimeWindowSummaries( void ); +void disableFileRegionSummaries( void ); + +void initIOTrace( void ); +void endIOTrace( void ); +#define PABLO 1 +/* on the ipsc/860 we don't include unistd.h */ +#ifndef __NX +#include <unistd.h> +#endif + +#define returnRecord(x) return x; + +#ifdef HAVE_MPIOTRACE + int initMPIOTrace( char *, int ); + void endMPIOTrace( void ) ; +#endif +extern char *hdfRecordPointer; +/*======================================================================* +// Prototypes of functions in this file. * +//======================================================================*/ +void HDFinitTrace_SDDF( char *, uint32 ); +/*======================================================================* +// Each procedure being traced has associated with it a distinct pair * +// of entry and exit event IDs. This code maintains a vector of such * +// matchings which permits the ready identification of an event ID as * +// being either an entry event or an exit event and for which procedure.* +//======================================================================*/ +typedef struct procEventMatch { + int entryID; /* procedure entry event ID */ + int exitID; /* procedure exit event ID */ +} PROC_EVENTS; + +static PROC_EVENTS *procEvents = /* array of event ID pairs */ + (PROC_EVENTS *) 0; +/*======================================================================* +// For each procedure being traced this code maintains a stack of * +// procedure entry times. Each procedure entry event causes the * +// corresponding procedure's stack to be pushed, each procedure exit * +// event causes the corresponding procedure's stack to be popped, and * +// from the difference in time between entry and exit the procedure * +// duration may be calculated in a very straightforward subtraction. * +// The above procedure entry-exit event ID matching is used to map * +// events to their corresponding procedures. In addition, the * +// cumulative total of these procedure durations is maintained for all * +// traced subprocedures of each traced procedure. That is, when a * +// traced procedure exits, it increases this duration sum for its most * +// immediate traced ancestor procedure. By subtracting this * +// subprocedure duration sum from the traced procedure's inclusive * +// duration, we arrive at the exclusive duration of the procedure. * +//======================================================================*/ +typedef struct procEntryTime { + CLOCK entryTime; /* when proc entered */ + CLOCK subProcTime; /* subproc duration */ + struct procEntryTime *nextTime; /* stack pointer down */ + struct procEntryTime *ancestorProc; /* traced ancestor */ +} PROC_ENTRY; + +/* +static PROC_ENTRY **procEntryStack =*/ /* array of pointers to */ +/* (PROC_ENTRY **) 0;*/ /* stack top elements */ +/*======================================================================* +// Define data structure types for procedure entry and exit trace * +// records, similarly to record data structures in Trace.h * +//======================================================================*/ + +/*======================================================================* +// FAMILY_PROCENTRY family Record Data packets: * +//======================================================================*/ +struct procEntryTraceRecordData { + int packetLength; /* bytes in packet */ + int packetType; /* == PKT_DATA */ + int packetTag; /* FAMILY_PROCENTRY | RECORD_TRACE */ + int eventID; /* ID of corresponding event */ + double seconds; /* floating-point timestamp */ + long sourceByte; /* source code byte offset in file */ + int sourceLine; /* source code line number in file */ + int nodeNumber; /* occurred on which node */ +}; +#define procEntryTraceLen 6*sizeof(int) + sizeof(long) + sizeof(double) +/*======================================================================* +// FAMILY_PROCEXIT family Record Data packets: * +//======================================================================*/ +struct procExitTraceRecordData { + int packetLength; /* bytes in packet */ + int packetType; /* == PKT_DATA */ + int packetTag; /* FAMILY_PROCEXIT | RECORD_TRACE */ + int eventID; /* ID of corresponding event */ + double seconds; /* floating-point timestamp */ + long setID; /* index of file | Data Set accessed */ + int nodeNumber; /* occurred on which node */ + int nameLen; /* Length of file or data set name */ + /* name comes next, but no space is allocated */ +}; +#define procExitTraceLen 6*sizeof(int) + 3*sizeof(double) +sizeof(long) +/*======================================================================* +// misc Record Data packets: * +//======================================================================*/ +struct miscTraceRecordData { + int packetLength; /* bytes in packet */ + int packetType; /* == PKT_DATA */ + int packetTag; /* FAMILY_MISC | RECORD_TRACE */ + int eventID; /* ID of corresponding event */ + double seconds; /* floating-point timestamp */ + double duration; /* floating-point operation duration */ + unsigned long bytes; /* number of bytes requested */ + int nodeNumber; /* occurred on which node */ +}; +#define miscTraceLen 5*sizeof(int) + 2*sizeof(double) +sizeof(long) +/*======================================================================* +// HDFprocName Record Data packets: * +// These are used to pass information about the names of the traced * +// routine in the trace file to the post processing utilities. * +//======================================================================*/ +struct HDFprocNameRecordData { + int packetLength; /* bytes in packet */ + int packetType; /* == PKT_DATA */ + int packetTag; /* FAMILY_HDFPROCNAME | RECORD_TRACE */ + int eventID; /* ID of corresponding event */ + int HDFeventID; /* ID of HDF proc */ + int procIndex; /* Index of HDF proc */ + int numProcs; /* Number of HDF procs */ + int NameLen; /* length of HDF proc Name */ + char *Name; +}; +#define HDFprocNameRecLen 8*sizeof(int) +/*======================================================================* +// Define data structures used to contain source code location data for * +// Pablo instrumenting parser-generated code. * +//======================================================================*/ +static long procByteOffset = -1; /* source code byte offset */ + +static int procLineNumber = -1; /* source code line number */ + +/*======================================================================* +// The procEntries array specifies the event IDs of procedure entry * +// events. * +//======================================================================*/ +int procEntries[] = { +#include "HDFidList.h" +ID_HDF_Last_Entry +}; +/*======================================================================* +// The procEntryCalled array indicates whether or not a procedure entry * +// was called. * +//======================================================================*/ +int *procEntryCalled; +/*======================================================================* +// The HDFProcNames array holds the names of the HDF entries. * +//======================================================================*/ +static char HDFProcNames[][40] = { +#include "HDFentryNames.h" +"HDF_LAST_ENTRY" +}; +/*======================================================================= +// NAME * +// HDFinitTrace_SDDF -- initalize HDF tracing with SDDF records * +// USAGE * +// HDFinitTrace_SDDF( traceFileName, procTraceMask ) * +// PARAMETERS * +// char *traceFileName -- name of trace file to hold output * +// uint32 prcoTraceMask -- mask indicating classes of HDF procs to * +// be traced * +// RETURNS * +// None * +//======================================================================*/ +void HDFinitTrace_SDDF( char *traceFileName, uint32 procTraceMask ) +{ + /*=============================================================== + // set traceFileName and set IO tracing switches. If MPIO * + // tracing is available, this will be initialized also. * + //==============================================================*/ +#ifdef HAVE_PARALLEL + /*=============================================================== + // in the parallel case, initialize MPI-IO tracing. This will * + // initialize the traceFileName and set the I/O tracing * + // switches. * + //==============================================================*/ + MPI_Comm_rank( MPI_COMM_WORLD, &myNode ); + setTraceProcessorNumber( myNode ); +#ifdef HAVE_MPIOTRACE + initMPIOTrace( traceFileName, 0 ); +#else + buff = (char *)malloc( strlen(traceFileName)+12); + sprintf( buff, "%s.nd%.4d\0",traceFileName,myNode); + setTraceFileName( buff ); + free( buff ); +#endif +#else + /*=============================================================== + // in the non-parallel case, set the trace file name and the * + // I/O tracing switches. * + //==============================================================*/ + setTraceFileName(traceFileName); + initIOTrace(); + enableIOdetail(); + disableLifetimeSummaries(); + disableTimeWindowSummaries(); + disableFileRegionSummaries(); +#endif /* HAVE_PARALLEL */ + /*=============================================================== + // complete HDF initiailization. * + //==============================================================*/ + preInitHDFProcTrace(); + initHDFProcTrace( sizeof(procEntries)/sizeof(int), procEntries ); + procTrace = procTraceMask; +} +/*======================================================================= +// NAME * +// HDFendTrace_SDDF -- end HDF tracing * +// USAGE * +// HDFendTrace_SDDF() * +// RETURNS * +// None. * +//======================================================================*/ +void HDFendTrace_SDDF(void) +{ + HDFtraceIOEvent( -ID_timeStamp, 0, 0 ); +#ifdef HAVE_MPIOTRACE + /*=============================================================== + // termintate MPI-IO tracing in the parallel case. This will * + // terminate the I/O tracing and close tracing as well. * + //==============================================================*/ + endMPIOTrace(); +#else + /*=============================================================== + // terminate tracing * + //==============================================================*/ + endIOTrace(); + endTracing(); +#endif +} +/*======================================================================= +// NAME * +// initHDFProcTrace: * +// This function initializes data structures specific to * +// the procedure entry/exit tracing extensions of the Pablo * +// instrumentation library. The argument numProcs specifies * +// how many procedures are to be traced. The argument procEntryID * +// is a vector specifying the event IDs to be use as entry events * +// for each of the procedures. The negative value is used for * +// the exit event ID. * +// USAGE * +// result = initHDFProcTrace(numProcs,procEntryID) * +// PARAMETERS * +// int numProcs -- number of Procedures to be initialized * +// int *procEntryID -- array of id entry codes for these procedures * +// RETURNS * +// SUCCESS or FAILURE * +//======================================================================*/ +int initHDFProcTrace( int numProcs, int *procEntryID ) +{ + int procIndex; + + if (( numProcs <= 0 ) || ( procEntryID == (int *) 0 ) ) + return FAILURE; + /*=============================================================== + // Allocate space to store a copy of the procedure entry-exit * + // event ID matchings and also the procedure entry stacks. * + //==============================================================*/ + procEvents = (PROC_EVENTS *) TRgetBuffer( + (numProcs+4)*sizeof(PROC_EVENTS) ); + + if ( procEvents == (PROC_EVENTS *) 0 ) + TRfailure( "cannot allocate procedure events matching" ); + + procEntryCalled = ( int *)malloc( numProcs*sizeof(int) ); + if ( procEvents == NULL ) + TRfailure( "cannot allocate procedure Called indicators" ); + /*=============================================================== + // Initialize the procedure events matching from the arguments * + // passed. Configure the trace record-generating function for * + // these events. Initialize the flags indicating whether or * + // not the procedure was called. * + //==============================================================*/ + for ( procIndex = 0; procIndex < numProcs; procIndex++ ) { + + procEvents[ procIndex ].entryID = procEntryID[ procIndex ]; + procEvents[ procIndex ].exitID = -procEntryID[ procIndex ]; + + setEventRecordFunction( procEntryID[ procIndex ], + HDFprocEventRecord ); + setEventRecordFunction( -procEntryID[ procIndex ], + HDFprocEventRecord ); + procEntryCalled[ procIndex ] = 0; + + } + + /*=============================================================== + // Initialize the procedure events for malloc. * + // Configure the trace record-generating function for this * + // event. * + //==============================================================*/ + procEvents[ numProcs ].entryID = ID_malloc; + procEvents[ numProcs ].exitID = -ID_malloc; + setEventRecordFunction( ID_malloc, miscEventRecord ); + setEventRecordFunction( -ID_malloc, miscEventRecord ); + procEvents[ numProcs+1 ].entryID = ID_free; + procEvents[ numProcs+1 ].exitID = -ID_free; + setEventRecordFunction( ID_free, miscEventRecord ); + setEventRecordFunction( -ID_free, miscEventRecord ); + procEvents[ numProcs+2 ].entryID = ID_timeStamp; + procEvents[ numProcs+2 ].exitID = -ID_timeStamp; + setEventRecordFunction( ID_timeStamp, miscEventRecord ); + setEventRecordFunction( -ID_timeStamp, miscEventRecord ); + + return SUCCESS; +} +/*======================================================================= +// NAME * +// preInitHDFProcTrace: * +// This function calls the trace library interface function * +// setRecordDescriptor, which records the address of the * +// procedure that generates the record descriptors for the * +// procedure trace event families. It is automatically * +// invoked by HDFinitTrace_SDDF. * +// USAGE * +// result = preInitHDFProcTrace(); * +// RESULT * +// SUCCESS or FAILURE * +/=======================================================================*/ +int preInitHDFProcTrace( void ) +{ + static int preInitDone = FALSE; + + if ( preInitDone == TRUE ) + return SUCCESS; + /*=============================================================== + // Give the instrumentation library a pointer to the functions * + // in which we output the specialized record descriptors for * + // procedure entry/exit. * + //==============================================================*/ + setRecordDescriptor( writeHDFProcRecordDescriptors ); + + preInitDone = TRUE; + return SUCCESS; +} +/*======================================================================= +// NAME * +// writeHDFProcRecordDescriptors: * +// This function generates the record descriptors for the HDF * +// procedure entry/exit event families. It will be invoked * +// by the instrumentation library initialization routines. * +// Patterned after instrumentation library internal function * +// writeRecordDescriptors. * +// USAGE * +// result = writeHDFProcRecordDescriptors(); * +// RESULT * +// SUCCESS * +/=======================================================================*/ +int writeHDFProcRecordDescriptors( void ) +{ +#ifdef DEBUG + fprintf( debugFile, "writeHDFProcRecordDescriptors\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + + _hdfMiscDescriptor(); + _hdfTraceEntryDescriptor() ; + _hdfTraceExitDescriptor() ; + _hdfProcNameDescriptor(); + +#ifdef DEBUG + fprintf( debugFile, "writeHDFProcRecordDescriptors done\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + return SUCCESS; +} +/*======================================================================= +// NAME * +// HDFprocEventRecord: * +// This function generates trace records for events which are * +// to produce procedure entry or exit event family trace records. * +// Patterned after the instrumentation library internal functions * +// externalEventRecord and sddfRecord. * +// USAGE * +// REC = HDFprocEventRecord( recordType, eventPointer, timeStamp, * +// dataPointer, dataLength) * +// PARAMETERS * +// int recordType -- type of event record * +// TR_EVENT eventPointer -- pointer to event data structure * +// CLOCK timeStamp -- time event is recorded * +// HDFsetInfo dataPointer -- information about HDF data set accessed * +// unsigned dataLength -- dummy for compatability * +// RETURNS * +// pointer to trace record for this event * +//======================================================================*/ +TR_RECORD * +HDFprocEventRecord( int recordType, TR_EVENT *eventPointer, CLOCK timeStamp, + HDFsetInfo *dataPointer, unsigned dataLength ) +{ + static TR_RECORD traceRecord; + static void *recordBuffer = NULL; + static int bufferLength = 0; + struct procEntryTraceRecordData *entryTraceRecordHeader; + struct procExitTraceRecordData *exitTraceRecordHeader; + struct HDFprocNameRecordData *nameRecord; + int procIndex; + int recordFamily; + char *namePtr; + int NameLen; + int NameRecLen; + +#ifdef DEBUG + fprintf( debugFile, "HDFprocEventRecord\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + + /*==============================================================* + // Find the index in the tables for the procedure corresponding * + // to this eventID. * + //==============================================================*/ + procIndex = findHDFProcEvent( eventPointer->eventID ); + if ( procIndex < 0 ) { + return nullRecordFunction( recordType, eventPointer, + timeStamp, (char *)dataPointer, dataLength ); + } + /*==============================================================* + // Produce a packet for the name of the procedure if one has * + // not already been produced. * + //==============================================================*/ + if ( procEntryCalled[procIndex] == 0 ) { + NameLen = strlen( HDFProcNames[procIndex] ); + NameRecLen = HDFprocNameRecLen + NameLen; + nameRecord = ( struct HDFprocNameRecordData *)malloc( NameRecLen ); + nameRecord->packetLength = NameRecLen; + nameRecord->packetType = PKT_DATA; + nameRecord->packetTag = FAMILY_HDFPROCNAME | RECORD_TRACE; + nameRecord->eventID = ID_HDFprocName; + nameRecord->HDFeventID = abs(eventPointer->eventID); + nameRecord->procIndex = procIndex; + nameRecord->numProcs = NumHDFProcs; + nameRecord->NameLen = NameLen; + /*===========================================================* + // copy procedure name into the packet, write out the packet * + // and set ProcEntryCalled[procIndex] to indicate the name * + // packet was produced. * + //===========================================================*/ + memcpy( &(nameRecord->Name), HDFProcNames[procIndex], NameLen ); + putBytes( (char *)nameRecord , NameRecLen ); + free( nameRecord ); + procEntryCalled[procIndex] = 1; + } + /*==============================================================* + // Determine whether this is a procedure entry or a procedure * + // exit family event by lookup in the procedure event ID * + // matching. * + //==============================================================*/ + if ( procEvents[ procIndex ].entryID == eventPointer->eventID ) { + recordFamily = FAMILY_PROCENTRY; + } else { + recordFamily = FAMILY_PROCEXIT; + } + /*==============================================================* + // The time stamp stored in the event descriptor will be used * + // unless one is specified in the timeStamp parameter. * + //==============================================================*/ + if ( clockCompare( timeStamp, noSuchClock ) == 0 ) { + timeStamp = eventPointer->eventLast; + } + /*==============================================================* + // Determine how many bytes of storage will be needed for the * + // contents of the trace record. * + //==============================================================*/ + switch (( recordFamily | recordType )) { + + case FAMILY_PROCENTRY | RECORD_TRACE: + traceRecord.recordLength = sizeof *entryTraceRecordHeader; + break; + + case FAMILY_PROCEXIT | RECORD_TRACE: + traceRecord.recordLength = sizeof *exitTraceRecordHeader; + break; + } + if ( dataPointer != NULL && dataPointer->setName != NULL ) { + traceRecord.recordLength += strlen( dataPointer->setName ); + } + /*==============================================================* + // If there is a previously-allocated buffer and its size will * + // hold this record, re-use the buffer. Otherwise, deallocate * + // the buffer (if allocated) and allocate a bigger one. * + //==============================================================*/ + if ( bufferLength < traceRecord.recordLength ) { + + if ( recordBuffer != NULL ) { + TRfreeBuffer( recordBuffer ); + } + + recordBuffer = (char *)TRgetBuffer( traceRecord.recordLength ); + + if ( recordBuffer == NULL ) { + TRfailure( "cannot allocate storage for trace record" ); + } + bufferLength = traceRecord.recordLength; + } + + traceRecord.recordContents = recordBuffer; + /*==============================================================* + // Load the trace record fields into the allocated buffer * + //==============================================================*/ + switch (( recordFamily | recordType )) { + + case FAMILY_PROCENTRY | RECORD_TRACE: + entryTraceRecordHeader = (struct procEntryTraceRecordData *) + recordBuffer; + entryTraceRecordHeader->packetLength = + traceRecord.recordLength; + entryTraceRecordHeader->packetType = PKT_DATA; + entryTraceRecordHeader->packetTag = recordFamily | recordType; + entryTraceRecordHeader->seconds = clockToSeconds( timeStamp ); + entryTraceRecordHeader->eventID = eventPointer->eventID; + entryTraceRecordHeader->nodeNumber = TRgetNode(); + entryTraceRecordHeader->sourceByte = procByteOffset; + entryTraceRecordHeader->sourceLine = procLineNumber; + break; + + case FAMILY_PROCEXIT | RECORD_TRACE: + exitTraceRecordHeader = (struct procExitTraceRecordData *) + recordBuffer; + exitTraceRecordHeader->packetLength = + traceRecord.recordLength; + exitTraceRecordHeader->packetType = PKT_DATA; + exitTraceRecordHeader->packetTag = recordFamily | recordType; + exitTraceRecordHeader->seconds = clockToSeconds( timeStamp ); + exitTraceRecordHeader->eventID = eventPointer->eventID; + exitTraceRecordHeader->nodeNumber = TRgetNode(); + + if ( dataPointer != 0 ) { + exitTraceRecordHeader->setID = dataPointer->setID; + if (dataPointer->setName != NULL ) { + exitTraceRecordHeader->nameLen + = (int)strlen( dataPointer->setName ); + /*================================================* + // copy name directly into the end of the buffer. * + //================================================*/ + namePtr = (char *)exitTraceRecordHeader + + procExitTraceLen; + memcpy( namePtr, dataPointer->setName, + exitTraceRecordHeader->nameLen ); + } else { + exitTraceRecordHeader->nameLen = 0; + } + } else { + exitTraceRecordHeader->setID = NoDSid; + exitTraceRecordHeader->nameLen = 0; + } + break; + } + +#ifdef DEBUG + fprintf( debugFile, "HDFprocEventRecord done\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + returnRecord(&traceRecord); +} +/*======================================================================* +// Internal Routine: miscEventRecord * +// Called for misc start and end events. * +//======================================================================*/ +TR_RECORD *miscEventRecord( int recordType, + TR_EVENT *eventPointer, + CLOCK timeStamp, + void *dataPointer, + unsigned dataLength ) +{ + static TR_RECORD traceRecord; + static struct miscTraceRecordData miscRecord; + static int initialized = FALSE; + int eventID; + + if ( clockCompare( timeStamp, noSuchClock ) == 0 ) { + timeStamp = eventPointer->eventLast; + } + + eventID = eventPointer->eventID; + if ( ! initialized ) { + miscRecord.packetLength = sizeof( miscRecord ); + miscRecord.packetType = PKT_DATA; + miscRecord.packetTag = FAMILY_MISC | RECORD_TRACE; + miscRecord.nodeNumber = traceProcessorNumber; + + traceRecord.recordLength = miscRecord.packetLength; + traceRecord.recordContents = (char *) &miscRecord; + initialized = TRUE; + } + + switch ( eventID ) { + case ID_malloc: + case ID_free: + miscRecord.seconds = clockToSeconds( timeStamp ) ; + miscRecord.bytes = *(size_t *)dataPointer; + miscRecord.eventID = eventID ; + break; + case -ID_malloc: + case -ID_free: + miscRecord.duration = clockToSeconds( timeStamp) + - miscRecord.seconds; + return &traceRecord; /* generate trace record */ + break; + case ID_timeStamp: + case -ID_timeStamp: + miscRecord.seconds = clockToSeconds( timeStamp ) ; + miscRecord.bytes = 0; + miscRecord.eventID = eventID ; + miscRecord.duration = 0; + return &traceRecord; + break; + default: + fprintf( stderr, "miscEventRecord: unknown eventID %d\n", eventID ); + break; + } + /*==================================================================* + // If we get here then no trace record generated. Normally we * + // should get here if this is an entry call. * + //==================================================================*/ + return( nullRecordFunction( recordType, eventPointer, timeStamp, + dataPointer, dataLength ) ); +} +/*======================================================================* +// NAME * +// findHDFProcEvent: * +// Search the procedure entry/exit event ID matching data * +// structure for an event ID (either entry or exit) which is * +// the same as the argument eventID. If found, return the * +// index from that table, which will be between 0 and * +// numberProcedures - 1, inclusive. If not found, return -1; * +// USAGE * +// index = findHDFProcEvent * +// RETURNS * +// index of the procedure corresponding to this ID * +//======================================================================*/ +int findHDFProcEvent( int eventID ) +{ + int procIndex; + +#ifdef DEBUG + fprintf( debugFile, "findHDFProcEvent\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + if ( isBeginHDFEvent(eventID) ) { + procIndex = eventID - BEGIN_HDF; + } else if ( isEndHDFEvent( eventID ) ) { + procIndex = -eventID - BEGIN_HDF; + } else { + procIndex = -1 ; + } + return procIndex; +} +/*======================================================================* +// NAME * +// _hdfTraceEntryDescriptor * +// Generate a SDDF binary format record descriptor for the * +// full trace class of events in the HDF procedure entry * +// USAGE * +// _hdfTraceEntryDescriptro() * +// RETURNS * +// void * +//======================================================================*/ +void _hdfTraceEntryDescriptor( void ) +{ + static char recordBuffer[ 4096 ]; + int recordLength; + +#ifdef DEBUG + fprintf( debugFile, "_hdfTraceEntryDescriptor entered\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + hdfRecordPointer = recordBuffer; + /*==================================================================* + // Allow space at the beginning of the record for the packet * + //length which will be computed after the packet is complete. * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 0 ); + /*==================================================================* + // The record type, tag, and name * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, PKT_DESCRIPTOR ); + sddfWriteInteger( &hdfRecordPointer, ( FAMILY_PROCENTRY | RECORD_TRACE ) ); + sddfWriteString( &hdfRecordPointer, "HDF Procedure Entry Trace" ); + /*==================================================================* + // The record attribute count and string pair * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 1 ); + sddfWriteString( &hdfRecordPointer, "description" ); + sddfWriteString( &hdfRecordPointer, "HDF Procedure Entry Trace Record" ); + /*==================================================================* + // The record field count * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 5); + /*==================================================================* + // Create fields * + //==================================================================*/ + WRITE_HDF_FIELD( "Event Identifier", + "Event ID", + "Event Identifier Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "Seconds", + "Seconds", + "Floating Point Timestamp", + DOUBLE, 0 ); + WRITE_HDF_FIELD( "Source Byte", + "Byte", + "Source Byte Offset", + LONG, 0 ); + WRITE_HDF_FIELD( "Source Line", + "Line", + "Source Line Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "Processor Number", + "Node", + "Processor number", + INTEGER, 0 ); + + recordLength = (int)(hdfRecordPointer - recordBuffer); + + hdfRecordPointer = recordBuffer; + sddfWriteInteger( &hdfRecordPointer, recordLength ); + + putBytes( recordBuffer, (unsigned) recordLength ); +} +/*======================================================================* +// NAME * +// _hdfTraceExitDescriptor * +// Generate a SDDF binary format record descriptor for the * +// full trace class of events in the HDF procedure exit * +// USAGE * +// _hdfTraceExitDescriptor() * +// RETURNS * +// void * +//======================================================================*/ +void _hdfTraceExitDescriptor( void ) +{ + static char recordBuffer[ 4096 ]; + int recordLength; + +#ifdef DEBUG + fprintf( debugFile, "_hdfExitTraceDescriptor entered\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + hdfRecordPointer = recordBuffer; + /*==================================================================* + // Allow space at the beginning of the record for the packet * + // length which will be computed after the packet is complete. * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 0 ); + /*==================================================================* + // The record type, tag, and name * + /===================================================================*/ + sddfWriteInteger( &hdfRecordPointer, PKT_DESCRIPTOR ); + sddfWriteInteger( &hdfRecordPointer, ( FAMILY_PROCEXIT | RECORD_TRACE ) ); + sddfWriteString( &hdfRecordPointer, "HDF Procedure Exit Trace" ); + /*==================================================================* + // The record attribute count and string pair * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 1 ); + sddfWriteString( &hdfRecordPointer, "description" ); + sddfWriteString( &hdfRecordPointer, "HDF Procedure Exit Trace Record" ); + /*==================================================================* + // The record field count * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 5); + /*==================================================================* + // Create fields * + //==================================================================*/ + WRITE_HDF_FIELD( "Event Identifier", + "Event ID", + "Event Identifier Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "Seconds", + "Seconds", + "Floating Point Timestamp", + DOUBLE, 0 ); + WRITE_HDF_FIELD2( "HDF ID", + "HDF ID", "File, Data Set or Dim Identifier number", + "0", "No HDF ID specified", + LONG, 0 ); + WRITE_HDF_FIELD( "Processor Number", + "Node", + "Processor number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "HDF Name", + "HDF Name", "Name of File, Data Set or Dim", + CHARACTER, 1 ); + + recordLength = (int)(hdfRecordPointer - recordBuffer); + + hdfRecordPointer = recordBuffer; + sddfWriteInteger( &hdfRecordPointer, recordLength ); + + putBytes( recordBuffer, (unsigned) recordLength ); +} + +/*======================================================================* +// NAME * +// _hdfMiscDescriptor * +// Generate a SDDF binary format record descriptor for the * +// misc procedure * +// USAGE * +// _hdfMiscDescriptor() * +// RETURNS * +// void * +//======================================================================*/ +void _hdfMiscDescriptor( void ) +{ + static char recordBuffer[ 4096 ]; + int recordLength; + +#ifdef DEBUG + fprintf( debugFile, "_hdfMiscDescriptor entered\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + hdfRecordPointer = recordBuffer; + /*==================================================================* + // Allow space at the beginning of the record for the packet * + //length which will be computed after the packet is complete. * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 0 ); + /*==================================================================* + // The record type, tag, and name * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, PKT_DESCRIPTOR ); + sddfWriteInteger( &hdfRecordPointer, ( FAMILY_MISC | RECORD_TRACE ) ); + sddfWriteString( &hdfRecordPointer, "Misc Trace" ); + /*==================================================================* + // The record attribute count and string pair * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 1 ); + sddfWriteString( &hdfRecordPointer, "description" ); + sddfWriteString( &hdfRecordPointer, "Misc Trace Record" ); + /*==================================================================* + // The record field count * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 5); + /*==================================================================* + // Create fields * + //==================================================================*/ + WRITE_HDF_FIELD( "Event Identifier", + "Event ID", + "Event Identifier Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "Seconds", + "Seconds", + "Floating Point Timestamp", + DOUBLE, 0 ); + WRITE_HDF_FIELD( "Duration", + "Duration", + "Operation Duration", + DOUBLE, 0 ); + WRITE_HDF_FIELD( "Bytes", + "Bytes", + "Bytes Requested", + LONG, 0 ); + WRITE_HDF_FIELD( "Processor Number", + "Node", + "Processor number", + INTEGER, 0 ); + + recordLength = (int)(hdfRecordPointer - recordBuffer); + + hdfRecordPointer = recordBuffer; + sddfWriteInteger( &hdfRecordPointer, recordLength ); + + putBytes( recordBuffer, (unsigned) recordLength ); +} +/*======================================================================* +// NAME * +// _hdfProcNameDescriptor * +// Generate a SDDF binary format record descriptor for the * +// HDFProcName Records * +// USAGE * +// _hdfProcNameDescriptor() * +// RETURNS * +// void * +//======================================================================*/ +void _hdfProcNameDescriptor( void ) +{ + static char recordBuffer[ 4096 ]; + int recordLength; + +#ifdef DEBUG + fprintf( debugFile, "_hdfProcNameDescriptor entered\n" ); + fflush( debugFile ); +#endif /* DEBUG */ + hdfRecordPointer = recordBuffer; + /*==================================================================* + // Allow space at the beginning of the record for the packet * + //length which will be computed after the packet is complete. * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 0 ); + /*==================================================================* + // The record type, tag, and name * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, PKT_DESCRIPTOR ); + sddfWriteInteger( &hdfRecordPointer, ( FAMILY_HDFPROCNAME| RECORD_TRACE ) ); + sddfWriteString( &hdfRecordPointer, "HDF Procedure Information" ); + /*==================================================================* + // The record attribute count and string pair * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 1 ); + sddfWriteString( &hdfRecordPointer, "description" ); + sddfWriteString( &hdfRecordPointer, "HDF Proc Info Record" ); + /*==================================================================* + // The record field count * + //==================================================================*/ + sddfWriteInteger( &hdfRecordPointer, 5); + /*==================================================================* + // Create fields * + //==================================================================*/ + WRITE_HDF_FIELD( "Event Identifier", + "Event ID", + "Event Identifier Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "HDF Proc Event Id", + "HDF Proc Event Identifier", + "HDF Proc Event Identifier Number", + INTEGER, 0 ); + WRITE_HDF_FIELD( "HDF Proc Index", + "HDF Proc Index", + "Index of HDF Proc in Tables", + INTEGER, 0 ); + WRITE_HDF_FIELD( "Num HDF Procs", + "Num HDF Procs", + "Number of HDF Procedures", + INTEGER, 0 ); + WRITE_HDF_FIELD( "HDF Proc Name", + "HDF Proc Name", + "Name of HDF Procedure", + CHARACTER, 1 ); + recordLength = (int)(hdfRecordPointer - recordBuffer); + + hdfRecordPointer = recordBuffer; + sddfWriteInteger( &hdfRecordPointer, recordLength ); + + putBytes( recordBuffer, (unsigned) recordLength ); +} +/*#endif */ /* HAVE_PABLO */ |