view probes.c @ 209:0c83ea8adefc

Close to compilable version of common_ancestor -- still includes HW dep stuff
author Some Random Person <seanhalle@yahoo.com>
date Sun, 04 Mar 2012 14:26:35 -0800
parents eaf7e4c58c9e
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 /*
17 * In practice, probe operations are called from the app, from inside slaves
18 * -- so have to be sure each probe is single-Slv owned, and be sure that
19 * any place common structures are modified it's done inside the master.
20 * So -- the only place common structures are modified is during creation.
21 * after that, all mods are to individual instances.
22 *
23 * Thniking perhaps should change the semantics to be that probes are
24 * attached to the virtual processor -- and then everything is guaranteed
25 * to be isolated -- except then can't take any intervals that span Slvs,
26 * and would have to transfer the probes to Master env when Slv dissipates..
27 * gets messy..
28 *
29 * For now, just making so that probe creation causes a suspend, so that
30 * the dynamic array in the master env is only modified from the master
31 *
32 */
34 //============================ Helpers ===========================
35 inline void
36 doNothing()
37 {
38 }
41 IntervalProbe *
42 create_generic_probe( char *nameStr, SlaveVP *animSlv )
43 {
44 VMSSemReq reqData;
46 reqData.reqType = createProbe;
47 reqData.nameStr = nameStr;
49 VMS_WL__send_VMSSem_request( &reqData, animSlv );
51 return animSlv->dataRetFromReq;
52 }
54 /*Use this version from outside VMS -- it uses external malloc, and modifies
55 * dynamic array, so can't be animated in a slave Slv
56 */
57 IntervalProbe *
58 ext__create_generic_probe( char *nameStr )
59 { IntervalProbe *newProbe;
60 int32 nameLen;
62 newProbe = malloc( sizeof(IntervalProbe) );
63 nameLen = strlen( nameStr );
64 newProbe->nameStr = malloc( nameLen );
65 memcpy( newProbe->nameStr, nameStr, nameLen );
66 newProbe->hist = NULL;
67 newProbe->schedChoiceWasRecorded = FALSE;
68 newProbe->probeID =
69 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
71 return newProbe;
72 }
74 //============================ Fns def in header =======================
76 int32
77 VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animSlv )
78 { IntervalProbe *newProbe;
80 newProbe = create_generic_probe( nameStr, animSlv );
82 return newProbe->probeID;
83 }
85 int32
86 VMS_impl__create_histogram_probe( int32 numBins, float64 startValue,
87 float64 binWidth, char *nameStr, SlaveVP *animSlv )
88 { IntervalProbe *newProbe;
89 DblHist *hist;
91 newProbe = create_generic_probe( nameStr, animSlv );
93 hist = makeDblHistogram( numBins, startValue, binWidth );
94 newProbe->hist = hist;
95 return newProbe->probeID;
96 }
99 int32
100 VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animSlv)
101 { IntervalProbe *newProbe;
102 struct timeval *startStamp;
103 float64 startSecs;
105 newProbe = create_generic_probe( nameStr, animSlv );
106 newProbe->endSecs = 0;
108 gettimeofday( &(newProbe->startStamp), NULL);
110 //turn into a double
111 startStamp = &(newProbe->startStamp);
112 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
113 newProbe->startSecs = startSecs;
115 return newProbe->probeID;
116 }
118 int32
119 VMS_ext_impl__record_time_point_into_new_probe( char *nameStr )
120 { IntervalProbe *newProbe;
121 struct timeval *startStamp;
122 float64 startSecs;
124 newProbe = ext__create_generic_probe( nameStr );
125 newProbe->endSecs = 0;
127 gettimeofday( &(newProbe->startStamp), NULL);
129 //turn into a double
130 startStamp = &(newProbe->startStamp);
131 startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 );
132 newProbe->startSecs = startSecs;
134 return newProbe->probeID;
135 }
138 /*Only call from inside master or main startup/shutdown thread
139 */
140 void
141 VMS_impl__free_probe( IntervalProbe *probe )
142 { if( probe->hist != NULL ) freeDblHist( probe->hist );
143 if( probe->nameStr != NULL) VMS_int__free( probe->nameStr );
144 VMS_int__free( probe );
145 }
148 void
149 VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animSlv )
150 { IntervalProbe *probe;
152 //TODO: fix this To be in Master -- race condition
153 probe = _VMSMasterEnv->intervalProbes[ probeID ];
155 addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl);
156 }
159 IntervalProbe *
160 VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animSlv )
161 {
162 //TODO: fix this To be in Master -- race condition
163 return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl );
164 }
167 /*Everything is local to the animating procr, so no need for request, do
168 * work locally, in the anim Slv
169 */
170 void
171 VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animatingSlv )
172 { IntervalProbe *probe;
174 probe = _VMSMasterEnv->intervalProbes[ probeID ];
175 probe->schedChoiceWasRecorded = TRUE;
176 probe->coreNum = animatingSlv->coreAnimatedBy;
177 probe->slaveID = animatingSlv->procrID;
178 probe->slaveCreateSecs = animatingSlv->createPtInSecs;
179 }
181 /*Everything is local to the animating procr, so no need for request, do
182 * work locally, in the anim Slv
183 */
184 void
185 VMS_impl__record_interval_start_in_probe( int32 probeID )
186 { IntervalProbe *probe;
188 DEBUG( dbgProbes, "record start of interval\n" )
189 probe = _VMSMasterEnv->intervalProbes[ probeID ];
190 probe->startStamp = getTSCount();
191 }
194 /*Everything is local to the animating procr, so no need for request, do
195 * work locally, in the anim Slv
196 *
197 *This should be safe to run inside SlaveVP -- weird behavior will be due
198 * to the logical error of having more than one interval open in overlapped.
199 */
200 void
201 VMS_impl__record_interval_end_in_probe( int32 probeID )
202 { IntervalProbe *probe;
203 TSCount endStamp;
205 endStamp = getTSCount();
207 DEBUG( dbgProbes, "record end of interval\n" )
209 probe = _VMSMasterEnv->intervalProbes[ probeID ];
210 probe->endStamp = endStamp;
212 if( probe->hist != NULL )
213 { TSCount interval = probe->endStamp - probe->startStamp;
214 //if the interval is sane, then add to histogram
215 if( interval < probe->hist->endOfRange * 10 )
216 addToFloatHist( interval, probe->hist );
217 }
218 }
221 void
222 print_probe_helper( IntervalProbe *probe )
223 {
224 printf( "\nprobe: %s, ", probe->nameStr );
227 if( probe->schedChoiceWasRecorded )
228 { printf( "coreNum: %d, procrID: %d, procrCreated: %0.6f | ",
229 probe->coreNum, probe->slaveID, probe->slaveCreateSecs );
230 }
232 if( probe->endSecs == 0 ) //just a single point in time
233 {
234 printf( " time point: %.6f\n",
235 probe->startSecs - _VMSMasterEnv->createPtInSecs );
236 }
237 else if( probe->hist == NULL ) //just an interval
238 {
239 printf( " startSecs: %.6f interval: %.6f\n",
240 (probe->startSecs - _VMSMasterEnv->createPtInSecs), probe->interval);
241 }
242 else //a full histogram of intervals
243 {
244 printDblHist( probe->hist );
245 }
246 }
248 //TODO: change so pass around pointer to probe instead of its array-index..
249 // will eliminate chance for timing of resize to cause problems with the
250 // lookup -- even though don't think it actually can cause problems..
251 // there's no need to pass index around -- have hash table for names, and
252 // only need it once, then have ptr to probe.. the thing about enum the
253 // index and use that as name is clunky in practice -- just hash.
254 void
255 VMS_impl__print_stats_of_probe( int32 probeID )
256 { IntervalProbe *probe;
258 probe = _VMSMasterEnv->intervalProbes[ probeID ];
260 print_probe_helper( probe );
261 }
264 void
265 VMS_impl__print_stats_of_all_probes()
266 {
267 forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo,
268 &VMS_impl__print_stats_of_probe );
269 fflush( stdout );
270 }