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