annotate probes.c @ 60:7b799a46cc87

Added compiler switch to turn on and off debug-only probes, deleted time-junk
author Me
date Mon, 08 Nov 2010 03:57:46 -0800
parents 3bac84e4e56e
children a6c442d52590 13b22ffb8a2f
rev   line source
Me@50 1 /*
Me@50 2 * Copyright 2010 OpenSourceStewardshipFoundation
Me@50 3 *
Me@50 4 * Licensed under BSD
Me@50 5 */
Me@50 6
Me@50 7 #include <stdio.h>
Me@50 8 #include <stdlib.h>
Me@50 9 #include <malloc.h>
Me@50 10 #include <sys/time.h>
Me@52 11 #include <string.h>
Me@50 12
Me@50 13 #include "VMS.h"
Me@50 14 #include "Queue_impl/BlockingQueue.h"
Me@50 15 #include "Histogram/Histogram.h"
Me@50 16
Me@50 17
Me@50 18 //================================ STATS ====================================
Me@50 19
Me@50 20 inline TSCount getTSCount()
Me@50 21 { unsigned int low, high;
Me@50 22 TSCount out;
Me@50 23
Me@50 24 saveTimeStampCountInto( low, high );
Me@50 25 out = high;
Me@50 26 out = (out << 32) + low;
Me@50 27 return out;
Me@50 28 }
Me@50 29
Me@50 30
Me@50 31
Me@50 32 //==================== Probes =================
Me@50 33 #ifdef STATS__USE_TSC_PROBES
Me@50 34
Me@50 35 int32
Me@50 36 VMS__create_histogram_probe( int32 numBins, float32 startValue,
Me@50 37 float32 binWidth, char *nameStr )
Me@50 38 { IntervalProbe *newProbe;
Me@50 39 int32 idx;
Me@50 40 FloatHist *hist;
Me@50 41
Me@50 42 idx = VMS__create_single_interval_probe( nameStr );
Me@50 43 newProbe = _VMSMasterEnv->intervalProbes[ idx ];
Me@50 44
Me@50 45 hist = makeFloatHistogram( numBins, startValue, binWidth );
Me@50 46 newProbe->hist = hist;
Me@50 47 return idx;
Me@50 48 }
Me@50 49
Me@50 50 void
Me@50 51 VMS_impl__record_interval_start_in_probe( int32 probeID )
Me@50 52 { IntervalProbe *probe;
Me@50 53
Me@50 54 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 55 probe->startStamp = getTSCount();
Me@50 56 }
Me@50 57
Me@50 58 void
Me@50 59 VMS_impl__record_interval_end_in_probe( int32 probeID )
Me@50 60 { IntervalProbe *probe;
Me@50 61 TSCount endStamp;
Me@50 62
Me@50 63 endStamp = getTSCount();
Me@50 64
Me@50 65 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 66 probe->endStamp = endStamp;
Me@50 67
Me@50 68 if( probe->hist != NULL )
Me@50 69 { TSCount interval = probe->endStamp - probe->startStamp;
Me@50 70 //if the interval is sane, then add to histogram
Me@50 71 if( interval < probe->hist->endOfRange * 10 )
Me@50 72 addToFloatHist( interval, probe->hist );
Me@50 73 }
Me@50 74 }
Me@50 75
Me@50 76 void
Me@50 77 VMS_impl__print_stats_of_probe( int32 probeID )
Me@50 78 { IntervalProbe *probe;
Me@50 79
Me@50 80 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 81
Me@50 82 if( probe->hist == NULL )
Me@50 83 {
Me@50 84 printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval);
Me@50 85 }
Me@50 86
Me@50 87 else
Me@50 88 {
Me@50 89 printf( "probe: %s\n", probe->nameStr );
Me@50 90 printFloatHist( probe->hist );
Me@50 91 }
Me@50 92 }
Me@50 93 #else
Me@50 94
Me@50 95 /*
Me@50 96 * In practice, probe operations are called from the app, from inside slaves
Me@50 97 * -- so have to be sure each probe is single-VP owned, and be sure that
Me@50 98 * any place common structures are modified it's done inside the master.
Me@50 99 * So -- the only place common structures are modified is during creation.
Me@50 100 * after that, all mods are to individual instances.
Me@50 101 *
Me@50 102 * Thniking perhaps should change the semantics to be that probes are
Me@50 103 * attached to the virtual processor -- and then everything is guaranteed
Me@50 104 * to be isolated -- except then can't take any intervals that span VPs,
Me@50 105 * and would have to transfer the probes to Master env when VP dissipates..
Me@50 106 * gets messy..
Me@50 107 *
Me@50 108 * For now, just making so that probe creation causes a suspend, so that
Me@50 109 * the dynamic array in the master env is only modified from the master
Me@50 110 *
Me@50 111 */
Me@50 112 IntervalProbe *
Me@50 113 create_generic_probe( char *nameStr, VirtProcr *animPr )
Me@50 114 { IntervalProbe *newProbe;
Me@50 115 VMSSemReq reqData;
Me@50 116
Me@50 117 reqData.reqType = createProbe;
Me@50 118 reqData.nameStr = nameStr;
Me@50 119
Me@52 120 VMS__send_VMSSem_request( &reqData, animPr );
Me@50 121
Me@53 122 return animPr->dataRetFromReq;
Me@50 123 }
Me@50 124
Me@52 125 /*Use this version from outside VMS -- it uses external malloc, and modifies
Me@52 126 * dynamic array, so can't be animated in a slave VP
Me@52 127 */
Me@52 128 IntervalProbe *
Me@52 129 ext__create_generic_probe( char *nameStr )
Me@52 130 { IntervalProbe *newProbe;
Me@52 131 int32 nameLen;
Me@52 132
Me@52 133 newProbe = malloc( sizeof(IntervalProbe) );
Me@52 134 nameLen = strlen( nameStr );
Me@52 135 newProbe->nameStr = malloc( nameLen );
Me@52 136 memcpy( newProbe->nameStr, nameStr, nameLen );
Me@52 137 newProbe->hist = NULL;
Me@52 138 newProbe->schedChoiceWasRecorded = FALSE;
Me@52 139 newProbe->probeID =
Me@52 140 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
Me@52 141
Me@52 142 return newProbe;
Me@52 143 }
Me@52 144
Me@53 145
Me@53 146 /*Only call from inside master or main startup/shutdown thread
Me@53 147 */
Me@53 148 void
Me@53 149 VMS_impl__free_probe( IntervalProbe *probe )
Me@53 150 { if( probe->hist != NULL ) freeDblHist( probe->hist );
Me@53 151 if( probe->nameStr != NULL) VMS__free( probe->nameStr );
Me@53 152 VMS__free( probe );
Me@53 153 }
Me@53 154
Me@53 155
Me@50 156 int32
Me@53 157 VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr)
Me@50 158 { IntervalProbe *newProbe;
Me@50 159 struct timeval *startStamp;
Me@50 160 float64 startSecs;
Me@50 161
Me@50 162 newProbe = create_generic_probe( nameStr, animPr );
Me@50 163 newProbe->endSecs = 0;
Me@50 164
Me@50 165 gettimeofday( &(newProbe->startStamp), NULL);
Me@50 166
Me@50 167 //turn into a double
Me@50 168 startStamp = &(newProbe->startStamp);
Me@50 169 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
Me@50 170 newProbe->startSecs = startSecs;
Me@50 171
Me@50 172 return newProbe->probeID;
Me@50 173 }
Me@50 174
Me@50 175 int32
Me@52 176 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
Me@52 177 { IntervalProbe *newProbe;
Me@52 178 struct timeval *startStamp;
Me@52 179 float64 startSecs;
Me@52 180
Me@52 181 newProbe = ext__create_generic_probe( nameStr );
Me@52 182 newProbe->endSecs = 0;
Me@52 183
Me@52 184 gettimeofday( &(newProbe->startStamp), NULL);
Me@52 185
Me@52 186 //turn into a double
Me@52 187 startStamp = &(newProbe->startStamp);
Me@52 188 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
Me@52 189 newProbe->startSecs = startSecs;
Me@52 190
Me@52 191 return newProbe->probeID;
Me@52 192 }
Me@52 193
Me@52 194 int32
Me@50 195 VMS_impl__create_single_interval_probe( char *nameStr, VirtProcr *animPr )
Me@50 196 { IntervalProbe *newProbe;
Me@50 197
Me@50 198 newProbe = create_generic_probe( nameStr, animPr );
Me@50 199
Me@50 200 return newProbe->probeID;
Me@50 201 }
Me@50 202
Me@50 203 int32
Me@50 204 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
Me@50 205 float64 binWidth, char *nameStr, VirtProcr *animPr )
Me@50 206 { IntervalProbe *newProbe;
Me@50 207 DblHist *hist;
Me@50 208
Me@50 209 newProbe = create_generic_probe( nameStr, animPr );
Me@50 210
Me@50 211 hist = makeDblHistogram( numBins, startValue, binWidth );
Me@50 212 newProbe->hist = hist;
Me@50 213 return newProbe->probeID;
Me@50 214 }
Me@50 215
Me@50 216 void
Me@50 217 VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr )
Me@50 218 { IntervalProbe *probe;
Me@50 219
Me@50 220 //TODO: fix this To be in Master -- race condition
Me@50 221 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 222
Me@50 223 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
Me@50 224 }
Me@50 225
Me@50 226 IntervalProbe *
Me@50 227 VMS_impl__get_probe_by_name( char *probeName, VirtProcr *animPr )
Me@50 228 {
Me@50 229 //TODO: fix this To be in Master -- race condition
Me@50 230 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
Me@50 231 }
Me@50 232
Me@50 233
Me@50 234 /*Everything is local to the animating procr, so no need for request, do
Me@50 235 * work locally, in the anim Pr
Me@50 236 */
Me@50 237 void
Me@50 238 VMS_impl__record_sched_choice_into_probe( int32 probeID, VirtProcr *animatingPr )
Me@50 239 { IntervalProbe *probe;
Me@50 240
Me@50 241 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 242 probe->schedChoiceWasRecorded = TRUE;
Me@50 243 probe->coreNum = animatingPr->coreAnimatedBy;
Me@50 244 probe->procrID = animatingPr->procrID;
Me@53 245 probe->procrCreateSecs = animatingPr->createPtInSecs;
Me@50 246 }
Me@50 247
Me@50 248 /*Everything is local to the animating procr, so no need for request, do
Me@50 249 * work locally, in the anim Pr
Me@50 250 */
Me@50 251 void
Me@50 252 VMS_impl__record_interval_start_in_probe( int32 probeID )
Me@50 253 { IntervalProbe *probe;
Me@50 254
Me@55 255 DEBUG( dbgProbes, "record start of interval\n" )
Me@50 256 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 257 gettimeofday( &(probe->startStamp), NULL );
Me@50 258 }
Me@50 259
Me@50 260
Me@50 261 /*Everything is local to the animating procr, so no need for request, do
Me@50 262 * work locally, in the anim Pr
Me@50 263 */
Me@50 264 void
Me@50 265 VMS_impl__record_interval_end_in_probe( int32 probeID )
Me@50 266 { IntervalProbe *probe;
Me@50 267 struct timeval *endStamp, *startStamp;
Me@54 268 float64 startSecs, endSecs;
Me@50 269
Me@55 270 DEBUG( dbgProbes, "record end of interval\n" )
Me@50 271 //possible seg-fault if array resized by diff core right after this
Me@50 272 // one gets probe..? Something like that? Might be safe.. don't care
Me@50 273 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 274 gettimeofday( &(probe->endStamp), NULL);
Me@50 275
Me@50 276 //now turn into an interval held in a double
Me@50 277 startStamp = &(probe->startStamp);
Me@50 278 endStamp = &(probe->endStamp);
Me@50 279
Me@50 280 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
Me@50 281 endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 );
Me@50 282
Me@50 283 probe->interval = endSecs - startSecs;
Me@50 284 probe->startSecs = startSecs;
Me@50 285 probe->endSecs = endSecs;
Me@50 286
Me@50 287 if( probe->hist != NULL )
Me@50 288 {
Me@50 289 //if the interval is sane, then add to histogram
Me@50 290 if( probe->interval < probe->hist->endOfRange * 10 )
Me@50 291 addToDblHist( probe->interval, probe->hist );
Me@50 292 }
Me@50 293 }
Me@50 294
Me@50 295 void
Me@50 296 print_probe_helper( IntervalProbe *probe )
Me@50 297 {
Me@50 298 printf( "\nprobe: %s, ", probe->nameStr );
Me@50 299
Me@50 300 if( probe->schedChoiceWasRecorded )
Me@50 301 { printf( "coreNum: %d, procrID: %d, procrCreated: %.6lf | ",
Me@50 302 probe->coreNum, probe->procrID, probe->procrCreateSecs );
Me@50 303 }
Me@50 304
Me@50 305 if( probe->endSecs == 0 ) //just a single point in time
Me@50 306 {
Me@50 307 printf( " time point: %.6lf\n",
Me@50 308 probe->startSecs - _VMSMasterEnv->createPtInSecs );
Me@50 309 }
Me@50 310 else if( probe->hist == NULL ) //just an interval
Me@50 311 {
Me@50 312 printf( " startSecs: %.6lf, interval: %.6lf\n",
Me@50 313 probe->startSecs - _VMSMasterEnv->createPtInSecs, probe->interval);
Me@50 314 }
Me@50 315 else //a full histogram of intervals
Me@50 316 {
Me@50 317 printDblHist( probe->hist );
Me@50 318 }
Me@50 319 }
Me@50 320
Me@50 321 //TODO: change so pass around pointer to probe instead of its array-index..
Me@50 322 // will eliminate chance for timing of resize to cause problems with the
Me@50 323 // lookup -- even though don't think it actually can cause problems..
Me@50 324 // there's no need to pass index around -- have hash table for names, and
Me@50 325 // only need it once, then have ptr to probe.. the thing about enum the
Me@50 326 // index and use that as name is clunky in practice -- just hash.
Me@50 327 void
Me@50 328 VMS_impl__print_stats_of_probe( int32 probeID )
Me@50 329 { IntervalProbe *probe;
Me@50 330
Me@50 331 probe = _VMSMasterEnv->intervalProbes[ probeID ];
Me@50 332
Me@50 333 print_probe_helper( probe );
Me@50 334 }
Me@50 335
Me@50 336
Me@50 337
Me@50 338 void
Me@50 339 generic_print_probe( void *_probe )
Me@50 340 { IntervalProbe *probe;
Me@50 341
Me@50 342 probe = (IntervalProbe *)_probe;
Me@50 343 print_probe_helper( probe );
Me@50 344 }
Me@50 345
Me@50 346 void
Me@50 347 VMS_impl__print_stats_of_all_probes()
Me@50 348 { IntervalProbe *probe;
Me@50 349
Me@50 350 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
Me@50 351 &generic_print_probe );
Me@50 352 fflush( stdout );
Me@50 353 }
Me@50 354 #endif