Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view probes.c @ 52:f59cfa31a579
fixed up probes just a bit
| author | Me |
|---|---|
| date | Sat, 30 Oct 2010 21:53:55 -0700 |
| parents | 8f7141a9272e |
| children | 42dd44df1bb0 |
line source
1 /*
2 * Copyright 2010 OpenSourceStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <malloc.h>
10 #include <sys/time.h>
11 #include <string.h>
13 #include "VMS.h"
14 #include "Queue_impl/BlockingQueue.h"
15 #include "Histogram/Histogram.h"
18 //================================ STATS ====================================
20 inline TSCount getTSCount()
21 { unsigned int low, high;
22 TSCount out;
24 saveTimeStampCountInto( low, high );
25 out = high;
26 out = (out << 32) + low;
27 return out;
28 }
32 //==================== Probes =================
33 #ifdef STATS__USE_TSC_PROBES
34 int32
35 VMS__create_single_interval_probe( char *nameStr )
36 { IntervalProbe *newProbe;
37 int32 idx;
39 newProbe = malloc( sizeof(IntervalProbe) );
40 newProbe->nameStr = nameStr; //caller frees if not constant on stack
41 newProbe->hist = NULL;
42 idx = addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
43 return idx;
44 }
46 int32
47 VMS__create_histogram_probe( int32 numBins, float32 startValue,
48 float32 binWidth, char *nameStr )
49 { IntervalProbe *newProbe;
50 int32 idx;
51 FloatHist *hist;
53 idx = VMS__create_single_interval_probe( nameStr );
54 newProbe = _VMSMasterEnv->intervalProbes[ idx ];
56 hist = makeFloatHistogram( numBins, startValue, binWidth );
57 newProbe->hist = hist;
58 return idx;
59 }
61 void
62 VMS_impl__record_interval_start_in_probe( int32 probeID )
63 { IntervalProbe *probe;
65 probe = _VMSMasterEnv->intervalProbes[ probeID ];
66 probe->startStamp = getTSCount();
67 }
69 void
70 VMS_impl__record_interval_end_in_probe( int32 probeID )
71 { IntervalProbe *probe;
72 TSCount endStamp;
74 endStamp = getTSCount();
76 probe = _VMSMasterEnv->intervalProbes[ probeID ];
77 probe->endStamp = endStamp;
79 if( probe->hist != NULL )
80 { TSCount interval = probe->endStamp - probe->startStamp;
81 //if the interval is sane, then add to histogram
82 if( interval < probe->hist->endOfRange * 10 )
83 addToFloatHist( interval, probe->hist );
84 }
85 }
87 void
88 VMS_impl__print_stats_of_probe( int32 probeID )
89 { IntervalProbe *probe;
91 probe = _VMSMasterEnv->intervalProbes[ probeID ];
93 if( probe->hist == NULL )
94 {
95 printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval);
96 }
98 else
99 {
100 printf( "probe: %s\n", probe->nameStr );
101 printFloatHist( probe->hist );
102 }
103 }
104 #else
105 #ifdef STATS__USE_DBL_PROBES
107 /*
108 * In practice, probe operations are called from the app, from inside slaves
109 * -- so have to be sure each probe is single-VP owned, and be sure that
110 * any place common structures are modified it's done inside the master.
111 * So -- the only place common structures are modified is during creation.
112 * after that, all mods are to individual instances.
113 *
114 * Thniking perhaps should change the semantics to be that probes are
115 * attached to the virtual processor -- and then everything is guaranteed
116 * to be isolated -- except then can't take any intervals that span VPs,
117 * and would have to transfer the probes to Master env when VP dissipates..
118 * gets messy..
119 *
120 * For now, just making so that probe creation causes a suspend, so that
121 * the dynamic array in the master env is only modified from the master
122 *
123 */
124 IntervalProbe *
125 create_generic_probe( char *nameStr, VirtProcr *animPr )
126 { IntervalProbe *newProbe;
127 VMSSemReq reqData;
129 reqData.reqType = createProbe;
130 reqData.nameStr = nameStr;
132 VMS__send_VMSSem_request( &reqData, animPr );
134 return animPr->dataReturnedFromReq;
135 }
137 /*Use this version from outside VMS -- it uses external malloc, and modifies
138 * dynamic array, so can't be animated in a slave VP
139 */
140 IntervalProbe *
141 ext__create_generic_probe( char *nameStr )
142 { IntervalProbe *newProbe;
143 int32 nameLen;
145 newProbe = malloc( sizeof(IntervalProbe) );
146 nameLen = strlen( nameStr );
147 newProbe->nameStr = malloc( nameLen );
148 memcpy( newProbe->nameStr, nameStr, nameLen );
149 newProbe->hist = NULL;
150 newProbe->schedChoiceWasRecorded = FALSE;
151 newProbe->probeID =
152 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
154 return newProbe;
155 }
157 int32
158 VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr )
159 { IntervalProbe *newProbe;
160 struct timeval *startStamp;
161 float64 startSecs;
163 newProbe = create_generic_probe( nameStr, animPr );
164 newProbe->endSecs = 0;
166 gettimeofday( &(newProbe->startStamp), NULL);
168 //turn into a double
169 startStamp = &(newProbe->startStamp);
170 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
171 newProbe->startSecs = startSecs;
173 return newProbe->probeID;
174 }
176 int32
177 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
178 { IntervalProbe *newProbe;
179 struct timeval *startStamp;
180 float64 startSecs;
182 newProbe = ext__create_generic_probe( nameStr );
183 newProbe->endSecs = 0;
185 gettimeofday( &(newProbe->startStamp), NULL);
187 //turn into a double
188 startStamp = &(newProbe->startStamp);
189 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
190 newProbe->startSecs = startSecs;
192 return newProbe->probeID;
193 }
195 int32
196 VMS_impl__create_single_interval_probe( char *nameStr, VirtProcr *animPr )
197 { IntervalProbe *newProbe;
199 newProbe = create_generic_probe( nameStr, animPr );
201 return newProbe->probeID;
202 }
204 int32
205 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
206 float64 binWidth, char *nameStr, VirtProcr *animPr )
207 { IntervalProbe *newProbe;
208 DblHist *hist;
210 newProbe = create_generic_probe( nameStr, animPr );
212 hist = makeDblHistogram( numBins, startValue, binWidth );
213 newProbe->hist = hist;
214 return newProbe->probeID;
215 }
217 void
218 VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr )
219 { IntervalProbe *probe;
221 //TODO: fix this To be in Master -- race condition
222 probe = _VMSMasterEnv->intervalProbes[ probeID ];
224 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
225 }
227 IntervalProbe *
228 VMS_impl__get_probe_by_name( char *probeName, VirtProcr *animPr )
229 {
230 //TODO: fix this To be in Master -- race condition
231 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
232 }
235 /*Everything is local to the animating procr, so no need for request, do
236 * work locally, in the anim Pr
237 */
238 void
239 VMS_impl__record_sched_choice_into_probe( int32 probeID, VirtProcr *animatingPr )
240 { IntervalProbe *probe;
242 probe = _VMSMasterEnv->intervalProbes[ probeID ];
243 probe->schedChoiceWasRecorded = TRUE;
244 probe->coreNum = animatingPr->coreAnimatedBy;
245 probe->procrID = animatingPr->procrID;
246 probe->procrCreateSecs = 0;
247 }
249 /*Everything is local to the animating procr, so no need for request, do
250 * work locally, in the anim Pr
251 */
252 void
253 VMS_impl__record_interval_start_in_probe( int32 probeID )
254 { IntervalProbe *probe;
256 probe = _VMSMasterEnv->intervalProbes[ probeID ];
257 gettimeofday( &(probe->startStamp), NULL );
258 }
261 /*Everything is local to the animating procr, so no need for request, do
262 * work locally, in the anim Pr
263 */
264 void
265 VMS_impl__record_interval_end_in_probe( int32 probeID )
266 { IntervalProbe *probe;
267 struct timeval *endStamp, *startStamp;
268 double startSecs, endSecs;
270 //possible seg-fault if array resized by diff core right after this
271 // one gets probe..? Something like that? Might be safe.. don't care
272 probe = _VMSMasterEnv->intervalProbes[ probeID ];
273 gettimeofday( &(probe->endStamp), NULL);
275 //now turn into an interval held in a double
276 startStamp = &(probe->startStamp);
277 endStamp = &(probe->endStamp);
279 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
280 endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 );
282 probe->interval = endSecs - startSecs;
283 probe->startSecs = startSecs;
284 probe->endSecs = endSecs;
286 if( probe->hist != NULL )
287 {
288 //if the interval is sane, then add to histogram
289 if( probe->interval < probe->hist->endOfRange * 10 )
290 addToDblHist( probe->interval, probe->hist );
291 }
292 }
294 void
295 print_probe_helper( IntervalProbe *probe )
296 {
297 printf( "\nprobe: %s, ", probe->nameStr );
299 if( probe->schedChoiceWasRecorded )
300 { printf( "coreNum: %d, procrID: %d, procrCreated: %.6lf | ",
301 probe->coreNum, probe->procrID, probe->procrCreateSecs );
302 }
304 if( probe->endSecs == 0 ) //just a single point in time
305 {
306 printf( " time point: %.6lf\n",
307 probe->startSecs - _VMSMasterEnv->createPtInSecs );
308 }
309 else if( probe->hist == NULL ) //just an interval
310 {
311 printf( " startSecs: %.6lf, interval: %.6lf\n",
312 probe->startSecs - _VMSMasterEnv->createPtInSecs, probe->interval);
313 }
314 else //a full histogram of intervals
315 {
316 printDblHist( probe->hist );
317 }
318 }
320 //TODO: change so pass around pointer to probe instead of its array-index..
321 // will eliminate chance for timing of resize to cause problems with the
322 // lookup -- even though don't think it actually can cause problems..
323 // there's no need to pass index around -- have hash table for names, and
324 // only need it once, then have ptr to probe.. the thing about enum the
325 // index and use that as name is clunky in practice -- just hash.
326 void
327 VMS_impl__print_stats_of_probe( int32 probeID )
328 { IntervalProbe *probe;
330 probe = _VMSMasterEnv->intervalProbes[ probeID ];
332 print_probe_helper( probe );
333 }
337 void
338 generic_print_probe( void *_probe )
339 { IntervalProbe *probe;
341 probe = (IntervalProbe *)_probe;
342 print_probe_helper( probe );
343 }
345 void
346 VMS_impl__print_stats_of_all_probes()
347 { IntervalProbe *probe;
349 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
350 &generic_print_probe );
351 fflush( stdout );
352 }
353 #endif
354 #endif
356 /* Junk left over from when trying the different ways to get time stamps..
357 struct timeval tim;
358 gettimeofday(&tim, NULL);
359 double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
361 clock_t startClockStamp = clock();
363 TSCount startMultStamp = getTSCount();
364 */
366 /*
367 TSCount endMultStamp = getTSCount();
369 dividerParams->numTSCsToExe = endMultStamp - startMultStamp;
370 printf("\ntime to execute: %d\n", endMultStamp - startMultStamp);
372 //==================================================================
373 clock_t endClockStamp = clock();
374 printf("%.4lf seconds of processing\n",
375 (endClockStamp - startClockStamp)/(double)CLOCKS_PER_SEC);
377 //==================================================================
378 gettimeofday(&tim, NULL);
379 double t2=tim.tv_sec+(tim.tv_usec/1000000.0);
380 printf("%.6lf seconds elapsed\n", t2-t1);
381 */
