annotate probes.c @ 200:6db9e4898978

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