Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff probes.c @ 61:984f7d78bfdf
Merge See what happens -- merged test stuff into Nov 8 VMS version
| author | SeanHalle |
|---|---|
| date | Thu, 11 Nov 2010 06:19:51 -0800 |
| parents | 3bac84e4e56e |
| children | a6c442d52590 13b22ffb8a2f |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/probes.c Thu Nov 11 06:19:51 2010 -0800 1.3 @@ -0,0 +1,354 @@ 1.4 +/* 1.5 + * Copyright 2010 OpenSourceStewardshipFoundation 1.6 + * 1.7 + * Licensed under BSD 1.8 + */ 1.9 + 1.10 +#include <stdio.h> 1.11 +#include <stdlib.h> 1.12 +#include <malloc.h> 1.13 +#include <sys/time.h> 1.14 +#include <string.h> 1.15 + 1.16 +#include "VMS.h" 1.17 +#include "Queue_impl/BlockingQueue.h" 1.18 +#include "Histogram/Histogram.h" 1.19 + 1.20 + 1.21 +//================================ STATS ==================================== 1.22 + 1.23 +inline TSCount getTSCount() 1.24 + { unsigned int low, high; 1.25 + TSCount out; 1.26 + 1.27 + saveTimeStampCountInto( low, high ); 1.28 + out = high; 1.29 + out = (out << 32) + low; 1.30 + return out; 1.31 + } 1.32 + 1.33 + 1.34 + 1.35 +//==================== Probes ================= 1.36 +#ifdef STATS__USE_TSC_PROBES 1.37 + 1.38 +int32 1.39 +VMS__create_histogram_probe( int32 numBins, float32 startValue, 1.40 + float32 binWidth, char *nameStr ) 1.41 + { IntervalProbe *newProbe; 1.42 + int32 idx; 1.43 + FloatHist *hist; 1.44 + 1.45 + idx = VMS__create_single_interval_probe( nameStr ); 1.46 + newProbe = _VMSMasterEnv->intervalProbes[ idx ]; 1.47 + 1.48 + hist = makeFloatHistogram( numBins, startValue, binWidth ); 1.49 + newProbe->hist = hist; 1.50 + return idx; 1.51 + } 1.52 + 1.53 +void 1.54 +VMS_impl__record_interval_start_in_probe( int32 probeID ) 1.55 + { IntervalProbe *probe; 1.56 + 1.57 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.58 + probe->startStamp = getTSCount(); 1.59 + } 1.60 + 1.61 +void 1.62 +VMS_impl__record_interval_end_in_probe( int32 probeID ) 1.63 + { IntervalProbe *probe; 1.64 + TSCount endStamp; 1.65 + 1.66 + endStamp = getTSCount(); 1.67 + 1.68 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.69 + probe->endStamp = endStamp; 1.70 + 1.71 + if( probe->hist != NULL ) 1.72 + { TSCount interval = probe->endStamp - probe->startStamp; 1.73 + //if the interval is sane, then add to histogram 1.74 + if( interval < probe->hist->endOfRange * 10 ) 1.75 + addToFloatHist( interval, probe->hist ); 1.76 + } 1.77 + } 1.78 + 1.79 +void 1.80 +VMS_impl__print_stats_of_probe( int32 probeID ) 1.81 + { IntervalProbe *probe; 1.82 + 1.83 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.84 + 1.85 + if( probe->hist == NULL ) 1.86 + { 1.87 + printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval); 1.88 + } 1.89 + 1.90 + else 1.91 + { 1.92 + printf( "probe: %s\n", probe->nameStr ); 1.93 + printFloatHist( probe->hist ); 1.94 + } 1.95 + } 1.96 +#else 1.97 + 1.98 +/* 1.99 + * In practice, probe operations are called from the app, from inside slaves 1.100 + * -- so have to be sure each probe is single-VP owned, and be sure that 1.101 + * any place common structures are modified it's done inside the master. 1.102 + * So -- the only place common structures are modified is during creation. 1.103 + * after that, all mods are to individual instances. 1.104 + * 1.105 + * Thniking perhaps should change the semantics to be that probes are 1.106 + * attached to the virtual processor -- and then everything is guaranteed 1.107 + * to be isolated -- except then can't take any intervals that span VPs, 1.108 + * and would have to transfer the probes to Master env when VP dissipates.. 1.109 + * gets messy.. 1.110 + * 1.111 + * For now, just making so that probe creation causes a suspend, so that 1.112 + * the dynamic array in the master env is only modified from the master 1.113 + * 1.114 + */ 1.115 +IntervalProbe * 1.116 +create_generic_probe( char *nameStr, VirtProcr *animPr ) 1.117 + { IntervalProbe *newProbe; 1.118 + VMSSemReq reqData; 1.119 + 1.120 + reqData.reqType = createProbe; 1.121 + reqData.nameStr = nameStr; 1.122 + 1.123 + VMS__send_VMSSem_request( &reqData, animPr ); 1.124 + 1.125 + return animPr->dataRetFromReq; 1.126 + } 1.127 + 1.128 +/*Use this version from outside VMS -- it uses external malloc, and modifies 1.129 + * dynamic array, so can't be animated in a slave VP 1.130 + */ 1.131 +IntervalProbe * 1.132 +ext__create_generic_probe( char *nameStr ) 1.133 + { IntervalProbe *newProbe; 1.134 + int32 nameLen; 1.135 + 1.136 + newProbe = malloc( sizeof(IntervalProbe) ); 1.137 + nameLen = strlen( nameStr ); 1.138 + newProbe->nameStr = malloc( nameLen ); 1.139 + memcpy( newProbe->nameStr, nameStr, nameLen ); 1.140 + newProbe->hist = NULL; 1.141 + newProbe->schedChoiceWasRecorded = FALSE; 1.142 + newProbe->probeID = 1.143 + addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); 1.144 + 1.145 + return newProbe; 1.146 + } 1.147 + 1.148 + 1.149 +/*Only call from inside master or main startup/shutdown thread 1.150 + */ 1.151 +void 1.152 +VMS_impl__free_probe( IntervalProbe *probe ) 1.153 + { if( probe->hist != NULL ) freeDblHist( probe->hist ); 1.154 + if( probe->nameStr != NULL) VMS__free( probe->nameStr ); 1.155 + VMS__free( probe ); 1.156 + } 1.157 + 1.158 + 1.159 +int32 1.160 +VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr) 1.161 + { IntervalProbe *newProbe; 1.162 + struct timeval *startStamp; 1.163 + float64 startSecs; 1.164 + 1.165 + newProbe = create_generic_probe( nameStr, animPr ); 1.166 + newProbe->endSecs = 0; 1.167 + 1.168 + gettimeofday( &(newProbe->startStamp), NULL); 1.169 + 1.170 + //turn into a double 1.171 + startStamp = &(newProbe->startStamp); 1.172 + startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); 1.173 + newProbe->startSecs = startSecs; 1.174 + 1.175 + return newProbe->probeID; 1.176 + } 1.177 + 1.178 +int32 1.179 +VMS_ext_impl__record_time_point_into_new_probe( char *nameStr ) 1.180 + { IntervalProbe *newProbe; 1.181 + struct timeval *startStamp; 1.182 + float64 startSecs; 1.183 + 1.184 + newProbe = ext__create_generic_probe( nameStr ); 1.185 + newProbe->endSecs = 0; 1.186 + 1.187 + gettimeofday( &(newProbe->startStamp), NULL); 1.188 + 1.189 + //turn into a double 1.190 + startStamp = &(newProbe->startStamp); 1.191 + startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); 1.192 + newProbe->startSecs = startSecs; 1.193 + 1.194 + return newProbe->probeID; 1.195 + } 1.196 + 1.197 +int32 1.198 +VMS_impl__create_single_interval_probe( char *nameStr, VirtProcr *animPr ) 1.199 + { IntervalProbe *newProbe; 1.200 + 1.201 + newProbe = create_generic_probe( nameStr, animPr ); 1.202 + 1.203 + return newProbe->probeID; 1.204 + } 1.205 + 1.206 +int32 1.207 +VMS_impl__create_histogram_probe( int32 numBins, float64 startValue, 1.208 + float64 binWidth, char *nameStr, VirtProcr *animPr ) 1.209 + { IntervalProbe *newProbe; 1.210 + DblHist *hist; 1.211 + 1.212 + newProbe = create_generic_probe( nameStr, animPr ); 1.213 + 1.214 + hist = makeDblHistogram( numBins, startValue, binWidth ); 1.215 + newProbe->hist = hist; 1.216 + return newProbe->probeID; 1.217 + } 1.218 + 1.219 +void 1.220 +VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr ) 1.221 + { IntervalProbe *probe; 1.222 + 1.223 + //TODO: fix this To be in Master -- race condition 1.224 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.225 + 1.226 + addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl); 1.227 + } 1.228 + 1.229 +IntervalProbe * 1.230 +VMS_impl__get_probe_by_name( char *probeName, VirtProcr *animPr ) 1.231 + { 1.232 + //TODO: fix this To be in Master -- race condition 1.233 + return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl ); 1.234 + } 1.235 + 1.236 + 1.237 +/*Everything is local to the animating procr, so no need for request, do 1.238 + * work locally, in the anim Pr 1.239 + */ 1.240 +void 1.241 +VMS_impl__record_sched_choice_into_probe( int32 probeID, VirtProcr *animatingPr ) 1.242 + { IntervalProbe *probe; 1.243 + 1.244 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.245 + probe->schedChoiceWasRecorded = TRUE; 1.246 + probe->coreNum = animatingPr->coreAnimatedBy; 1.247 + probe->procrID = animatingPr->procrID; 1.248 + probe->procrCreateSecs = animatingPr->createPtInSecs; 1.249 + } 1.250 + 1.251 +/*Everything is local to the animating procr, so no need for request, do 1.252 + * work locally, in the anim Pr 1.253 + */ 1.254 +void 1.255 +VMS_impl__record_interval_start_in_probe( int32 probeID ) 1.256 + { IntervalProbe *probe; 1.257 + 1.258 + DEBUG( dbgProbes, "record start of interval\n" ) 1.259 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.260 + gettimeofday( &(probe->startStamp), NULL ); 1.261 + } 1.262 + 1.263 + 1.264 +/*Everything is local to the animating procr, so no need for request, do 1.265 + * work locally, in the anim Pr 1.266 + */ 1.267 +void 1.268 +VMS_impl__record_interval_end_in_probe( int32 probeID ) 1.269 + { IntervalProbe *probe; 1.270 + struct timeval *endStamp, *startStamp; 1.271 + float64 startSecs, endSecs; 1.272 + 1.273 + DEBUG( dbgProbes, "record end of interval\n" ) 1.274 + //possible seg-fault if array resized by diff core right after this 1.275 + // one gets probe..? Something like that? Might be safe.. don't care 1.276 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.277 + gettimeofday( &(probe->endStamp), NULL); 1.278 + 1.279 + //now turn into an interval held in a double 1.280 + startStamp = &(probe->startStamp); 1.281 + endStamp = &(probe->endStamp); 1.282 + 1.283 + startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); 1.284 + endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 ); 1.285 + 1.286 + probe->interval = endSecs - startSecs; 1.287 + probe->startSecs = startSecs; 1.288 + probe->endSecs = endSecs; 1.289 + 1.290 + if( probe->hist != NULL ) 1.291 + { 1.292 + //if the interval is sane, then add to histogram 1.293 + if( probe->interval < probe->hist->endOfRange * 10 ) 1.294 + addToDblHist( probe->interval, probe->hist ); 1.295 + } 1.296 + } 1.297 + 1.298 +void 1.299 +print_probe_helper( IntervalProbe *probe ) 1.300 + { 1.301 + printf( "\nprobe: %s, ", probe->nameStr ); 1.302 + 1.303 + if( probe->schedChoiceWasRecorded ) 1.304 + { printf( "coreNum: %d, procrID: %d, procrCreated: %.6lf | ", 1.305 + probe->coreNum, probe->procrID, probe->procrCreateSecs ); 1.306 + } 1.307 + 1.308 + if( probe->endSecs == 0 ) //just a single point in time 1.309 + { 1.310 + printf( " time point: %.6lf\n", 1.311 + probe->startSecs - _VMSMasterEnv->createPtInSecs ); 1.312 + } 1.313 + else if( probe->hist == NULL ) //just an interval 1.314 + { 1.315 + printf( " startSecs: %.6lf, interval: %.6lf\n", 1.316 + probe->startSecs - _VMSMasterEnv->createPtInSecs, probe->interval); 1.317 + } 1.318 + else //a full histogram of intervals 1.319 + { 1.320 + printDblHist( probe->hist ); 1.321 + } 1.322 + } 1.323 + 1.324 +//TODO: change so pass around pointer to probe instead of its array-index.. 1.325 +// will eliminate chance for timing of resize to cause problems with the 1.326 +// lookup -- even though don't think it actually can cause problems.. 1.327 +// there's no need to pass index around -- have hash table for names, and 1.328 +// only need it once, then have ptr to probe.. the thing about enum the 1.329 +// index and use that as name is clunky in practice -- just hash. 1.330 +void 1.331 +VMS_impl__print_stats_of_probe( int32 probeID ) 1.332 + { IntervalProbe *probe; 1.333 + 1.334 + probe = _VMSMasterEnv->intervalProbes[ probeID ]; 1.335 + 1.336 + print_probe_helper( probe ); 1.337 + } 1.338 + 1.339 + 1.340 + 1.341 +void 1.342 +generic_print_probe( void *_probe ) 1.343 + { IntervalProbe *probe; 1.344 + 1.345 + probe = (IntervalProbe *)_probe; 1.346 + print_probe_helper( probe ); 1.347 + } 1.348 + 1.349 +void 1.350 +VMS_impl__print_stats_of_all_probes() 1.351 + { IntervalProbe *probe; 1.352 + 1.353 + forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo, 1.354 + &generic_print_probe ); 1.355 + fflush( stdout ); 1.356 + } 1.357 +#endif
