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