Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

instrumentation.c

Go to the documentation of this file.
00001 /*
00002  * instrumentation.c
00003  *
00004  * Copyright (c) 2003 The University of Utah and the Flux Group.
00005  * All rights reserved.
00006  *
00007  * This file is licensed under the terms of the GNU Public License.  
00008  * See the file "license.terms" for restrictions on redistribution 
00009  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  */
00011 
00012 /**
00013  * @file instrumentation.c
00014  *
00015  * Implementation of the functions in instrumentation.h.
00016  */
00017 
00018 #include "config.h"
00019 
00020 #include <sys/types.h>
00021 #include <string.h>
00022 #include <unistd.h>
00023 #include <float.h>
00024 #include <assert_pp.h>
00025 
00026 #include "instrumentation.h"
00027 
00028 /**
00029  * Add an amount to an existing index into the ip_History.data array of the
00030  * iPoint structure.  In case the addition causes the index to extend beyond
00031  * the bounds of the array, the result will be wrapped around to the beginning.
00032  *
00033  * @param ip A pointer to a valid iPoint.
00034  * @param amount The amount to add to the ip_History.start value.
00035  * @return The new index.
00036  */
00037 #define IP_HISTORY_START_ADD(ip, amount) \
00038     ((ip)->ip_History.start + (amount)) % (ip)->ip_History.length
00039 
00040 /**
00041  * The default name for the instrumentation file.
00042  */
00043 static const char *DEFAULT_INSTRUMENTATION_FILE_NAME =
00044     PACKAGE "-instrumentation-%d.txt";
00045 
00046 struct iInstrumentationData instrumentation_data;
00047 
00048 static void iInitPoint(struct iPoint *ip)
00049 {
00050     require(ip != NULL);
00051     require(ip->ip_Name != NULL);
00052 
00053     ip->ip_Minimum = FLT_MAX;
00054     ip->ip_Maximum = FLT_MIN;
00055     if( ip->ip_Format == NULL )
00056     {
00057         ip->ip_Format = "%10.2f  ";
00058     }
00059     if( ip->ip_Succ == NULL )
00060     {
00061         if( instrumentation_data.iid_FirstPoint == NULL )
00062         {
00063             instrumentation_data.iid_FirstPoint =
00064                 &instrumentation_data.iid_NullPoint;
00065         }
00066         ip->ip_Succ = instrumentation_data.iid_FirstPoint;
00067         instrumentation_data.iid_FirstPoint = ip;
00068     }
00069 }
00070 
00071 void iPostFloatData(struct iPoint *ip, double value)
00072 {
00073     require(ip != NULL);
00074 
00075     if( ip->ip_Count == 0 )
00076     {
00077         /* The first recorded value, initialize any defaults. */
00078         iInitPoint(ip);
00079     }
00080     if( ip->ip_History.data != NULL )
00081     {
00082         if( ip->ip_Count >= ip->ip_History.length )
00083         {
00084             ip->ip_History.lost += 1;
00085             if( ip->ip_Flags & IPF_DROP_HISTORY_START )
00086             {
00087                 ip->ip_History.data[ip->ip_History.start] = value;
00088                 ip->ip_History.start = IP_HISTORY_START_ADD(ip, 1);
00089             }
00090         }
00091         else
00092         {
00093             ip->ip_History.data[ip->ip_Count] = value;
00094         }
00095     }
00096     ip->ip_Count += 1;
00097     ip->ip_Total += value;
00098     if( value < ip->ip_Minimum )
00099     {
00100         ip->ip_Minimum = value;
00101     }
00102     if( value > ip->ip_Maximum )
00103     {
00104         ip->ip_Maximum = value;
00105     }
00106 }
00107 
00108 void iPrintPoint(FILE *file, struct iPoint *ip)
00109 {
00110     require(file != NULL);
00111     require(ip != NULL);
00112     require(ip->ip_Name != NULL);
00113 
00114     fprintf(file,
00115             "%s: count=%qd total=%f min=%f max=%f avg=%f  '%s'\n",
00116             ip->ip_Name,
00117             ip->ip_Count,
00118             ip->ip_Total,
00119             ip->ip_Minimum,
00120             ip->ip_Maximum,
00121             ip->ip_Total / ((double)ip->ip_Count),
00122             ip->ip_Description != NULL ? ip->ip_Description : "");
00123     if( ip->ip_History.data != NULL )
00124     {
00125         int lpc;
00126 
00127         if( ip->ip_History.lost > 0 )
00128         {
00129             fprintf(file,
00130                     "\tLost %d data points at the start\n",
00131                     ip->ip_History.lost);
00132         }
00133         for( lpc = 0;
00134              (lpc < ip->ip_Count) && (lpc < ip->ip_History.length);
00135              )
00136         {
00137             int row_count;
00138             
00139             fprintf(file, "\t");
00140             for( row_count = 0;
00141                  (row_count < 5) &&
00142                      (lpc < ip->ip_Count) &&
00143                      (lpc < ip->ip_History.length);
00144                  row_count++, lpc++ )
00145             {
00146                 fprintf(file,
00147                         ip->ip_Format,
00148                         ip->ip_History.data[IP_HISTORY_START_ADD(ip, lpc)]);
00149             }
00150             fprintf(file, "\n");
00151         }
00152     }
00153 }
00154 
00155 void iPrintPoints(FILE *file)
00156 {
00157     struct iPoint *ip;
00158     
00159     require(file != NULL);
00160 
00161     ip = instrumentation_data.iid_FirstPoint;
00162     while( (ip != NULL) && (ip != &instrumentation_data.iid_NullPoint) )
00163     {
00164         iPrintPoint(file, ip);
00165         ip = ip->ip_Succ;
00166     }
00167 }
00168 
00169 void iPrintPointsAtExit(void)
00170 {
00171     FILE *file;
00172 
00173     if( instrumentation_data.iid_OutputFileName != NULL )
00174     {
00175         if( strcmp("-", instrumentation_data.iid_OutputFileName) == 0 )
00176         {
00177             file = stdout;
00178         }
00179         else
00180         {
00181             file = fopen(instrumentation_data.iid_OutputFileName, "w");
00182         }
00183     }
00184     else
00185     {
00186         static char formatted_filename[
00187                 sizeof(DEFAULT_INSTRUMENTATION_FILE_NAME) + 8];
00188         
00189         sprintf(formatted_filename,
00190                 DEFAULT_INSTRUMENTATION_FILE_NAME,
00191                 getpid());
00192         file = fopen(formatted_filename, "w");
00193     }
00194     if( file != NULL )
00195     {
00196         iPrintPoints(file);
00197         fclose(file);
00198     }
00199     else
00200     {
00201         fprintf(stderr,
00202                 "Warning: unable to create instrumentation file.\n");
00203     }
00204 }

Generated on Mon Dec 1 16:29:06 2003 for CPU Broker by doxygen 1.3.4