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