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