added 2 bool params to visi_DefinePhase
[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.42  1996/02/23 17:47:16  tamches
18 /* added 2 bool params to visi_DefinePhase
19 /*
20  * Revision 1.41  1996/01/26 19:24:26  newhall
21  * changes so that visiLib can be used by C visis
22  *
23  * Revision 1.40  1996/01/19  20:55:44  newhall
24  * more chages to visiLib interface
25  *
26  * Revision 1.39  1996/01/17 18:29:18  newhall
27  * reorginization of visiLib
28  *
29  * Revision 1.38  1996/01/05 20:02:43  newhall
30  * changed parameters to showErrorVisiCallback, so that visilib users are
31  * not forced into using our string class
32  *
33  * Revision 1.37  1995/12/18 23:22:05  newhall
34  * changed metric units type so that it can have one of 3 values (normalized,
35  * unnormalized or sampled)
36  *
37  * Revision 1.36  1995/12/18 17:22:07  naim
38  * Adding function showErrorVisiCallback to display error messages from
39  * visis - naim
40  *
41  * Revision 1.35  1995/12/15  20:15:24  naim
42  * Adding call back function to display error messages from visis - naim
43  *
44  * Revision 1.34  1995/11/17  17:28:40  newhall
45  * added normalized member to Metric class which specifies units type
46  * added MetricLabel, MetricAveLabel, and MetricSumLabel DG method functions
47  *
48  * Revision 1.33  1995/11/13  17:24:25  newhall
49  * bug fix
50  *
51  * Revision 1.32  1995/11/12  23:29:55  newhall
52  * removed warnings, removed error.C
53  *
54  * Revision 1.31  1995/11/12  00:45:19  newhall
55  * added PARADYNEXITED event, added "InvalidSpans" dataGrid method
56  *
57  * Revision 1.30  1995/11/02  02:12:51  newhall
58  * added class derived from igen generated visualization class that contains
59  * a handle_error method that won't print an error msg when an error occurs
60  *
61  * Revision 1.29  1995/09/18  18:26:06  newhall
62  * updated test subdirectory, added visilib routine GetMetRes()
63  *
64  * Revision 1.28  1995/09/08  19:47:00  krisna
65  * stupid way to avoid the for-scope problem
66  *
67  * Revision 1.27  1995/08/05 17:12:18  krisna
68  * use `0' instead of `NULL'
69  *
70  * Revision 1.26  1995/08/01 01:59:35  newhall
71  * changes relating to phase interface stuff
72  *
73  * Revision 1.25  1995/06/02  21:02:06  newhall
74  * changed type of metric and focus handles to u_int
75  *
76  * Revision 1.24  1995/03/31  15:56:11  jcargill
77  * Changed malloc's to new's, so that constructors would get fired;
78  * otherwise, bogus memory references/free's occur.
79  *
80  * Revision 1.23  1995/02/26  01:59:40  newhall
81  * added phase interface functions
82  *
83  * Revision 1.22  1995/02/16  09:31:03  markc
84  * Modified NaN generation code for machines that do not have nan.h.
85  * This code has not been tested.
86  *
87  * Revision 1.21  1995/01/30  17:35:27  jcargill
88  * Updated igen-generated includes to new naming convention
89  *
90  * Revision 1.20  1994/11/02  04:15:00  newhall
91  * memory leak fixes
92  *
93  * Revision 1.19  1994/10/13  15:39:17  newhall
94  * QuitVisi added
95  *
96  * Revision 1.18  1994/09/30  21:00:51  newhall
97  * use datagrid method functions MetricId and ResourceId
98  *
99  * Revision 1.17  1994/09/25  02:00:29  newhall
100  * changes to visi interface routines that take list of met/focus pairs:
101  * AddMetricsResources, GetMetRes
102  * and changes to support the new version of igen
103  *
104  * Revision 1.16  1994/09/22  03:14:41  markc
105  * declared arrays at start
106  * incremented version number
107  *
108  * Added stronger compiler warnings
109  * removed compiler warnings
110  *
111  * Revision 1.15  1994/08/13  20:34:50  newhall
112  * removed all code associated with class visi_MRList
113  * removed mrlist src and obj
114  * removed
115  *
116  * Revision 1.14  1994/08/11  02:52:11  newhall
117  * removed calls to grid cell Deleted member functions
118  *
119  * Revision 1.13  1994/08/03  20:49:12  newhall
120  * removed code for interface routines NewMetricsResources and Enabled
121  * changed AddMetricsResources to set grid cell's enabled flag
122  *
123  * Revision 1.12  1994/07/30  03:27:27  newhall
124  * added visi interface functions Enabled and BulkDataTransfer
125  *
126  * Revision 1.11  1994/07/20  22:41:11  rbi
127  * Small arguments fix to make identification of wildcards easier.
128  *
129  * Revision 1.10  1994/07/07  22:40:31  newhall
130  * fixed compile warnings
131  *
132  * Revision 1.9  1994/06/16  18:24:53  newhall
133  * fix to visualization::Data
134  *
135  * Revision 1.8  1994/06/07  17:48:49  newhall
136  * support for adding metrics and resources to existing visualization
137  *
138  * Revision 1.7  1994/05/23  20:56:48  newhall
139  * To visi_GridCellHisto class: added deleted flag, SumValue
140  * method function, and fixed AggregateValue method function
141  *
142  * Revision 1.6  1994/05/11  17:13:14  newhall
143  * changed data type from double to float
144  *
145  * Revision 1.5  1994/04/13  21:34:54  newhall
146  * added routines: GetMetsRes StopMetRes NamePhase
147  *
148  * Revision 1.4  1994/03/26  04:19:49  newhall
149  * changed all floats to double
150  * fix problem with null string returned for first resource name
151  *
152  * Revision 1.3  1994/03/17  05:23:09  newhall
153  * changed eventCallbacks type, and the constraints on triggering the
154  * callback routine associated with the DATAVALUES event
155  *
156  * Revision 1.2  1994/03/14  20:28:55  newhall
157  * changed visi subdirectory structure
158  *  */ 
159 #include <stream.h> 
160 #include "visi/src/visualizationP.h"
161 #include "visi/src/datagridP.h"
162 #include "visi/src/visiTypesP.h"
163 #include "util/h/makenan.h"
164 #include "visi/h/visualization.h"
165
166 #define MAXSTRINGSIZE  16*1024
167 #define EVENTSIZE      FOLD+1
168
169 static visi_DataGrid  visi_dataGrid;
170 static int            visi_LastBucketSent = -1;
171 static int visi_fileDesc;
172 static int (*visi_fileDescCallbacks)();
173 static int (*visi_eventCallbacks[EVENTSIZE])(int);
174 static int visi_initDone = 0;
175 static visualization *visi_vp;
176
177 // TODO -- better error checking here?
178 int visi_callback(){
179   return(visi_vp->waitLoop());
180 }
181
182 ///////////////////////////////////////////////////////////
183 // paradyn initialization routine connects to parent socket,
184 // and registers the visualization::mainLoop routine as 
185 // callback on events on fileDesc[0]
186 ///////////////////////////////////////////////////////////
187 int visi_Init(){
188
189 int i;
190
191   visi_fileDescCallbacks = NULL;
192   visi_fileDesc = -1;
193   for(i=0;i<EVENTSIZE;i++){
194     visi_eventCallbacks[i] = NULL;
195   }
196
197   visi_vp = new visi_visualization(0);
198   visi_fileDesc = 0;
199   visi_fileDescCallbacks = visi_callback;
200   visi_initDone = 1;
201  
202   // make request for info. about all phases defined so far 
203   visi_vp->GetPhaseInfo();
204
205   return(visi_fileDesc);
206 }
207
208 ///////////////////////////////////////////////////////////
209 // makes initial call to get Metrics and Resources 
210 // for visualizations that do not provide an event that 
211 // invokes the GetMetsRes upcall, this routine should be
212 // called by the visiualizaiton before entering the mainloop
213 ///////////////////////////////////////////////////////////
214 int visi_StartVisi(int argc,
215               char *argv[]){
216
217   if(!visi_initDone)
218     visi_Init();
219
220   // call GetMetricResources with initial metric resource lists
221   if(argc == 3)
222    visi_vp->GetMetricResource(argv[1],(int)argv[2],0);
223   else
224    visi_vp->GetMetricResource("",0,0);
225   return(OK);
226
227 }
228
229 ///////////////////////////////////////////////////////////
230 // cleans up visi interface data structs 
231 // Visualizations should call this routine before exiting 
232 ///////////////////////////////////////////////////////////
233 void visi_QuitVisi(){
234
235     delete visi_vp;
236 }
237
238 //
239 // call back to Paradyn to display error message
240 //
241 void visi_showErrorVisiCallback(const char *msg)
242 {
243   int string_size;
244   string new_msg = msg; 
245   string_size = (new_msg.length())*sizeof(char);
246   if (string_size < MAXSTRINGSIZE)
247     visi_vp->showError(87,new_msg);
248   else {
249     string errmsg;
250     errmsg = string("Internal Error: error message has exceeded maximum length of ") + string(MAXSTRINGSIZE) + string(" bytes. Please, make your error message shorter.");
251     visi_vp->showError(87,errmsg);
252   }
253 }  
254
255 ///////////////////////////////////////////////////////////
256 // registration callback routine for paradyn events
257 // sets eventCallbacks[event] to callback routine provided by user
258 ///////////////////////////////////////////////////////////
259 int visi_RegistrationCallback(visi_msgTag event,
260                          int (*callBack)(int)){
261
262   if((event < EVENTSIZE)){
263     visi_eventCallbacks[event] = callBack;
264     return(OK);
265   }
266   return(ERROR_INT);
267 }
268
269 ///////////////////////////////////////////////////////////
270 // invokes upcall to paradyn VISIthread associated with the visualization
271 // takes list of current metrics, list of foci, and type of data
272 // (0 for histogram, 1 for scalar). 
273 // currently, only the NULL string, type 0 case is supported 
274 ///////////////////////////////////////////////////////////
275 void visi_GetMetsRes(char *, int){
276
277   if(!visi_initDone)
278     visi_Init();
279   visi_vp->GetMetricResource(0,0,0);
280 }
281
282
283 ///////////////////////////////////////////////////////////
284 // invokes upcall to paradyn.  Request to stop data for the 
285 // metric associated with metricIndex and resource associated with
286 // resourceIndex
287 ///////////////////////////////////////////////////////////
288 void visi_StopMetRes(int metricIndex,
289                      int resourceIndex){
290
291   if(!visi_initDone)
292     visi_Init();
293   if((metricIndex < visi_dataGrid.NumMetrics()) 
294       && (metricIndex >= 0)
295       && (resourceIndex >= 0)
296       && (resourceIndex <visi_dataGrid.NumResources())){
297     visi_dataGrid[metricIndex][resourceIndex].ClearEnabled();
298     visi_dataGrid[metricIndex][resourceIndex].Invalidate();
299     bool met_error = false;
300     bool res_error = false;
301     u_int m = visi_dataGrid.MetricId(metricIndex,met_error);
302     u_int r = visi_dataGrid.ResourceId(resourceIndex,res_error);
303     if((!met_error) && (!res_error)){
304         visi_vp->StopMetricResource(m,r);
305     }
306   }
307 }
308
309 ///////////////////////////////////////////////////////////
310 // invokes upcall to paradyn.  Visualization sends phase
311 // definition to paradyn.  
312 ///////////////////////////////////////////////////////////
313 void visi_DefinePhase(char *name, bool withPerfConsult,
314                       bool withVisis) {
315   if(!visi_initDone)
316     visi_Init();
317   visi_vp->StartPhase((double)-1.0, name, withPerfConsult, withVisis);
318 }
319
320 ///////////////////////////////////////////////////////////
321 //  Visi interface routine.  Receives an array of data 
322 //  values from paradyn, adds them to the datagrid, and
323 //  invokes the callback routine associated with the
324 //  DATAVALUES event.
325 ///////////////////////////////////////////////////////////
326 void visualization::Data(vector<T_visi::dataValue> data){
327
328   if(!visi_initDone)
329     visi_Init();
330
331   int noMetrics = visi_dataGrid.NumMetrics();
332   int noResources = visi_dataGrid.NumResources();
333
334   // get metric and resource index into visi_dataGrid and add value if found
335   for(unsigned i=0; i < data.size(); i++){
336       int metric = visi_dataGrid.MetricIndex(data[i].metricId);
337       int j = visi_dataGrid.ResourceIndex(data[i].resourceId);
338       if((j >= 0) && (metric >= 0)){
339          visi_dataGrid.AddValue(metric,j,
340                          data[i].bucketNum,
341                          data[i].data);
342   }} 
343
344   int min;
345   int max = visi_dataGrid.NumBins()+1;
346   min = max;
347   for(int i2=0; i2 < noMetrics; i2++){
348       for(int k=0; k < noResources; k++){
349           if(visi_dataGrid.Valid(i2,k)){
350               int temp = visi_dataGrid.LastBucketFilled(i2,k);  
351               if((temp > -1) && (temp < min))
352               min = temp; 
353   }}}
354
355   //call user registered callback routine assoc. w/event DATAVALUES
356   if((min > visi_LastBucketSent) //if new datagrid cross-section has been filled
357      && (min != max)
358      && (visi_eventCallbacks[DATAVALUES]!=NULL)){ //theres a callback routine 
359        visi_LastBucketSent = min;
360        visi_eventCallbacks[DATAVALUES](visi_LastBucketSent);
361   }
362 }
363
364
365 ///////////////////////////////////////////////////////////
366 //  Visi interface routine.  Receives notification of a
367 //  fold event, and the new bucket width.  Invokes
368 //  a fold operation on the datagrid
369 ///////////////////////////////////////////////////////////
370 void visualization::Fold(double newBucketWidth){
371   
372   int ok;
373
374   if(!visi_initDone)
375     visi_Init();
376
377   visi_dataGrid.Fold(newBucketWidth);
378   // assume a fold can only occur when datagrid histogram buckets are full
379   visi_LastBucketSent = (visi_dataGrid.NumBins()/2) - 1;
380
381   //call user registered callback routine assoc. w/event FOLD
382   if(visi_eventCallbacks[FOLD] !=  NULL){
383      ok = visi_eventCallbacks[FOLD](0);
384   }
385 }
386
387 ///////////////////////////////////////////////////////////
388 // Visi interface routine.  Receives notification of an
389 // invalid metric/resource pair.  Invalidataes the datagrid
390 // cell associated with the metricId m and resourceId r.
391 ///////////////////////////////////////////////////////////
392 void visualization::InvalidMR(u_int m, u_int r){
393
394 int i,j;
395 int ok;
396
397   if(!visi_initDone)
398     visi_Init();
399
400   // search for indices associated with metricId m and
401   // resourceId r
402   bool error = false;
403   for(i=0; (i<visi_dataGrid.NumMetrics()) &&(m != visi_dataGrid.MetricId(i,error)); i++){
404       if(error) return;
405   } 
406
407   for(j=0;(j<visi_dataGrid.NumResources())&&(r!= visi_dataGrid.ResourceId(j,error));j++){
408       if(error) return;
409   }
410
411   visi_dataGrid[i][j].ClearEnabled();
412   ok  = visi_dataGrid.Invalidate(i,j);
413
414   //call callback routine assoc. w/event INVALIDMETRICSRESOURCES 
415   if(visi_eventCallbacks[INVALIDMETRICSRESOURCES] != NULL){
416      ok = visi_eventCallbacks[INVALIDMETRICSRESOURCES](0);
417   }
418 }
419
420 ///////////////////////////////////////////////////////////
421 // Visi interface routine.  Receives a list of metrics and
422 // resources to add to the datagrid.
423 ///////////////////////////////////////////////////////////
424 void visualization::AddMetricsResources(vector<T_visi::visi_matrix> newElements,
425                                         double bucketWidth,
426                                         int nobuckets,
427                                         double start_time,
428                                         int phase_handle){
429
430
431   int ok;
432   visi_metricType *mets = 0;
433   visi_resourceType *res = 0;
434   int numRes, numMet;
435
436   if(!visi_initDone)
437     visi_Init();
438
439   // this is first set of metrics/resources, construct new visi_dataGrid
440   if(!visi_dataGrid.NumMetrics()){
441     // create list of all unique metric and resource entries
442     // in newElements
443     numRes = 0;
444     numMet = 0;
445     if((res= new visi_resourceType [newElements.size()]) == NULL){ 
446         return;
447     }                              
448     if((mets= new visi_metricType [newElements.size()]) == NULL){
449         return;
450     }                              
451     for(unsigned i = 0; i < newElements.size(); i++){
452         ok = 0;
453         for(int j=0; (j < numMet) && (!ok);j++){
454            if(newElements[i].met.Id == mets[j].Id)
455              ok = 1;
456         }
457         if(!ok){
458             if(!newElements[i].met.name.length())
459                 mets[numMet].name = NULL;
460             else
461                 mets[numMet].name = newElements[i].met.name.string_of();
462             if(!newElements[i].met.units.length())
463                 mets[numMet].units = NULL;
464             else
465                 mets[numMet].units = newElements[i].met.units.string_of();
466             mets[numMet].Id = newElements[i].met.Id;
467             if(newElements[i].met.unitstype == 0){
468                 mets[numMet].unitstype = UnNormalized;
469             }
470             else if(newElements[i].met.unitstype == 1){
471                 mets[numMet].unitstype = Normalized;
472             }
473             else {
474                 mets[numMet].unitstype = Sampled;
475             }
476             mets[numMet++].aggregate = newElements[i].met.aggregate;
477         }
478           ok = 0;
479         for(int j2=0; (j2 < numRes) && (!ok);j2++){
480            if(newElements[i].res.Id == res[j2].Id)
481              ok = 1;
482         }
483         if(!ok){
484             if(!newElements[i].res.name.length())
485                 res[numRes].name = NULL;
486             else
487                 res[numRes].name = newElements[i].res.name.string_of();
488             res[numRes++].Id = newElements[i].res.Id;
489         }
490     }
491
492     // construct new visi_dataGrid 
493     visi_dataGrid.visi_DataGrid(numMet,
494                            numRes,
495                            mets,
496                            res,
497                            nobuckets,
498                            (visi_timeType)bucketWidth,
499                            (visi_timeType)start_time,
500                            phase_handle);
501   }
502   else{ // add elements to existing data grid
503
504     // create list of new resources and add them to resource list
505     res= new visi_resourceType [newElements.size()];
506     numRes = 0;
507     for(unsigned i=0; i < newElements.size(); i++){
508       if(!visi_dataGrid.ResourceInGrid(newElements[i].res.Id)){
509           ok = 0;
510           for(int k=0; (k < numRes) && !ok; k++){
511              if(newElements[i].res.Id == res[k].Id)
512                ok = 1;
513           }
514           if(!ok){
515               if(!newElements[i].res.name.length())
516                 res[numRes].name = NULL;
517               else
518                 res[numRes].name = newElements[i].res.name.string_of();
519               res[numRes++].Id = newElements[i].res.Id;
520           }
521     }}
522
523     // add new resources to visi_dataGrid
524     if(numRes > 0)
525       visi_dataGrid.AddNewResource(numRes,res);
526
527     // create list of new metrics and add them to metricsList
528     mets = new visi_metricType [newElements.size()];
529     numMet = 0;
530     for(unsigned i2=0; i2 < newElements.size(); i2++){
531       if(!visi_dataGrid.MetricInGrid(newElements[i2].met.Id)){
532
533           ok = 0;
534           for(int k2=0; (k2 < numMet) && !ok; k2++){
535              if(newElements[i2].met.Id == mets[k2].Id)
536                ok = 1;
537           }
538           if(!ok){
539               if(!newElements[i2].met.name.length())
540                   mets[numMet].name = NULL;
541               else
542                   mets[numMet].name = newElements[i2].met.name.string_of();
543               if(!newElements[i2].met.units.length())
544                   mets[numMet].units = NULL;
545               else
546                   mets[numMet].units = newElements[i2].met.units.string_of();
547             mets[numMet].Id = newElements[i2].met.Id;
548             if(newElements[i2].met.unitstype == 0){
549                 mets[numMet].unitstype = UnNormalized;
550             }
551             else if(newElements[i2].met.unitstype == 1){
552                 mets[numMet].unitstype = Normalized;
553             }
554             else {
555                 mets[numMet].unitstype = Sampled;
556             }
557             mets[numMet++].aggregate = newElements[i2].met.aggregate;
558         }
559     }}
560
561     // add new metrics to visi_dataGrid
562     if(numMet > 0)
563       visi_dataGrid.AddNewMetrics(numMet,mets);
564   }
565
566   // set enabled for every element of newElements list 
567   for(unsigned r = 0; r < newElements.size(); r++){
568      visi_dataGrid[visi_dataGrid.MetricIndex(newElements[r].met.Id)][visi_dataGrid.ResourceIndex(newElements[r].res.Id)].SetEnabled();
569   }
570  
571   delete [] mets;
572   delete [] res;
573   //call callback routine assoc. w/event ADDMETRICSRESOURCES 
574   if(visi_eventCallbacks[ADDMETRICSRESOURCES] !=  NULL){
575      ok = visi_eventCallbacks[ADDMETRICSRESOURCES](0);
576   }
577 }
578
579 ///////////////////////////////////////////////////////////
580 // Visi interface routine.   Receives an array of histogram 
581 // values for the datagrid cell indicated by metricId and 
582 // resourceId 
583 ///////////////////////////////////////////////////////////
584 void visualization::BulkDataTransfer(vector<float> values,
585                                      u_int metricId,
586                                      u_int resourceId){
587 int lastBucket, temp, j;
588 int noMetrics, noResources;
589 int met,res;
590
591
592     // find datagrid indicies associated with metricId, resourceId 
593     noMetrics = visi_dataGrid.NumMetrics();
594     noResources = visi_dataGrid.NumResources();
595     bool found = false;
596     bool error = false;
597     for(int i = 0; i < noMetrics; i++){
598         u_int m_id = visi_dataGrid.MetricId(i,error);
599         if(!error){
600             if(m_id == metricId){
601                 met = i;
602                 found = true;
603             }
604         }
605     }
606
607     if(!found) return;
608     found = false;
609     error = false;
610     for(int i1 = 0; i1 < noResources; i1++){
611         u_int r_id = visi_dataGrid.ResourceId(i1,error);  
612         if(!error){
613             if(r_id == resourceId){
614                 res = i1;
615                 found = true;
616             }
617         }
618     }
619     if(!found) return;
620
621     // add new data values to datagrid
622     for(unsigned i2 = 0; i2 < values.size(); i2++){
623        if(!isnan(values[i2])){
624            visi_dataGrid.AddValue(met, res, i2, values[i2]);
625        }
626     }
627    
628     // find last full cross section for new visi_dataGrid 
629     lastBucket = visi_dataGrid.NumBins()+1;
630     for(int i3=0; i3 < noMetrics; i3++){
631         for(j=0; j < noResources; j++){
632             if(visi_dataGrid.Valid(i3,j)){
633                 temp = visi_dataGrid.LastBucketFilled(i3,j);  
634                 if((temp > -1) && (temp < lastBucket))
635                 lastBucket = temp; 
636             }
637         }
638     }
639
640     // call DATAVALUES callback routine
641     if(visi_eventCallbacks[DATAVALUES] !=  NULL){
642        visi_eventCallbacks[DATAVALUES](lastBucket);
643     }
644
645 }
646
647
648 ///////////////////////////////////////////////////////////
649 // Visi interface routine.  Visualization recieves Phase
650 // start information from Paradyn.
651 ///////////////////////////////////////////////////////////
652 void visualization::PhaseStart(double begin,
653                           double end,
654                           double bucketWidth,
655                           string name,
656                           u_int handle){
657
658   if(!visi_initDone)
659     visi_Init();
660    
661    // add new phase to phase vector
662    visi_dataGrid.AddNewPhase(handle,(visi_timeType)begin,(visi_timeType)end,
663                         (visi_timeType)bucketWidth,name);
664
665   //call callback routine assoc. w/event PHASESTART
666   if(visi_eventCallbacks[PHASESTART] !=  NULL){
667      visi_eventCallbacks[PHASESTART](visi_dataGrid.NumPhases()-1);
668   }
669 }
670
671 ///////////////////////////////////////////////////////////
672 // Visi interface routine.  Visualization recieves Phase
673 // end information from Paradyn.
674 ///////////////////////////////////////////////////////////
675 void visualization::PhaseEnd(double end, u_int handle){
676
677
678   if(!visi_initDone)
679     visi_Init();
680
681    // update phase end time for phase assoc w/handle
682    int ok;
683    if(!(ok = visi_dataGrid.AddEndTime(end,handle))){
684        fprintf(stderr,"in visualization::PhaseEnd: phase end not added\n");
685    }
686    
687   //call callback routine assoc. w/event PHASEEND
688   if(visi_eventCallbacks[PHASEEND] !=  NULL){
689      visi_eventCallbacks[PHASEEND](visi_dataGrid.NumPhases()-1);
690   }
691 }
692
693 ///////////////////////////////////////////////////////////
694 // Visi interface routine.  Visualization recieves list  
695 // of all Phase info from Paradyn.
696 ///////////////////////////////////////////////////////////
697 void visualization::PhaseData(vector<T_visi::phase_info> phases){
698
699   if(!visi_initDone)
700     visi_Init();
701
702   // add an new phase object to the visi_dataGrid's vector of phases
703    for (unsigned i=0; i < phases.size(); i++){ 
704      visi_dataGrid.AddNewPhase(phases[i].handle,
705                 (visi_timeType)phases[i].start,
706                 (visi_timeType)phases[i].end,
707                 (visi_timeType)phases[i].bucketWidth,
708                 phases[i].name.string_of());
709    }
710
711   //call callback routine assoc. w/event PHASEDATA
712   if(visi_eventCallbacks[PHASEDATA] !=  NULL){
713      visi_eventCallbacks[PHASEDATA](0);
714   }
715 }
716
717 void visi_visualization::handle_error(){
718    // call user registered callback routine assoc. w/event PARADYNEXITED
719    if(visi_eventCallbacks[PARADYNEXITED] !=  NULL){
720       visi_eventCallbacks[PARADYNEXITED](0);
721    }
722    // otherwise, exit
723    else {
724       exit(-1);
725    }
726 }
727
728 //***************************** Data Grid Routines ************
729
730 //
731 // returns the ith metric name or 0 on error
732 //
733 const char *visi_MetricName(int metric_num){ 
734     return visi_dataGrid.MetricName(metric_num);
735 }
736
737 //
738 // returns the ith metric units name or 0 on error
739 //
740 const char *visi_MetricUnits(int metric_num){
741     return visi_dataGrid.MetricUnits(metric_num);
742 }
743
744 //
745 // returns the ith metric units label for data values or 0 on error
746 //
747 const char *visi_MetricLabel(int metric_num){
748     return visi_dataGrid.MetricLabel(metric_num);
749 }
750
751 //
752 // returns the ith metric units label for average aggregate data values,
753 // or 0 on error
754 //
755 const char *visi_MetricAveLabel(int metric_num){
756     return visi_dataGrid.MetricAveLabel(metric_num);
757 }
758
759 //
760 // returns the ith metric units label for sum aggregate data values,
761 // or 0 on error
762 //
763 const char *visi_MetricSumLabel(int metric_num){
764     return visi_dataGrid.MetricSumLabel(metric_num);
765 }
766
767 //
768 // returns the ith resource's name,  or 0 on error
769 //
770 const char *visi_ResourceName(int resource_num){
771     return visi_dataGrid.ResourceName(resource_num);
772 }
773
774 //
775 //  returns the number of metrics in the data grid
776 //
777 int visi_NumMetrics(){
778     return visi_dataGrid.NumMetrics();
779 }
780
781 //
782 //  returns the number of resources in the data grid
783 //
784 int visi_NumResources(){
785     return visi_dataGrid.NumResources();
786 }
787
788 //
789 //  returns the number of phases currently defined in the system
790 //
791 u_int visi_NumPhases(){
792     return visi_dataGrid.NumPhases();
793 }
794
795 //
796 // returns the start time of the phase for which this visi is defined
797 //
798 visi_timeType visi_GetStartTime(){
799     return visi_dataGrid.GetStartTime();
800 }
801
802 //
803 // returns the name of the phase for which this visi is defined
804 //
805 const char *visi_GetMyPhaseName(){
806     return visi_dataGrid.GetMyPhaseName();
807 }
808
809 //
810 // returns the handle of the phase for which this visi is defined or
811 // -1 on error
812 //
813 int visi_GetMyPhaseHandle(){
814
815     return (visi_dataGrid.GetPhaseHandle());
816 }
817
818 //
819 // returns the handle of the phase for which this visi is defined or
820 // -1 on error
821 //
822 int visi_GetPhaseHandle(u_int phase_num){
823
824     const PhaseInfo *p = visi_dataGrid.GetPhaseInfo(phase_num);
825     if(p){
826         return (p->getPhaseHandle());
827     }
828     return (-1);
829 }
830
831 //
832 // returns phase name for the ith phase, or returns 0 on error
833 //
834 const char *visi_GetPhaseName(u_int phase_num){
835
836     const PhaseInfo *p = visi_dataGrid.GetPhaseInfo(phase_num);
837     if(p){
838         return (p->getName());
839     }
840     return (0);
841 }
842
843 //
844 // returns phase start time for the ith phase, or returns -1.0 on error
845 //
846 visi_timeType visi_GetPhaseStartTime(u_int phase_num){
847
848     const PhaseInfo *p = visi_dataGrid.GetPhaseInfo(phase_num);
849     if(p){
850         return (p->getStartTime());
851     }
852     return (-1.0);
853 }
854
855 //
856 // returns phase end time for the ith phase, or returns -1.0 on error
857 //
858 visi_timeType visi_GetPhaseEndTime(u_int phase_num){
859
860     const PhaseInfo *p = visi_dataGrid.GetPhaseInfo(phase_num);
861     if(p){
862         return (p->getEndTime());
863     }
864     return (-1.0);
865 }
866
867 //
868 // returns phase bucket width for the ith phase, or returns -1.0 on error
869 //
870 visi_timeType visi_GetPhaseBucketWidth(u_int phase_num){
871
872     const PhaseInfo *p = visi_dataGrid.GetPhaseInfo(phase_num);
873     if(p){
874         return (p->getBucketWidth());
875     }
876     return (-1.0);
877 }
878
879 //
880 // returns the average of all the data bucket values for the metric/resource
881 // pair "metric_num" and "resource_num", returns NaN value on error
882 //
883 visi_sampleType visi_AverageValue(int metric_num, int resource_num){
884     return visi_dataGrid.AggregateValue(metric_num,resource_num);
885 }
886
887 //
888 // returns the sum of all the data bucket values for the metric/resource
889 // pair "metric_num" and "resource_num", returns NaN value on error
890 //
891 visi_sampleType visi_SumValue(int metric_num, int resource_num){
892     return visi_dataGrid.SumValue(metric_num,resource_num);
893 }
894
895 //
896 // returns the data value in bucket "bucket_num" for the metric/resource pair
897 // "metric_num" and "resource_num", returns NaN value on error
898 //
899 visi_sampleType visi_DataValue(int metric_num, int resource_num, int bucket_num){
900     return visi_dataGrid[metric_num][resource_num][bucket_num];
901 }
902
903 //
904 // returns the data values for the metric/resource pair "metric_num" 
905 // and "resource_num", returns NaN value on error
906 //
907 const visi_sampleType *visi_DataValues(int metric_num, int resource_num){
908
909     if((metric_num >= 0) && (metric_num < visi_dataGrid.NumMetrics())
910        && (resource_num >= 0) && (resource_num < visi_dataGrid.NumResources())){
911         return visi_dataGrid[metric_num][resource_num].Value();
912     }
913     return 0;
914 }
915
916 //
917 //  returns true if the data grid cell corresponding to metric_num
918 //  and resource_num contains data
919 //
920 int visi_Valid(int metric_num, int resource_num){
921     if (visi_dataGrid.Valid(metric_num,resource_num))
922         return 1;
923     else
924         return 0;
925 }
926
927 //
928 //  returns true if the data collection has been enabled for metric_num
929 //  and resource_num
930 //
931 int visi_Enabled(int metric_num, int resource_num){
932     if (visi_dataGrid[metric_num][resource_num].Enabled())
933         return 1;
934     else
935         return 0;
936 }
937
938
939 //
940 //  returns the number of buckets in each data grid cell's histogram
941 //
942 int visi_NumBuckets(){
943     return visi_dataGrid.NumBins();
944 }
945
946 //
947 //  returns the buckets width (in seconds) of each data grid cell's histogram
948 //
949 visi_timeType visi_BucketWidth(){
950     return visi_dataGrid.BinWidth();
951 }
952
953 //
954 // returns the first data bucket with valid data values
955 //
956 int visi_FirstValidBucket(int metric_num, int resource_num){
957     return visi_dataGrid[metric_num][resource_num].FirstValidBucket();
958 }
959
960 //
961 // returns the last data bucket with valid data values
962 //
963 int visi_LastBucketFilled(int metric_num,int resource_num){
964     return visi_dataGrid.LastBucketFilled(metric_num, resource_num);
965 }
966
967 //
968 // returns true if there are invalid spans of data between the first
969 // valid bucket and the last bucket filled
970 //
971 int visi_InvalidSpans(int metric_num,int resource_num){
972     if(visi_dataGrid.InvalidSpans(metric_num, resource_num)) return 1;
973     else return 0;
974 }
975
976 //
977 // returns the user data associated with metric_num and resource_num
978 // returns 0 on error
979 //
980 void *visi_GetUserData(int metric_num, int resource_num){
981
982     if((metric_num >= 0) && (metric_num < visi_dataGrid.NumMetrics())
983        && (resource_num >= 0) && (resource_num < visi_dataGrid.NumResources())){
984         return visi_dataGrid[metric_num][resource_num].userdata;
985     }
986     return 0;
987 }
988
989 //
990 // sets the user data associated with metric_num and resource_num
991 //
992 int visi_SetUserData(int metric_num, int resource_num, void *data){
993
994     if((metric_num >= 0) && (metric_num < visi_dataGrid.NumMetrics())
995        && (resource_num >= 0) && (resource_num < visi_dataGrid.NumResources())){
996         visi_dataGrid[metric_num][resource_num].userdata = data;
997         return 1;
998     }
999     return 0;
1000 }
1001