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