removed calls to grid cell Deleted member functions
[dyninst.git] / visi / src / visualization.C
1 /*
2  * Copyright (c) 1993, 1994 Barton P. Miller, Jeff Hollingsworth,
3  *     Bruce Irvin, Jon Cargille, Krishna Kunchithapadam, Karen
4  *     Karavanic, Tia Newhall, Mark Callaghan.  All rights reserved.
5  * 
6  * This software is furnished under the condition that it may not be
7  * provided or otherwise made available to, or used by, any other
8  * person, except as provided for by the terms of applicable license
9  * agreements.  No title to or ownership of the software is hereby
10  * transferred.  The name of the principals may not be used in any
11  * advertising or publicity related to this software without specific,
12  * written prior authorization.  Any use of this software must include
13  * the above copyright notice.
14  *
15  */
16 /* $Log: visualization.C,v $
17 /* Revision 1.14  1994/08/11 02:52:11  newhall
18 /* removed calls to grid cell Deleted member functions
19 /*
20  * Revision 1.13  1994/08/03  20:49:12  newhall
21  * removed code for interface routines NewMetricsResources and Enabled
22  * changed AddMetricsResources to set grid cell's enabled flag
23  *
24  * Revision 1.12  1994/07/30  03:27:27  newhall
25  * added visi interface functions Enabled and BulkDataTransfer
26  *
27  * Revision 1.11  1994/07/20  22:41:11  rbi
28  * Small arguments fix to make identification of wildcards easier.
29  *
30  * Revision 1.10  1994/07/07  22:40:31  newhall
31  * fixed compile warnings
32  *
33  * Revision 1.9  1994/06/16  18:24:53  newhall
34  * fix to visualization::Data
35  *
36  * Revision 1.8  1994/06/07  17:48:49  newhall
37  * support for adding metrics and resources to existing visualization
38  *
39  * Revision 1.7  1994/05/23  20:56:48  newhall
40  * To visi_GridCellHisto class: added deleted flag, SumValue
41  * method function, and fixed AggregateValue method function
42  *
43  * Revision 1.6  1994/05/11  17:13:14  newhall
44  * changed data type from double to float
45  *
46  * Revision 1.5  1994/04/13  21:34:54  newhall
47  * added routines: GetMetsRes StopMetRes NamePhase
48  *
49  * Revision 1.4  1994/03/26  04:19:49  newhall
50  * changed all floats to double
51  * fix problem with null string returned for first resource name
52  *
53  * Revision 1.3  1994/03/17  05:23:09  newhall
54  * changed eventCallbacks type, and the constraints on triggering the
55  * callback routine associated with the DATAVALUES event
56  *
57  * Revision 1.2  1994/03/14  20:28:55  newhall
58  * changed visi subdirectory structure
59  *  */ 
60 #include "visi/h/visualization.h"
61 #include "visi.SRVR.h"
62 /*
63 #define DEBUG
64 */
65
66
67 visi_DataGrid  dataGrid;
68 visi_MRList    metricList;
69 visi_MRList    resourceList;
70 int            LastBucketSent = -1;
71 int fileDesc[FILETABLESIZE];
72 int (*fileDescCallbacks[FILETABLESIZE])();
73 int (*eventCallbacks[EVENTSIZE])(int);
74 int initDone = 0;
75
76 visualization *vp;
77 int visi_callback(){
78   return(vp->mainLoop());
79 }
80
81 ///////////////////////////////////////////////////////////
82 // paradyn initialization routine connects to parent socket,
83 // and registers the visualization::mainLoop routine as 
84 // callback on events on fileDesc[0]
85 ///////////////////////////////////////////////////////////
86 int VisiInit(){
87
88 int i;
89
90   for(i=0;i<FILETABLESIZE;i++){
91     fileDescCallbacks[i] = NULL;
92     fileDesc[i] = -1;
93   }
94   for(i=0;i<EVENTSIZE;i++){
95     eventCallbacks[i] = NULL;
96   }
97
98   vp = new visualization(0, NULL, NULL);
99   fileDesc[0] = 0;
100   fileDescCallbacks[0] = visi_callback;
101   initDone = 1;
102
103   return(fileDesc[0]);
104 }
105
106 ///////////////////////////////////////////////////////////
107 // makes initial call to get Metrics and Resources 
108 // for visualizations that do not provide an event that 
109 // invokes the GetMetsRes upcall, this routine should be
110 // called by the visiualizaiton before entering the mainloop
111 ///////////////////////////////////////////////////////////
112 int StartVisi(int argc,
113               char *argv[]){
114
115   if(!initDone)
116     VisiInit();
117
118   // call GetMetricResources with initial metric resource lists
119   if(argc >= 3)
120    vp->GetMetricResource(argv[1],argv[2],0);
121   else
122    vp->GetMetricResource(NULL,NULL,0);
123   return(OK);
124
125 }
126
127
128 ///////////////////////////////////////////////////////////
129 // registration callback routine for paradyn events
130 // sets eventCallbacks[event] to callback routine provided by user
131 ///////////////////////////////////////////////////////////
132 int RegistrationCallback(msgTag event,
133                          int (*callBack)(int)){
134
135   if((event < EVENTSIZE)){
136     eventCallbacks[event] = callBack;
137     return(OK);
138   }
139   else{
140     visi_ErrorHandler(ERROR_SUBSCRIPT,"error in RegistrationCallback");
141     return(ERROR_SUBSCRIPT);
142   }
143 }
144
145 ///////////////////////////////////////////////////////////
146 // fd registration and callback routine registration for user
147 // to register callback routines when they use the provided main routine
148 ///////////////////////////////////////////////////////////
149 int RegFileDescriptors(int *fd, int (*callBack)()){
150   return(OK);
151 }
152
153 ///////////////////////////////////////////////////////////
154 // invokes upcall to paradyn VISIthread associated with the visualization
155 // takes list of current metrics, list of foci, and type of data
156 // (0 for histogram, 1 for scalar). 
157 // currently, only the NULL string, type 0 case is supported 
158 ///////////////////////////////////////////////////////////
159 void GetMetsRes(char *metrics,
160                 char *resource,
161                 int type){
162
163   if(!initDone)
164     VisiInit();
165   vp->GetMetricResource(NULL,NULL,0);
166 }
167
168 ///////////////////////////////////////////////////////////
169 // invokes upcall to paradyn.  Request to stop data for the 
170 // metric associated with metricIndex and resource associated with
171 // resourceIndex
172 ///////////////////////////////////////////////////////////
173 void StopMetRes(int metricIndex,
174                 int resourceIndex){
175
176   if(!initDone)
177     VisiInit();
178   if((metricIndex < dataGrid.NumMetrics()) 
179       && (metricIndex >= 0)
180       && (resourceIndex >= 0)
181       && (resourceIndex <dataGrid.NumResources())){
182     dataGrid[metricIndex][resourceIndex].ClearEnabled();
183     dataGrid[metricIndex][resourceIndex].Invalidate();
184     vp->StopMetricResource(dataGrid.MetricId(metricIndex),
185                            dataGrid.ResourceId(resourceIndex));
186   }
187 }
188
189 ///////////////////////////////////////////////////////////
190 // invokes upcall to paradyn.  Visualization sends phase
191 // definition to paradyn.  
192 ///////////////////////////////////////////////////////////
193 void NamePhase(timeType begin,
194                timeType end,
195                char *name){
196
197   if(!initDone)
198     VisiInit();
199   vp->PhaseName((double)begin,(double)end,name);
200 }
201
202 ///////////////////////////////////////////////////////////
203 //  Visi interface routine.  Receives an array of data 
204 //  values from paradyn, adds them to the datagrid, and
205 //  invokes the callback routine associated with the
206 //  DATAVALUES event.
207 ///////////////////////////////////////////////////////////
208 void visualization::Data(dataValue_Array data){
209
210 int *metricIds, *resourceIds;
211 int noMetrics, noResources;
212 int i,j,metric,ok;
213 int temp,min,max;
214 #ifdef DEBUG
215 int flag = 0;
216 #endif
217
218
219   if(!initDone)
220     VisiInit();
221
222   noMetrics = dataGrid.NumMetrics();
223   noResources = dataGrid.NumResources();
224
225   if((metricIds = (int *)malloc(sizeof(int)*noMetrics)) == NULL){
226       visi_ErrorHandler(ERROR_MALLOC,"error in malloc in visi::Data()");
227   }
228   if((resourceIds = (int *)malloc(sizeof(int)*noResources)) == NULL){
229     visi_ErrorHandler(ERROR_MALLOC,"error in malloc in visi::Data()");
230   }
231
232   for(i=0; i < noMetrics; i++){
233      metricIds[i] = dataGrid.MetricId(i);
234   }
235
236   for(i=0; i < noResources; i++){
237     resourceIds[i] = dataGrid.ResourceId(i);
238   }
239
240   for(i=0; i < data.count; i++){
241
242     // find metric and resource index into dataGrid and add value if found
243     for(j=0;(j<noMetrics)&&(data.data[i].metricId!=metricIds[j]);j++) ;
244     metric = j;
245     for(j=0;(j<noResources)&&(data.data[i].resourceId!=resourceIds[j]);j++) ;
246
247     if((j<noResources) && (metric < noMetrics)){
248
249 #ifdef DEBUG
250        if((!dataGrid[metric][j].Valid()) && (dataGrid[metric][j].Enabled())){
251          fprintf(stderr,"datagrid[%d][%d]: enabled %d valid %d userdata %d\n",
252             metric,j,dataGrid[metric][j].Enabled(),dataGrid[metric][j].Valid(),
253             (int)dataGrid[metric][j].userdata);
254          flag = 1;
255        }
256 #endif
257        dataGrid.AddValue(metric,j,
258                          data.data[i].bucketNum,
259                          (float)data.data[i].data);
260 #ifdef DEBUG
261     if(flag){
262       fprintf(stderr,"datag[%d][%d]:enabled %d valid %d userdata %d fvb = %d\n",
263             metric,j,dataGrid[metric][j].Enabled(),dataGrid[metric][j].Valid(),
264             (int)dataGrid[metric][j].userdata,
265             dataGrid[metric][j].FirstValidBucket());
266       flag = 0;
267     }
268 #endif
269        
270     }
271   } 
272
273   min = max = dataGrid.NumBins()+1;
274   for(i=0; i < noMetrics; i++){
275     for(j=0; j < noResources; j++){
276       if(dataGrid.Valid(i,j)){
277         temp = dataGrid.LastBucketFilled(i,j);  
278         if((temp > -1) && (temp < min))
279           min = temp; 
280       }
281     }
282   }
283
284
285   free(metricIds);
286   free(resourceIds);
287
288   //call user registered callback routine assoc. w/event DATAVALUES
289   if((min > LastBucketSent) // if a new datagrid cross-section has been filled
290      && (min != max)
291      && (eventCallbacks[DATAVALUES] !=  NULL)){ // there is a callback routine 
292
293      LastBucketSent = min;
294      ok = eventCallbacks[DATAVALUES](LastBucketSent);
295   }
296 }
297
298
299 ///////////////////////////////////////////////////////////
300 //  Visi interface routine.  Receives notification of a
301 //  fold event, and the new bucket width.  Invokes
302 //  a fold operation on the datagrid
303 ///////////////////////////////////////////////////////////
304 void visualization::Fold(double newBucketWidth){
305   
306   int ok;
307
308   if(!initDone)
309     VisiInit();
310
311   dataGrid.Fold(newBucketWidth);
312   // assume a fold can only occur when datagrid histogram buckets are full
313   LastBucketSent = (dataGrid.NumBins()/2) - 1;
314
315   //call user registered callback routine assoc. w/event FOLD
316   if(eventCallbacks[FOLD] !=  NULL){
317      ok = eventCallbacks[FOLD](0);
318   }
319 }
320
321 ///////////////////////////////////////////////////////////
322 // Visi interface routine.  Receives notification of an
323 // invalid metric/resource pair.  Invalidataes the datagrid
324 // cell associated with the metricId m and resourceId r.
325 ///////////////////////////////////////////////////////////
326 void visualization::InvalidMR(int m, int r){
327
328 int i,j;
329 int ok;
330
331   if(!initDone)
332     VisiInit();
333
334   // search for indices associated with metricId m and
335   // resourceId r
336   for(i=0;
337      (i<dataGrid.NumMetrics())
338      &&(m!=dataGrid.MetricId(i)); i++) ;
339   for(j=0;
340       (j<dataGrid.NumResources())
341       &&(r!=dataGrid.ResourceId(j)); j++) ;
342
343   dataGrid[i][j].ClearEnabled();
344   ok = dataGrid.Invalidate(i,j);
345
346   //call callback routine assoc. w/event INVALIDMETRICSRESOURCES 
347   if(eventCallbacks[INVALIDMETRICSRESOURCES] != NULL){
348      ok = eventCallbacks[INVALIDMETRICSRESOURCES](0);
349   }
350 }
351
352 ///////////////////////////////////////////////////////////
353 // Visi interface routine.  Receives a list of metrics and
354 // resources to add to the datagrid.
355 ///////////////////////////////////////////////////////////
356 void visualization::AddMetricsResources(metricType_Array metrics,
357                                         resourceType_Array resources,
358                                         double bucketWidth,
359                                         int nobuckets){
360   int ok,i;
361   visi_metricType *mets = 0;
362   visi_resourceType *res = 0;
363   int numRes, numMet;
364   int metId, resId, max, k;
365
366   if(!initDone)
367     VisiInit();
368
369   // this is first set of metrics/resources, construct new dataGrid
370   if(!dataGrid.NumMetrics()){
371     //construct metric, resource lists
372     metricList.visi_MRList(metrics.count,
373                            (visi_metricType *)metrics.data);
374     resourceList.visi_MRList(resources.count,
375                              (visi_resourceType *)resources.data);
376
377     // construct new dataGrid 
378     dataGrid.visi_DataGrid(metrics.count,
379                         resources.count,
380                         (visi_metricType *)metrics.data,
381                         (visi_resourceType *)resources.data,
382                         nobuckets,
383                         (timeType)bucketWidth);
384   }
385   else{ // add elements to existing data grid
386
387     // create list of new resources and add them to resource list
388     res=(visi_resourceType *)malloc(sizeof(visi_resourceType)*resources.count);
389     numRes = 0;
390
391     for(i=0; i < resources.count; i++){
392       if(!dataGrid.ResourceInGrid(resources.data[i].Id)){
393 #ifdef DEBUG
394           fprintf(stderr,"resource %s Id = %d is new\n",resources.data[i].name,
395                  resources.data[i].Id);
396 #endif
397           if(!resources.data[i].name)
398             res[numRes].name = NULL;
399           else
400             res[numRes].name = strdup(resources.data[i].name);
401           res[numRes++].Id = resources.data[i].Id;
402           resourceList.AddElements(1,resources.data[i].name);
403       }
404     }
405 #ifdef DEBUG
406     fprintf(stderr,"number of new resources = %d\n",numRes);
407 #endif
408
409     // add new resources to dataGrid
410     if(numRes > 0)
411       dataGrid.AddNewResource(numRes,res);
412
413     // create list of new metrics and add them to metricsList
414     mets = (visi_metricType *)malloc(sizeof(visi_metricType)*metrics.count);
415     numMet = 0;
416     for(i=0; i < metrics.count; i++){
417       if(!dataGrid.MetricInGrid(metrics.data[i].Id)){
418
419 #ifdef DEBUG
420           fprintf(stderr,"metric %s Id = %d is new\n",metrics.data[i].name,
421                  metrics.data[i].Id);
422 #endif
423         if(!metrics.data[i].name)
424           mets[numMet].name = NULL;
425         else
426           mets[numMet].name = strdup(metrics.data[i].name);
427         if(!metrics.data[i].units)
428           mets[numMet].units = NULL;
429         else
430           mets[numMet].units = strdup(metrics.data[i].units);
431         mets[numMet].Id = metrics.data[i].Id;
432         mets[numMet++].aggregate = metrics.data[i].aggregate;
433         metricList.AddElements(1,metrics.data[i].name);
434       }
435     }
436 #ifdef DEBUG
437     fprintf(stderr,"number of new metrics = %d\n",numMet);
438 #endif
439
440     // add new metrics to dataGrid
441     if(numMet > 0)
442       dataGrid.AddNewMetrics(numMet,mets);
443
444   }
445
446   // set enabled for the cross product of the metrics and resources 
447   for(k = 0; k < resources.count; k++){
448       // find current resource index
449       max = dataGrid.NumResources();
450       for(resId = 0;
451           (resId < max) 
452           && (dataGrid.ResourceId(resId) != resources.data[k].Id);
453           resId++) ;
454        
455       if(resId < max){
456           max = dataGrid.NumMetrics();
457           for(i = 0; i < metrics.count; i++){
458               // find metric index
459               for( metId = 0; 
460                    (metId < max) 
461                    && (dataGrid.MetricId(metId) != metrics.data[i].Id);
462                    metId++) ;
463               if(metId < max){
464                   dataGrid[metId][resId].SetEnabled();
465               }
466           }
467       }
468   }
469  
470   //call callback routine assoc. w/event ADDMETRICSRESOURCES 
471   if(eventCallbacks[ADDMETRICSRESOURCES] !=  NULL){
472      ok = eventCallbacks[ADDMETRICSRESOURCES](0);
473   }
474 }
475
476 ///////////////////////////////////////////////////////////
477 // Visi interface routine.   Receives an array of histogram 
478 // values for the datagrid cell indicated by metricId and 
479 // resourceId 
480 ///////////////////////////////////////////////////////////
481 void visualization::BulkDataTransfer(float_Array values,
482                                      int metricId,
483                                      int resourceId){
484 int i, lastBucket, temp, j;
485 int noMetrics, noResources;
486 int met = -1, res = -1;
487
488
489     // find datagrid indicies associated with metricId, resourceId 
490     noMetrics = dataGrid.NumMetrics();
491     noResources = dataGrid.NumResources();
492     for(i = 0; i < noMetrics; i++){
493         if(dataGrid.MetricId(i) == metricId)
494             met = i;
495     }
496     for(i = 0; i < noResources; i++){
497         if(dataGrid.ResourceId(i) == resourceId)
498             res = i;
499     }
500     if((met == -1) || (res == -1))  return; 
501
502     // add new data values to datagrid
503     for(i = 0; i < values.count; i++){
504        if(!isnan(values.data[i])){
505            dataGrid.AddValue(met, res, i, (float)values.data[i]);
506        }
507     }
508    
509     // find last full cross section for new dataGrid 
510     lastBucket = dataGrid.NumBins()+1;
511     for(i=0; i < noMetrics; i++){
512         for(j=0; j < noResources; j++){
513             if(dataGrid.Valid(i,j)){
514                 temp = dataGrid.LastBucketFilled(i,j);  
515                 if((temp > -1) && (temp < lastBucket))
516                 lastBucket = temp; 
517             }
518         }
519     }
520
521     // call DATAVALUES callback routine
522     if(eventCallbacks[DATAVALUES] !=  NULL){
523        i = eventCallbacks[DATAVALUES](lastBucket);
524     }
525
526 }
527
528
529 ///////////////////////////////////////////////////////////
530 // Visi interface routine.  Visualization recieves Phase
531 // information from Paradyn.
532 ///////////////////////////////////////////////////////////
533 void visualization::Phase(double begin,
534                           double end,
535                           String name){
536
537 int size,ok;
538
539   if(!initDone)
540     VisiInit();
541   size = strlen(name);
542    
543   //call callback routine assoc. w/event PHASENAME
544   if(eventCallbacks[PHASENAME] !=  NULL){
545      ok = eventCallbacks[PHASENAME](0);
546   }
547 }
548