Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view probes.c @ 135:0b49fd35afc1
distributed free working
-app sends a VMSSemReqst to his Master which send a request to a different Master
-Master send the request directly
-The request structure is freed by the sender, when the request was handled
There are still problems on shutdown. The shutdownVPs are all allocated by one Master which is likly to be terminated
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Fri, 16 Sep 2011 20:08:28 +0200 |
| parents | 96e273d9f66f |
| 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"
12 #include "Queue_impl/BlockingQueue.h"
13 #include "Histogram/Histogram.h"
16 //================================ STATS ====================================
18 inline TSCount getTSCount()
19 { unsigned int low, high;
20 TSCount out;
22 saveTimeStampCountInto( low, high );
23 out = high;
24 out = (out << 32) + low;
25 return out;
26 }
30 //==================== Probes =================
31 #ifdef STATS__USE_TSC_PROBES
33 int32
34 VMS__create_histogram_probe( int32 numBins, float32 startValue,
35 float32 binWidth, char *nameStr )
36 { IntervalProbe *newProbe;
37 int32 idx;
38 FloatHist *hist;
40 idx = VMS__create_single_interval_probe( nameStr );
41 newProbe = _VMSMasterEnv->intervalProbes[ idx ];
43 hist = makeFloatHistogram( numBins, startValue, binWidth );
44 newProbe->hist = hist;
45 return idx;
46 }
48 void
49 VMS_impl__record_interval_start_in_probe( int32 probeID )
50 { IntervalProbe *probe;
52 probe = _VMSMasterEnv->intervalProbes[ probeID ];
53 probe->startStamp = getTSCount();
54 }
56 void
57 VMS_impl__record_interval_end_in_probe( int32 probeID )
58 { IntervalProbe *probe;
59 TSCount endStamp;
61 endStamp = getTSCount();
63 probe = _VMSMasterEnv->intervalProbes[ probeID ];
64 probe->endStamp = endStamp;
66 if( probe->hist != NULL )
67 { TSCount interval = probe->endStamp - probe->startStamp;
68 //if the interval is sane, then add to histogram
69 if( interval < probe->hist->endOfRange * 10 )
70 addToFloatHist( interval, probe->hist );
71 }
72 }
74 void
75 VMS_impl__print_stats_of_probe( int32 probeID )
76 { IntervalProbe *probe;
78 probe = _VMSMasterEnv->intervalProbes[ probeID ];
80 if( probe->hist == NULL )
81 {
82 printf("probe: %s, interval: %.6lf\n", probe->nameStr,probe->interval);
83 }
85 else
86 {
87 printf( "probe: %s\n", probe->nameStr );
88 printFloatHist( probe->hist );
89 }
90 }
91 #else
93 /*
94 * In practice, probe operations are called from the app, from inside slaves
95 * -- so have to be sure each probe is single-VP owned, and be sure that
96 * any place common structures are modified it's done inside the master.
97 * So -- the only place common structures are modified is during creation.
98 * after that, all mods are to individual instances.
99 *
100 * Thniking perhaps should change the semantics to be that probes are
101 * attached to the virtual processor -- and then everything is guaranteed
102 * to be isolated -- except then can't take any intervals that span VPs,
103 * and would have to transfer the probes to Master env when VP dissipates..
104 * gets messy..
105 *
106 * For now, just making so that probe creation causes a suspend, so that
107 * the dynamic array in the master env is only modified from the master
108 *
109 */
110 IntervalProbe *
111 create_generic_probe( char *nameStr, VirtProcr *animPr )
112 {
113 VMSSemReq reqData;
115 reqData.reqType = createProbe;
116 reqData.data = (void*)nameStr;
118 VMS__send_VMSSem_request( &reqData, animPr );
120 return animPr->dataRetFromReq;
121 }
123 /*Use this version from outside VMS -- it uses external malloc, and modifies
124 * dynamic array, so can't be animated in a slave VP
125 */
126 IntervalProbe *
127 ext__create_generic_probe( char *nameStr )
128 { IntervalProbe *newProbe;
129 int32 nameLen;
131 newProbe = malloc( sizeof(IntervalProbe) );
132 nameLen = strlen( nameStr );
133 newProbe->nameStr = malloc( nameLen );
134 memcpy( newProbe->nameStr, nameStr, nameLen );
135 newProbe->hist = NULL;
136 newProbe->schedChoiceWasRecorded = FALSE;
137 newProbe->probeID =
138 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
140 return newProbe;
141 }
144 /*Only call from inside master or main startup/shutdown thread
145 */
146 void
147 VMS_impl__free_probe( IntervalProbe *probe )
148 { if( probe->hist != NULL ) freeDblHist( probe->hist );
149 if( probe->nameStr != NULL) VMS__free( probe->nameStr );
150 VMS__free( probe );
151 }
154 int32
155 VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr)
156 { IntervalProbe *newProbe;
157 struct timeval *startStamp;
158 float64 startSecs;
160 newProbe = create_generic_probe( nameStr, animPr );
161 newProbe->endSecs = 0;
163 gettimeofday( &(newProbe->startStamp), NULL);
165 //turn into a double
166 startStamp = &(newProbe->startStamp);
167 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
168 newProbe->startSecs = startSecs;
170 return newProbe->probeID;
171 }
173 int32
174 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
175 { IntervalProbe *newProbe;
176 struct timeval *startStamp;
177 float64 startSecs;
179 newProbe = ext__create_generic_probe( nameStr );
180 newProbe->endSecs = 0;
182 gettimeofday( &(newProbe->startStamp), NULL);
184 //turn into a double
185 startStamp = &(newProbe->startStamp);
186 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
187 newProbe->startSecs = startSecs;
189 return newProbe->probeID;
190 }
192 int32
193 VMS_impl__create_single_interval_probe( char *nameStr, VirtProcr *animPr )
194 { IntervalProbe *newProbe;
196 newProbe = create_generic_probe( nameStr, animPr );
198 return newProbe->probeID;
199 }
201 int32
202 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
203 float64 binWidth, char *nameStr, VirtProcr *animPr )
204 { IntervalProbe *newProbe;
205 DblHist *hist;
207 newProbe = create_generic_probe( nameStr, animPr );
209 hist = makeDblHistogram( numBins, startValue, binWidth );
210 newProbe->hist = hist;
211 return newProbe->probeID;
212 }
214 void
215 VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr )
216 { IntervalProbe *probe;
218 //TODO: fix this To be in Master -- race condition
219 probe = _VMSMasterEnv->intervalProbes[ probeID ];
221 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
222 }
224 IntervalProbe *
225 VMS_impl__get_probe_by_name( char *probeName, VirtProcr *animPr )
226 {
227 //TODO: fix this To be in Master -- race condition
228 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
229 }
232 /*Everything is local to the animating procr, so no need for request, do
233 * work locally, in the anim Pr
234 */
235 void
236 VMS_impl__record_sched_choice_into_probe( int32 probeID, VirtProcr *animatingPr )
237 { IntervalProbe *probe;
239 probe = _VMSMasterEnv->intervalProbes[ probeID ];
240 probe->schedChoiceWasRecorded = TRUE;
241 probe->coreNum = animatingPr->coreAnimatedBy;
242 probe->procrID = animatingPr->procrID;
243 probe->procrCreateSecs = animatingPr->createPtInSecs;
244 }
246 /*Everything is local to the animating procr, so no need for request, do
247 * work locally, in the anim Pr
248 */
249 void
250 VMS_impl__record_interval_start_in_probe( int32 probeID )
251 { IntervalProbe *probe;
253 DEBUG( dbgProbes, "record start of interval\n" )
254 probe = _VMSMasterEnv->intervalProbes[ probeID ];
255 gettimeofday( &(probe->startStamp), NULL );
256 }
259 /*Everything is local to the animating procr, so no need for request, do
260 * work locally, in the anim Pr
261 */
262 void
263 VMS_impl__record_interval_end_in_probe( int32 probeID )
264 { IntervalProbe *probe;
265 struct timeval *endStamp, *startStamp;
266 float64 startSecs, endSecs;
268 DEBUG( dbgProbes, "record end of interval\n" )
269 //possible seg-fault if array resized by diff core right after this
270 // one gets probe..? Something like that? Might be safe.. don't care
271 probe = _VMSMasterEnv->intervalProbes[ probeID ];
272 gettimeofday( &(probe->endStamp), NULL);
274 //now turn into an interval held in a double
275 startStamp = &(probe->startStamp);
276 endStamp = &(probe->endStamp);
278 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
279 endSecs = endStamp->tv_sec + ( endStamp->tv_usec / 1000000.0 );
281 probe->interval = endSecs - startSecs;
282 probe->startSecs = startSecs;
283 probe->endSecs = endSecs;
285 if( probe->hist != NULL )
286 {
287 //if the interval is sane, then add to histogram
288 if( probe->interval < probe->hist->endOfRange * 10 )
289 addToDblHist( probe->interval, probe->hist );
290 }
291 }
293 void
294 print_probe_helper( IntervalProbe *probe )
295 {
296 printf( "\nprobe: %s, ", probe->nameStr );
299 if( probe->schedChoiceWasRecorded )
300 { printf( "coreNum: %d, procrID: %d, procrCreated: %0.6f | ",
301 probe->coreNum, probe->procrID, probe->procrCreateSecs );
302 }
304 if( probe->endSecs == 0 ) //just a single point in time
305 {
306 printf( " time point: %.6f\n",
307 probe->startSecs - _VMSMasterEnv->createPtInSecs );
308 }
309 else if( probe->hist == NULL ) //just an interval
310 {
311 printf( " startSecs: %.6f interval: %.6f\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 }
336 inline void doNothing(){};
338 void
339 generic_print_probe( void *_probe )
340 {
341 //IntervalProbe *probe = (IntervalProbe *)_probe;
343 //TODO segfault in printf
344 //print_probe_helper( probe );
345 }
347 void
348 VMS_impl__print_stats_of_all_probes()
349 {
350 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
351 &generic_print_probe );
352 fflush( stdout );
353 }
354 #endif
