00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00030
00031
00032
00033
00034
00035
00036
00037 #define IP_HISTORY_START_ADD(ip, amount) \
00038 ((ip)->ip_History.start + (amount)) % (ip)->ip_History.length
00039
00040
00041
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
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 }