comparison probes.c @ 50:8f7141a9272e

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