annotate probes.c @ 135:0b49fd35afc1

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