Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view probes.c @ 67:2377967a2732
Fixed sequential coreLoop, where switchVPs was broken
| author | Me |
|---|---|
| date | Tue, 16 Nov 2010 16:00:32 +0100 |
| parents | 7b799a46cc87 |
| children | 9ddbb071142d |
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
35 int32
36 VMS__create_histogram_probe( int32 numBins, float32 startValue,
37 float32 binWidth, char *nameStr )
38 { IntervalProbe *newProbe;
39 int32 idx;
40 FloatHist *hist;
42 idx = VMS__create_single_interval_probe( nameStr );
43 newProbe = _VMSMasterEnv->intervalProbes[ idx ];
45 hist = makeFloatHistogram( numBins, startValue, binWidth );
46 newProbe->hist = hist;
47 return idx;
48 }
50 void
51 VMS_impl__record_interval_start_in_probe( int32 probeID )
52 { IntervalProbe *probe;
54 probe = _VMSMasterEnv->intervalProbes[ probeID ];
55 probe->startStamp = getTSCount();
56 }
58 void
59 VMS_impl__record_interval_end_in_probe( int32 probeID )
60 { IntervalProbe *probe;
61 TSCount endStamp;
63 endStamp = getTSCount();
65 probe = _VMSMasterEnv->intervalProbes[ probeID ];
66 probe->endStamp = endStamp;
68 if( probe->hist != NULL )
69 { TSCount interval = probe->endStamp - probe->startStamp;
70 //if the interval is sane, then add to histogram
71 if( interval < probe->hist->endOfRange * 10 )
72 addToFloatHist( interval, probe->hist );
73 }
74 }
76 void
77 VMS_impl__print_stats_of_probe( int32 probeID )
78 { IntervalProbe *probe;
80 probe = _VMSMasterEnv->intervalProbes[ probeID ];
82 if( probe->hist == NULL )
83 {
84 printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval);
85 }
87 else
88 {
89 printf( "probe: %s\n", probe->nameStr );
90 printFloatHist( probe->hist );
91 }
92 }
93 #else
95 /*
96 * In practice, probe operations are called from the app, from inside slaves
97 * -- so have to be sure each probe is single-VP owned, and be sure that
98 * any place common structures are modified it's done inside the master.
99 * So -- the only place common structures are modified is during creation.
100 * after that, all mods are to individual instances.
101 *
102 * Thniking perhaps should change the semantics to be that probes are
103 * attached to the virtual processor -- and then everything is guaranteed
104 * to be isolated -- except then can't take any intervals that span VPs,
105 * and would have to transfer the probes to Master env when VP dissipates..
106 * gets messy..
107 *
108 * For now, just making so that probe creation causes a suspend, so that
109 * the dynamic array in the master env is only modified from the master
110 *
111 */
112 IntervalProbe *
113 create_generic_probe( char *nameStr, VirtProcr *animPr )
114 { IntervalProbe *newProbe;
115 VMSSemReq reqData;
117 reqData.reqType = createProbe;
118 reqData.nameStr = nameStr;
120 VMS__send_VMSSem_request( &reqData, animPr );
122 return animPr->dataRetFromReq;
123 }
125 /*Use this version from outside VMS -- it uses external malloc, and modifies
126 * dynamic array, so can't be animated in a slave VP
127 */
128 IntervalProbe *
129 ext__create_generic_probe( char *nameStr )
130 { IntervalProbe *newProbe;
131 int32 nameLen;
133 newProbe = malloc( sizeof(IntervalProbe) );
134 nameLen = strlen( nameStr );
135 newProbe->nameStr = malloc( nameLen );
136 memcpy( newProbe->nameStr, nameStr, nameLen );
137 newProbe->hist = NULL;
138 newProbe->schedChoiceWasRecorded = FALSE;
139 newProbe->probeID =
140 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
142 return newProbe;
143 }
146 /*Only call from inside master or main startup/shutdown thread
147 */
148 void
149 VMS_impl__free_probe( IntervalProbe *probe )
150 { if( probe->hist != NULL ) freeDblHist( probe->hist );
151 if( probe->nameStr != NULL) VMS__free( probe->nameStr );
152 VMS__free( probe );
153 }
156 int32
157 VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr)
158 { IntervalProbe *newProbe;
159 struct timeval *startStamp;
160 float64 startSecs;
162 newProbe = create_generic_probe( nameStr, animPr );
163 newProbe->endSecs = 0;
165 gettimeofday( &(newProbe->startStamp), NULL);
167 //turn into a double
168 startStamp = &(newProbe->startStamp);
169 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
170 newProbe->startSecs = startSecs;
172 return newProbe->probeID;
173 }
175 int32
176 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
177 { IntervalProbe *newProbe;
178 struct timeval *startStamp;
179 float64 startSecs;
181 newProbe = ext__create_generic_probe( nameStr );
182 newProbe->endSecs = 0;
184 gettimeofday( &(newProbe->startStamp), NULL);
186 //turn into a double
187 startStamp = &(newProbe->startStamp);
188 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
189 newProbe->startSecs = startSecs;
191 return newProbe->probeID;
192 }
194 int32
195 VMS_impl__create_single_interval_probe( char *nameStr, VirtProcr *animPr )
196 { IntervalProbe *newProbe;
198 newProbe = create_generic_probe( nameStr, animPr );
200 return newProbe->probeID;
201 }
203 int32
204 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
205 float64 binWidth, char *nameStr, VirtProcr *animPr )
206 { IntervalProbe *newProbe;
207 DblHist *hist;
209 newProbe = create_generic_probe( nameStr, animPr );
211 hist = makeDblHistogram( numBins, startValue, binWidth );
212 newProbe->hist = hist;
213 return newProbe->probeID;
214 }
216 void
217 VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr )
218 { IntervalProbe *probe;
220 //TODO: fix this To be in Master -- race condition
221 probe = _VMSMasterEnv->intervalProbes[ probeID ];
223 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
224 }
226 IntervalProbe *
227 VMS_impl__get_probe_by_name( char *probeName, VirtProcr *animPr )
228 {
229 //TODO: fix this To be in Master -- race condition
230 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
231 }
234 /*Everything is local to the animating procr, so no need for request, do
235 * work locally, in the anim Pr
236 */
237 void
238 VMS_impl__record_sched_choice_into_probe( int32 probeID, VirtProcr *animatingPr )
239 { IntervalProbe *probe;
241 probe = _VMSMasterEnv->intervalProbes[ probeID ];
242 probe->schedChoiceWasRecorded = TRUE;
243 probe->coreNum = animatingPr->coreAnimatedBy;
244 probe->procrID = animatingPr->procrID;
245 probe->procrCreateSecs = animatingPr->createPtInSecs;
246 }
248 /*Everything is local to the animating procr, so no need for request, do
249 * work locally, in the anim Pr
250 */
251 void
252 VMS_impl__record_interval_start_in_probe( int32 probeID )
253 { IntervalProbe *probe;
255 DEBUG( dbgProbes, "record start of interval\n" )
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 float64 startSecs, endSecs;
270 DEBUG( dbgProbes, "record end of interval\n" )
271 //possible seg-fault if array resized by diff core right after this
272 // one gets probe..? Something like that? Might be safe.. don't care
273 probe = _VMSMasterEnv->intervalProbes[ probeID ];
274 gettimeofday( &(probe->endStamp), NULL);
276 //now turn into an interval held in a double
277 startStamp = &(probe->startStamp);
278 endStamp = &(probe->endStamp);
280 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
281 endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 );
283 probe->interval = endSecs - startSecs;
284 probe->startSecs = startSecs;
285 probe->endSecs = endSecs;
287 if( probe->hist != NULL )
288 {
289 //if the interval is sane, then add to histogram
290 if( probe->interval < probe->hist->endOfRange * 10 )
291 addToDblHist( probe->interval, probe->hist );
292 }
293 }
295 void
296 print_probe_helper( IntervalProbe *probe )
297 {
298 printf( "\nprobe: %s, ", probe->nameStr );
300 if( probe->schedChoiceWasRecorded )
301 { printf( "coreNum: %d, procrID: %d, procrCreated: %.6lf | ",
302 probe->coreNum, probe->procrID, probe->procrCreateSecs );
303 }
305 if( probe->endSecs == 0 ) //just a single point in time
306 {
307 printf( " time point: %.6lf\n",
308 probe->startSecs - _VMSMasterEnv->createPtInSecs );
309 }
310 else if( probe->hist == NULL ) //just an interval
311 {
312 printf( " startSecs: %.6lf, interval: %.6lf\n",
313 probe->startSecs - _VMSMasterEnv->createPtInSecs, probe->interval);
314 }
315 else //a full histogram of intervals
316 {
317 printDblHist( probe->hist );
318 }
319 }
321 //TODO: change so pass around pointer to probe instead of its array-index..
322 // will eliminate chance for timing of resize to cause problems with the
323 // lookup -- even though don't think it actually can cause problems..
324 // there's no need to pass index around -- have hash table for names, and
325 // only need it once, then have ptr to probe.. the thing about enum the
326 // index and use that as name is clunky in practice -- just hash.
327 void
328 VMS_impl__print_stats_of_probe( int32 probeID )
329 { IntervalProbe *probe;
331 probe = _VMSMasterEnv->intervalProbes[ probeID ];
333 print_probe_helper( probe );
334 }
337 inline void doNothing(){};
339 void
340 generic_print_probe( void *_probe )
341 { IntervalProbe *probe;
343 probe = (IntervalProbe *)_probe;
344 print_probe_helper( probe );
345 }
347 void
348 VMS_impl__print_stats_of_all_probes()
349 { IntervalProbe *probe;
351 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
352 &generic_print_probe );
353 fflush( stdout );
354 }
355 #endif
