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