added phaseType parameter to PCnewData
[dyninst.git] / paradyn / src / PCthread / PCmain.C
1
2 /*
3  * Copyright (c) 1993, 1994 Barton P. Miller, Jeff Hollingsworth,
4  *     Bruce Irvin, Jon Cargille, Krishna Kunchithapadam, Karen
5  *     Karavanic, Tia Newhall, Mark Callaghan.  All rights reserved.
6  * 
7  * This software is furnished under the condition that it may not be
8  * provided or otherwise made available to, or used by, any other
9  * person, except as provided for by the terms of applicable license
10  * agreements.  No title to or ownership of the software is hereby
11  * transferred.  The name of the principals may not be used in any
12  * advertising or publicity related to this software without specific,
13  * written prior authorization.  Any use of this software must include
14  * the above copyright notice.
15  *
16  */
17
18 /* $Log: PCmain.C,v $
19 /* Revision 1.35  1995/10/13 22:09:19  newhall
20 /* added phaseType parameter to PCnewData
21 /*
22  * Revision 1.34  1995/10/05  04:41:43  karavan
23  * changes to UI::PC interface calls.
24  *
25  * Revision 1.33  1995/08/08  03:13:03  newhall
26  * updates due to changes in DM: newPerfData, sampleDataCallbackFunc defs.
27  *
28  * Revision 1.32  1995/08/05  17:09:11  krisna
29  * do not include <memory.h> in C++ programs, use <stdlib.h>
30  *
31  * Revision 1.31  1995/08/01 02:18:20  newhall
32  * changes to support phase interface
33  *
34  * Revision 1.30  1995/06/02  20:50:09  newhall
35  * made code compatable with new DM interface
36  *
37  * Revision 1.29  1995/02/27  19:17:31  tamches
38  * Changes to code having to do with tunable constants.
39  * First, header files have moved from util lib to TCthread.
40  * Second, tunable constants may no longer be declared globally.
41  * Third, accessing tunable constants is different.
42  *
43  * Revision 1.28  1995/02/16  08:19:11  markc
44  * Changed Boolean to bool
45  *
46  * Revision 1.27  1995/01/26  17:58:39  jcargill
47  * Changed igen-generated include files to new naming convention; fixed
48  * some bugs compiling with gcc-2.6.3.
49  *
50  * Revision 1.26  1994/09/30  19:18:12  rbi
51  * Abstraction interface change.
52  *
53  * Revision 1.25  1994/09/22  01:01:08  markc
54  * Cast stringHandle to char* to view as text
55  *
56  * Revision 1.24  1994/09/06  08:32:30  karavan
57  * Better control of PC output through tunable constants.
58  *
59  * Revision 1.23  1994/09/05  20:01:00  jcargill
60  * Better control of PC output through tunable constants.
61  *
62  * Revision 1.22  1994/08/22  15:55:58  markc
63  * Cast stringHandles to char* for printing.
64  *
65  * Revision 1.21  1994/08/05  16:04:12  hollings
66  * more consistant use of stringHandle vs. char *.
67  *
68  * Revision 1.20  1994/08/03  19:09:49  hollings
69  * split tunable constant into float and boolean types
70  *
71  * added tunable constant for printing tests as they avaluate.
72  *
73  * added code to compute the min interval data has been enabled for a single
74  * test rather than using a global min.  This prevents short changes from
75  * altering long term trends among high level hypotheses.
76  *
77  * Revision 1.19  1994/07/28  22:33:59  krisna
78  * proper starting code for PCmain thread
79  * stringCompare matches qsort prototype
80  * changed infinity() to HUGE_VAL
81  *
82  * Revision 1.18  1994/07/25  04:47:05  hollings
83  * Added histogram to PCmetric so we only use data for minimum interval
84  * that all metrics for a current batch of requests has been enabled.
85  *
86  * added hypothsis to deal with the procedure level data correctly in
87  * CPU bound programs.
88  *
89  * changed inst hypothesis to use observed cost metric not old procedure
90  * call based one.
91  *
92  * Revision 1.17  1994/06/27  21:24:39  rbi
93  * New abstraction parameter for performance streams
94  *
95  * Revision 1.16  1994/06/27  18:55:08  hollings
96  * Added compiler flag to add SHG nodes to dag only on first evaluation.
97  *
98  * Revision 1.15  1994/06/22  22:58:19  hollings
99  * Compiler warnings and copyrights.
100  *
101  * Revision 1.14  1994/06/17  00:12:28  hollings
102  * fixed the init of the control callback structure.
103  *
104  * Revision 1.13  1994/06/12  22:40:49  karavan
105  * changed printf's to calls to status display service.
106  *
107  * Revision 1.12  1994/05/18  00:48:53  hollings
108  * Major changes in the notion of time to wait for a hypothesis.  We now wait
109  * until the earlyestLastSample for a metrics used by a hypothesis is at
110  * least sufficient observation time after the change was made.
111  *
112  * Revision 1.11  1994/05/12  23:34:06  hollings
113  * made path to paradyn.h relative.
114  *
115  * Revision 1.10  1994/05/10  03:57:43  hollings
116  * Changed data upcall to return array of buckets.
117  *
118  * Revision 1.9  1994/05/06  06:39:34  karavan
119  * SHG now initialized only upon request
120  *
121  * Revision 1.8  1994/05/02  20:38:10  hollings
122  * added pause search mode, and cleanedup global variable naming.
123  *
124  * Revision 1.7  1994/04/21  05:00:10  karavan
125  * added global SHGid for visual display.
126  *
127  * Revision 1.6  1994/04/06  21:24:10  markc
128  * First log message.
129  * */
130
131 #include <assert.h>
132 #include <stdlib.h>
133
134
135 #include "thread/h/thread.h"
136 #include "../TCthread/tunableConst.h"
137 #include "dataManager.thread.CLNT.h"
138 #include "performanceConsultant.thread.SRVR.h"
139 #include "UI.thread.CLNT.h"
140 #include "PCglobals.h"
141 #include "PCmetric.h"
142 #include "../src/pdMain/paradyn.h"
143 #include "../src/DMthread/DMresource.h"
144
145 #include "../src/DMthread/DMinclude.h"
146
147 // TEMP until remove all ptrs from interface then include DMinclue.h
148 #include "paradyn/src/DMthread/DMmetric.h"
149 #include "paradyn/src/DMthread/DMresource.h"
150 // ***********************************
151
152
153 perfStreamHandle pc_ps_handle;
154 extern void initResources();
155 extern void PCevaluateWorld();
156 extern thread_t MAINtid;
157 extern timeStamp PCstartTransTime;
158 extern timeStamp PCendTransTime;
159
160 int SHGid;             // id needed for Search History Graph uim dag calls
161 static float PCbucketWidth;
162
163 void PCfold(perfStreamHandle handle,
164             timeStamp newWidth,
165             phaseType phase_type)
166 {
167     if(phase_type == GlobalPhase) 
168         PCbucketWidth = newWidth;
169 }
170
171 void PCnewData(perfStreamHandle handle,
172                metricInstanceHandle m_handle,
173                int bucketNumber,
174                sampleValue value,
175                phaseType type)
176 {
177     // TODO: this should be removed and PC thread should not be accessing
178     // metricInstance objects directly
179     metricInstance *mi = metricInstance::getMI(m_handle);
180     if(!mi)  return;
181
182     sampleValue total = value*PCbucketWidth;
183
184     datum *dp = miToDatumMap.find(mi);
185     assert(dp);
186     timeStamp start = PCbucketWidth * bucketNumber;
187     timeStamp end = PCbucketWidth * (bucketNumber + 1);
188 #ifdef n_def
189     if((bucketNumber % 50) == 0){
190         cout << "PCdata:  bucketNumber:  " << bucketNumber << endl;
191         cout << "    width:         " << PCbucketWidth << endl;
192         cout << "    start:         " << start << endl;
193         cout << "    end:           " << end << endl;
194         cout << "    PCcurrentTime: " << PCcurrentTime << endl;
195         cout << "    PCstartTransTime: " << PCstartTransTime << endl;
196         cout << "    PCendTransTime: " << PCendTransTime << endl;
197     }
198 #endif
199
200   tunableBooleanConstant pcEvalPrint = tunableConstantRegistry::findBoolTunableConstant("pcEvalPrint");
201   if (pcEvalPrint.getValue()) {
202         cout << "AR: " << (char*)dp->metName << (char*)dp->resList->getName();
203         cout << " = " << total;
204         cout << " from " << start << " to " << end << "\n";
205   }
206
207     dp->newSample(start, end, total);
208
209     // see if we should check for new state change.
210     //  we wait until time moves, otherwise we evaluate hypotheses too often.
211     if (end > PCcurrentTime) {
212         PCcurrentTime = end;
213         if (PCstartTransTime < PCendTransTime) {
214             PCevaluateWorld();
215         }
216     }
217 }
218
219 void PCnewInfo()
220 {
221 }
222
223 void PCmetricFunc(perfStreamHandle handle, 
224                   const char *name,
225                   int style,
226                   int aggregate,
227                   const char *units,
228                   metricHandle m_handle)
229 {
230     PCmetric *pcMet;
231     stringHandle s_name;
232     extern stringPool PCmetricStrings;
233
234     // TODO: this should be removed and PC thread should not be accessing
235     // metric objects directly
236     metric *met = metric::getMetric(m_handle);
237     if(!met) return;
238
239     char *newName = strdup(name);
240     s_name = PCmetricStrings.findAndAdd(newName);
241     pcMet = (PCmetric *) allMetrics.find((char *)s_name);
242     if (!pcMet) {
243         // This warning was intended to make it easy to catch typos in metric
244         //   names between paradynd and the PC.  However, there are now several
245         //   metrics that paradynd defines that the PC doesn't need.
246         //   - jkh 6/25/94
247         // printf("WARNING performance consultant has no use for %s\n", name);
248         pcMet = new PCmetric((char*)s_name);
249     }
250     pcMet->met = met;
251 }
252
253 void PCmain(void* varg)
254 {
255     int arg; memcpy((void *) &arg, varg, sizeof arg);
256
257     int i;
258     int from;
259     unsigned int tag;
260     performanceConsultant *pc;
261     union dataCallback dataHandlers;
262     struct controlCallback controlHandlers;
263     char PCbuff[64];
264     unsigned int msgSize = 64;
265
266     thr_name("PerformanceConsultant");
267     // ??? do inits and waits.
268
269     pc = new performanceConsultant(MAINtid);
270
271     msg_send (MAINtid, MSG_TAG_PC_READY, (char *) NULL, 0);
272     tag = MSG_TAG_ALL_CHILDREN_READY;
273     msg_recv (&tag, PCbuff, &msgSize);
274     // why are static resources initialized here?
275     initResources();
276
277     // make sure memory is clear.
278     memset(&controlHandlers, '\0', sizeof(controlHandlers));
279     controlHandlers.mFunc = PCmetricFunc;
280     controlHandlers.fFunc = PCfold;
281
282     dataHandlers.sample = PCnewData;
283     pc_ps_handle = dataMgr->createPerformanceStream(Sample,
284         dataHandlers, controlHandlers);
285
286     PCbucketWidth = dataMgr->getCurrentBucketWidth();
287
288     // now find about existing metrics.
289     vector<string> *mets = dataMgr->getAvailableMetrics();
290     for (i=0; i < mets->size(); i++) {
291         metricHandle *m_handle = dataMgr->findMetric((*mets)[i].string_of());
292         if (m_handle) {
293             metric *met = metric::getMetric(*m_handle);
294             if(met) 
295                 PCmetricFunc(pc_ps_handle, 
296                              met->getName(),
297                              met->getStyle(),
298                              met->getAggregate(),
299                              met->getUnits(),
300                              met->getHandle());
301         }
302     }
303
304     while (1) {
305         tag = MSG_TAG_ANY;
306         from = msg_poll(&tag, true);
307         assert(from != THR_ERR);
308         if (dataMgr->isValidTag((T_dataManager::message_tags)tag)) {
309           if (dataMgr->waitLoop(true, (T_dataManager::message_tags)tag) ==
310               T_dataManager::error) {
311             // handle error
312             // TODO
313             cerr << "Error in PCmain.C, needs to be handled\n";
314             assert(0);
315           }
316         } else if (pc->isValidTag((T_performanceConsultant::message_tags)tag)) {
317           if (pc->waitLoop(true, (T_performanceConsultant::message_tags)tag) ==
318               T_performanceConsultant::error) {
319             // handle error
320             // TODO
321             cerr << "Error in PCmain.C, needs to be handled\n";
322             assert(0);
323           }
324         } else {
325           // TODO
326           cerr << "Message sent that is not recognized in PCmain.C\n";
327           assert(0);
328         }
329    }
330 }