annotate probes.c @ 51:2952d337d6f3

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