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