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