Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view probes.c @ 200:6db9e4898978
VMS name chgs -- added "WL" "PI" and "int" and split vms.h up
| author | Me@portablequad |
|---|---|
| date | Sun, 12 Feb 2012 01:49:33 -0800 |
| parents | 7cff4e13d5c4 |
| children |
line source
1 /*
2 * Copyright 2010 OpenSourceStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
7 #include <stdio.h>
8 #include <malloc.h>
9 #include <sys/time.h>
11 #include "VMS.h"
15 //==================== Probes =================
16 #ifdef STATS__USE_TSC_PROBES
18 int32
19 VMS__create_histogram_probe( int32 numBins, float32 startValue,
20 float32 binWidth, char *nameStr )
21 { IntervalProbe *newProbe;
22 int32 idx;
23 FloatHist *hist;
25 idx = VMS__create_single_interval_probe( nameStr );
26 newProbe = _VMSMasterEnv->intervalProbes[ idx ];
28 hist = makeFloatHistogram( numBins, startValue, binWidth );
29 newProbe->hist = hist;
30 return idx;
31 }
33 void
34 VMS_impl__record_interval_start_in_probe( int32 probeID )
35 { IntervalProbe *probe;
37 probe = _VMSMasterEnv->intervalProbes[ probeID ];
38 probe->startStamp = getTSCount();
39 }
41 void
42 VMS_impl__record_interval_end_in_probe( int32 probeID )
43 { IntervalProbe *probe;
44 TSCount endStamp;
46 endStamp = getTSCount();
48 probe = _VMSMasterEnv->intervalProbes[ probeID ];
49 probe->endStamp = endStamp;
51 if( probe->hist != NULL )
52 { TSCount interval = probe->endStamp - probe->startStamp;
53 //if the interval is sane, then add to histogram
54 if( interval < probe->hist->endOfRange * 10 )
55 addToFloatHist( interval, probe->hist );
56 }
57 }
59 void
60 VMS_impl__print_stats_of_probe( int32 probeID )
61 { IntervalProbe *probe;
63 probe = _VMSMasterEnv->intervalProbes[ probeID ];
65 if( probe->hist == NULL )
66 {
67 printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval);
68 }
70 else
71 {
72 printf( "probe: %s\n", probe->nameStr );
73 printFloatHist( probe->hist );
74 }
75 }
76 #else
78 /*
79 * In practice, probe operations are called from the app, from inside slaves
80 * -- so have to be sure each probe is single-VP owned, and be sure that
81 * any place common structures are modified it's done inside the master.
82 * So -- the only place common structures are modified is during creation.
83 * after that, all mods are to individual instances.
84 *
85 * Thniking perhaps should change the semantics to be that probes are
86 * attached to the virtual processor -- and then everything is guaranteed
87 * to be isolated -- except then can't take any intervals that span VPs,
88 * and would have to transfer the probes to Master env when VP dissipates..
89 * gets messy..
90 *
91 * For now, just making so that probe creation causes a suspend, so that
92 * the dynamic array in the master env is only modified from the master
93 *
94 */
95 IntervalProbe *
96 create_generic_probe( char *nameStr, SlaveVP *animPr )
97 {
98 VMSSemReq reqData;
100 reqData.reqType = createProbe;
101 reqData.nameStr = nameStr;
103 VMS_WL__send_VMSSem_request( &reqData, animPr );
105 return animPr->dataRetFromReq;
106 }
108 /*Use this version from outside VMS -- it uses external malloc, and modifies
109 * dynamic array, so can't be animated in a slave VP
110 */
111 IntervalProbe *
112 ext__create_generic_probe( char *nameStr )
113 { IntervalProbe *newProbe;
114 int32 nameLen;
116 newProbe = malloc( sizeof(IntervalProbe) );
117 nameLen = strlen( nameStr );
118 newProbe->nameStr = malloc( nameLen );
119 memcpy( newProbe->nameStr, nameStr, nameLen );
120 newProbe->hist = NULL;
121 newProbe->schedChoiceWasRecorded = FALSE;
122 newProbe->probeID =
123 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
125 return newProbe;
126 }
129 /*Only call from inside master or main startup/shutdown thread
130 */
131 void
132 VMS_impl__free_probe( IntervalProbe *probe )
133 { if( probe->hist != NULL ) freeDblHist( probe->hist );
134 if( probe->nameStr != NULL) VMS_int__free( probe->nameStr );
135 VMS_int__free( probe );
136 }
139 int32
140 VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animPr)
141 { IntervalProbe *newProbe;
142 struct timeval *startStamp;
143 float64 startSecs;
145 newProbe = create_generic_probe( nameStr, animPr );
146 newProbe->endSecs = 0;
148 gettimeofday( &(newProbe->startStamp), NULL);
150 //turn into a double
151 startStamp = &(newProbe->startStamp);
152 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
153 newProbe->startSecs = startSecs;
155 return newProbe->probeID;
156 }
158 int32
159 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
160 { IntervalProbe *newProbe;
161 struct timeval *startStamp;
162 float64 startSecs;
164 newProbe = ext__create_generic_probe( nameStr );
165 newProbe->endSecs = 0;
167 gettimeofday( &(newProbe->startStamp), NULL);
169 //turn into a double
170 startStamp = &(newProbe->startStamp);
171 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
172 newProbe->startSecs = startSecs;
174 return newProbe->probeID;
175 }
177 int32
178 VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animPr )
179 { IntervalProbe *newProbe;
181 newProbe = create_generic_probe( nameStr, animPr );
183 return newProbe->probeID;
184 }
186 int32
187 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
188 float64 binWidth, char *nameStr, SlaveVP *animPr )
189 { IntervalProbe *newProbe;
190 DblHist *hist;
192 newProbe = create_generic_probe( nameStr, animPr );
194 hist = makeDblHistogram( numBins, startValue, binWidth );
195 newProbe->hist = hist;
196 return newProbe->probeID;
197 }
199 void
200 VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animPr )
201 { IntervalProbe *probe;
203 //TODO: fix this To be in Master -- race condition
204 probe = _VMSMasterEnv->intervalProbes[ probeID ];
206 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
207 }
209 IntervalProbe *
210 VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animPr )
211 {
212 //TODO: fix this To be in Master -- race condition
213 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
214 }
217 /*Everything is local to the animating procr, so no need for request, do
218 * work locally, in the anim Pr
219 */
220 void
221 VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animatingPr )
222 { IntervalProbe *probe;
224 probe = _VMSMasterEnv->intervalProbes[ probeID ];
225 probe->schedChoiceWasRecorded = TRUE;
226 probe->coreNum = animatingPr->coreAnimatedBy;
227 probe->procrID = animatingPr->procrID;
228 probe->procrCreateSecs = animatingPr->createPtInSecs;
229 }
231 /*Everything is local to the animating procr, so no need for request, do
232 * work locally, in the anim Pr
233 */
234 void
235 VMS_impl__record_interval_start_in_probe( int32 probeID )
236 { IntervalProbe *probe;
238 DEBUG( dbgProbes, "record start of interval\n" )
239 probe = _VMSMasterEnv->intervalProbes[ probeID ];
240 gettimeofday( &(probe->startStamp), NULL );
241 }
244 /*Everything is local to the animating procr, so no need for request, do
245 * work locally, in the anim Pr
246 */
247 void
248 VMS_impl__record_interval_end_in_probe( int32 probeID )
249 { IntervalProbe *probe;
250 struct timeval *endStamp, *startStamp;
251 float64 startSecs, endSecs;
253 DEBUG( dbgProbes, "record end of interval\n" )
254 //possible seg-fault if array resized by diff core right after this
255 // one gets probe..? Something like that? Might be safe.. don't care
256 probe = _VMSMasterEnv->intervalProbes[ probeID ];
257 gettimeofday( &(probe->endStamp), NULL);
259 //now turn into an interval held in a double
260 startStamp = &(probe->startStamp);
261 endStamp = &(probe->endStamp);
263 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
264 endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 );
266 probe->interval = endSecs - startSecs;
267 probe->startSecs = startSecs;
268 probe->endSecs = endSecs;
270 if( probe->hist != NULL )
271 {
272 //if the interval is sane, then add to histogram
273 if( probe->interval < probe->hist->endOfRange * 10 )
274 addToDblHist( probe->interval, probe->hist );
275 }
276 }
278 void
279 print_probe_helper( IntervalProbe *probe )
280 {
281 printf( "\nprobe: %s, ", probe->nameStr );
284 if( probe->schedChoiceWasRecorded )
285 { printf( "coreNum: %d, procrID: %d, procrCreated: %0.6f | ",
286 probe->coreNum, probe->procrID, probe->procrCreateSecs );
287 }
289 if( probe->endSecs == 0 ) //just a single point in time
290 {
291 printf( " time point: %.6f\n",
292 probe->startSecs - _VMSMasterEnv->createPtInSecs );
293 }
294 else if( probe->hist == NULL ) //just an interval
295 {
296 printf( " startSecs: %.6f interval: %.6f\n",
297 (probe->startSecs - _VMSMasterEnv->createPtInSecs), probe->interval);
298 }
299 else //a full histogram of intervals
300 {
301 printDblHist( probe->hist );
302 }
303 }
305 //TODO: change so pass around pointer to probe instead of its array-index..
306 // will eliminate chance for timing of resize to cause problems with the
307 // lookup -- even though don't think it actually can cause problems..
308 // there's no need to pass index around -- have hash table for names, and
309 // only need it once, then have ptr to probe.. the thing about enum the
310 // index and use that as name is clunky in practice -- just hash.
311 void
312 VMS_impl__print_stats_of_probe( int32 probeID )
313 { IntervalProbe *probe;
315 probe = _VMSMasterEnv->intervalProbes[ probeID ];
317 print_probe_helper( probe );
318 }
321 inline void doNothing(){};
323 void
324 generic_print_probe( void *_probe )
325 {
326 IntervalProbe *probe = (IntervalProbe *)_probe;
328 //TODO segfault in printf
329 //print_probe_helper( probe );
330 }
332 void
333 VMS_impl__print_stats_of_all_probes()
334 {
335 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
336 &generic_print_probe );
337 fflush( stdout );
338 }
339 #endif
