dictionary_lite --> dictionary_hash to take advantage of the new
[dyninst.git] / paradyn / src / PCthread / PCfilter.h
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /*
43  * PCfilter.h
44  *
45  * Data filter class performs initial processing of raw DM data arriving 
46  * in the Performance Consultant.  
47  *
48  * $Log: PCfilter.h,v $
49  * Revision 1.12  1997/10/28 20:34:29  tamches
50  * dictionary_lite --> dictionary_hash to take advantage of the new
51  * and improved dictionary_hash class
52  *
53  * Revision 1.11  1996/08/16 21:03:27  tamches
54  * updated copyright for release 1.1
55  *
56  * Revision 1.10  1996/07/26 07:28:12  karavan
57  * bug fix: eliminated race condition from data subscription code.  Changed
58  * data structures used as indices in class filteredDataServer.  Obsoleted
59  * class fmf.
60  *
61  * Revision 1.9  1996/07/23 20:28:02  karavan
62  * second part of two-part commit.
63  *
64  * implements new search strategy which retests false nodes under certain
65  * circumstances.
66  *
67  * change in handling of high-cost nodes blocking the ready queue.
68  *
69  * code cleanup.
70  *
71  * Revision 1.8  1996/07/22 18:55:41  karavan
72  * part one of two-part commit for new PC functionality of restarting searches.
73  *
74  * Revision 1.7  1996/05/08 07:35:13  karavan
75  * Changed enable data calls to be fully asynchronous within the performance consultant.
76  *
77  * some changes to cost handling, with additional limit on number of outstanding enable requests.
78  *
79  * Revision 1.6  1996/05/06 04:35:10  karavan
80  * Bug fix for asynchronous predicted cost changes.
81  *
82  * added new function find() to template classes dictionary_hash and
83  * dictionary_lite.
84  *
85  * changed filteredDataServer::DataFilters to dictionary_lite
86  *
87  * changed normalized hypotheses to use activeProcesses:cf rather than
88  * activeProcesses:tlf
89  *
90  * code cleanup
91  *
92  * Revision 1.5  1996/05/02 19:46:35  karavan
93  * changed predicted data cost to be fully asynchronous within the pc.
94  *
95  * added predicted cost server which caches predicted cost values, minimizing
96  * the number of calls to the data manager.
97  *
98  * added new batch version of ui->DAGconfigNode
99  *
100  * added hysteresis factor to cost threshold
101  *
102  * eliminated calls to dm->enable wherever possible
103  *
104  * general cleanup
105  *
106  * Revision 1.4  1996/04/30 06:26:51  karavan
107  * change PC pause function so cost-related metric instances aren't disabled
108  * if another phase is running.
109  *
110  * fixed bug in search node activation code.
111  *
112  * added change to treat activeProcesses metric differently in all PCmetrics
113  * in which it is used; checks for refinement along process hierarchy and
114  * if there is one, uses value "1" instead of enabling activeProcesses metric.
115  *
116  * changed costTracker:  we now use min of active Processes and number of
117  * cpus, instead of just number of cpus; also now we average only across
118  * time intervals rather than cumulative average.
119  *
120  * Revision 1.3  1996/04/07 21:24:38  karavan
121  * added phaseID parameter to dataMgr->enableDataCollection2.
122  *
123  * Revision 1.2  1996/02/22 18:30:05  karavan
124  * bug fix to PC pause/resume so only filters active at time of pause
125  * resubscribe to data
126  *
127  * Revision 1.1  1996/02/02 02:07:27  karavan
128  * A baby Performance Consultant is born!
129  *
130  */
131
132 #ifndef pc_filter_h
133 #define pc_filter_h
134
135 #include <stream.h>
136 #include <assert.h>
137 //sys.h defines the following:
138 //  typedef double timeStamp;
139 //  typedef float sampleValue;
140 //  typedef struct {
141 //     timeStamp start;
142 //     timeStamp end;
143 //      sampleValue value;
144 //  } Interval;
145 #include "PCintern.h"
146 #include "PCdata.h"
147
148 //filter
149 //==========
150 //Receives and sends data in real-time
151
152 //#define MAX(a, b) ((a) > (b) ? (a):(b))
153
154 class filter;
155 class filteredDataServer;
156
157 class PCmetricInst;
158 typedef PCmetricInst* fdsSubscriber;
159 typedef metricInstanceHandle fdsDataID;
160 typedef resourceListHandle focus;
161
162 /* 
163    The filter class serves as a base class for individual types of 
164    filters, which differ in how data values are computed using the 
165    raw  data which serves as input.
166
167    Every filter receives data manager data as input, and sends output
168    to its list of subscribers at defined time intervals.  The subscribers
169    are managed by methods of the parent class, dataProvider, in data.C
170    and data.h.
171 */
172 class filter : public dataProvider
173 {
174   friend ostream& operator <<(ostream &os, filter& f);
175   friend class filteredDataServer;
176   enum FilterStatus { Active, ActivationRequestPending, Inactive };
177  public:
178   filter(filteredDataServer *keeper,  
179          metricHandle met, focus focs,
180          bool costFlag);
181   ~filter() { ; }  
182   // all processing for a fresh hunk of raw data
183   virtual void newData(sampleValue, timeStamp, timeStamp) = 0;
184   //
185   metricInstanceHandle getMI () {return mi;}
186   metricHandle getMetric() {return metric;}
187   focus getFocus() {return foc;}
188   bool isActive() {return status == Active;}
189   bool isPending() {return status == ActivationRequestPending;}
190   // true means we want to disable this as part of a PC pause event
191   bool pausable() {return (numConsumers > 0 && !costFlag);}
192   void setcostFlag() {costFlag = true;}
193  protected:  
194   // activate filter by enabling met/focus pair
195   void wakeUp();
196   void inactivate() {status = Inactive;}
197   // these used in newData() to figure out intervals 
198   void updateNextSendTime(timeStamp startTime);
199   void getInitialSendTime(timeStamp startTime);
200   // (re)enable data for an existing filter
201   void activate();
202   // current length of a single interval
203   timeStamp intervalLength;
204   // when does the interval currently being collected end?
205   timeStamp nextSendTime;
206   // current time, according to this filter
207   timeStamp lastDataSeen;   
208   // when did the interval currently being collected start?
209   timeStamp partialIntervalStartTime;
210   // numerator of running average
211   sampleValue workingValue; 
212   // denominator of running average: sum of all time used in this 
213   // average; time used may not start at 0; may not be contiguous
214   timeStamp workingInterval;  
215   // identifiers for this filter
216   metricInstanceHandle mi;
217   metricHandle metric;
218   focus foc;
219  private:
220   FilterStatus status;
221   // if set, this data is not disabled for a pause because it is used in 
222   // cost observation by all phases
223   bool costFlag;
224   // collector for these filters
225   filteredDataServer *server;          
226 };
227
228 ostream& operator <<(ostream &os, filter& f);
229
230 /* an avgFilter computes values based on the running average over all 
231    data received from first enable of its metric instance.  The current
232    running average is sent to each subscriber at the end of each time 
233    interval. 
234 */
235 class avgFilter : public filter
236 {
237 public:
238   avgFilter(filteredDataServer *keeper,  
239             metricHandle met, focus focs,
240             bool costFlag):
241               filter(keeper, met, focs, costFlag) {;}
242   ~avgFilter(){;}
243   // all processing for a fresh hunk of raw data
244   void newData(sampleValue newVal, timeStamp start, timeStamp end);
245 };
246
247 /* a valFilter computes values based on the average over each time 
248    interval.  The average for each time interval is sent to each 
249    subscriber at the end of that interval.
250 */
251 class valFilter : public filter
252 {
253 public:
254   valFilter(filteredDataServer *keeper,  
255          metricHandle met, focus focs,
256          bool costFlag):
257            filter(keeper, met, focs, costFlag) {;}
258   ~valFilter() {;}
259   // all processing for a fresh hunk of raw data
260   void newData(sampleValue newVal, timeStamp start, timeStamp end);
261 };
262
263 class filteredDataServer;
264
265 // contains variable number of filters; maintains subscribers to each
266 // filter; new subscription -> dm->enable() request and add filter; 
267 // end subscription -> if numSubscribers == 0, dm->disable request.
268 // 
269 class filteredDataServer
270 {
271   friend class filter;
272 public:
273   filteredDataServer(unsigned phID);
274   ~filteredDataServer();
275
276   // interface to subscribers (provider role)
277   void addSubscription(fdsSubscriber sub,
278                             metricHandle mh,
279                             focus f,
280                             filterType ft,
281                             bool costFlag);
282   void endSubscription(fdsSubscriber sub, fdsDataID subID);
283   void endSubscription(fdsSubscriber sub, metricHandle met, focus foc);
284   // cancel pending enable request for this met/foc pair
285   void cancelSubRequest (fdsSubscriber sub, metricHandle met, focus foc);
286   void unsubscribeAllData();
287   void resubscribeAllData();
288
289   // interface to raw data source (consumer role)
290   void newBinSize(timeStamp newSize);
291   void newData(metricInstanceHandle mih, sampleValue value, int bin);
292   void newDataEnabled(vector<metricInstInfo>* newlyEnabled);
293
294   // miscellaneous  
295   timeStamp getCurrentBinSize () {return currentBinSize;}
296  private:
297   void printPendings(); 
298   filter *findFilter(metricHandle mh, focus f);
299   static unsigned fdid_hash (fdsDataID& val) {return (unsigned)val % 19;} 
300   void inActivateFilter (filter *fil);
301   void makeEnableDataRequest (metricHandle met, focus foc);
302   unsigned getPCphaseID () {
303     if (phType == CurrentPhase) return dmPhaseID+1;
304     else return 0;
305   }
306   // size of dm histogram bucket; used to convert data bin number into interval
307   timeStamp currentBinSize;  
308   // current size of each interval of output
309   timeStamp intervalSize;
310   // used by filters to align send times across filters
311   timeStamp nextSendTime;
312   phaseType phType;
313   unsigned dmPhaseID;
314   // starting interval size we never go below this
315   timeStamp minGranularity;
316
317   // DataFilters  contain all filters which are now successfully enabled.  
318   dictionary_hash<fdsDataID, filter*>DataFilters;
319
320   // miIndex and AllDataFilters contain every filter ever created for this server
321   dictionary_hash<focus, filter*> **miIndex;
322   vector<filter*> AllDataFilters;
323 };
324
325 #endif