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