removed obsolete parameters from predictedCost callback function defn
[dyninst.git] / paradyn / src / DMthread / DMpublic.C
1 extern "C" {
2 #include <malloc.h>
3 }
4
5 #include <assert.h>
6 #include "dataManager.thread.h"
7 #include "dataManager.thread.SRVR.h"
8 #include "dataManager.thread.CLNT.h"
9 #include "dyninstRPC.xdr.CLNT.h"
10 #include "visi.xdr.h"
11 #include "util/h/sys.h"
12 #include "util/h/Vector.h"
13 #include "util/h/Dictionary.h"
14 #include "util/h/makenan.h"
15 #include "DMmetric.h"
16 #include "DMdaemon.h"
17 #include "DMresource.h"
18 #include "DMperfstream.h"
19 #include "DMphase.h"
20 #include "DMinclude.h"
21 #include "paradyn/src/DMthread/DVbufferpool.h"
22
23 // the argument list passed to paradynds
24 vector<string> paradynDaemon::args = 0;
25 extern bool our_print_sample_arrival;
26
27 void histDataCallBack(sampleValue *buckets,
28                       timeStamp,
29                       int count,
30                       int first,
31                       void *arg,
32                       bool globalFlag)
33 {
34     metricInstance *mi = (metricInstance *) arg;
35     performanceStream *ps = 0;
36
37 #ifdef n_def
38     // debug code that uses tunable constant printSampleArrival
39     if (our_print_sample_arrival){
40         cout << "bucket:  " << first << "value: "
41              << buckets[0] << "   bucketwidth " 
42              << metricInstance::GetGlobalWidth() <<  endl;
43     }
44 #endif
45
46     if(globalFlag) { 
47         // update global data
48         for(unsigned i=0; i < mi->global_users.size(); i++) {
49             ps = performanceStream::find(mi->global_users[i]); 
50             if(ps) {
51                 ps->callSampleFunc(mi->getHandle(), 
52                                    buckets, count, first,GlobalPhase);
53             }
54         }
55       }
56
57     else {  // update just curr. phase data
58         for(unsigned i=0; i < mi->users.size(); i++) {
59             ps = performanceStream::find(mi->users[i]); 
60             if(ps)
61                 ps->callSampleFunc(mi->getHandle(), 
62                                    buckets, count, first,CurrentPhase);
63         }
64       }
65
66     for(int i=first; i < count; i++){
67         if(buckets[i] < 0) printf("bucket %d : %f \n",i,buckets[i]);
68     }
69 }
70
71 //
72 // start_time specifies the phaseType (globalType starts at 0.0) 
73 //
74 void histFoldCallBack(timeStamp width, void *, bool globalFlag)
75 {
76
77     // need to check if current phase also starts at 0.0
78     // if it does, then fold applies to both global and curr phase
79     if(globalFlag){
80       if(metricInstance::GetGlobalWidth() != width) {
81         metricInstance::SetGlobalWidth(width);
82         performanceStream::foldAll(width,GlobalPhase);
83         if(!metricInstance::numCurrHists()){  // change the sampling rate
84           newSampleRate(width);
85         }
86       }
87     }
88     else {  // fold applies to current phase
89         if(metricInstance::GetCurrWidth() != width) {
90             metricInstance::SetCurrWidth(width);
91             performanceStream::foldAll(width,CurrentPhase);
92             newSampleRate(width); // change sampling rate
93         }
94         phaseInfo::setCurrentBucketWidth(width);
95       }
96 }
97
98
99 void dataManager::setResourceSearchSuppress(resourceHandle res, bool newValue)
100 {
101     resource *r = resource::handle_to_resource(res);
102     if(r)
103         r->setSuppress(newValue);
104 }
105
106 void dataManager::setResourceSearchChildrenSuppress(resourceHandle res, 
107                                                     bool newValue)
108 {
109     resource *r = resource::handle_to_resource(res);
110     if(r) r->setSuppressChildren(newValue);
111 }
112
113 void dataManager::setResourceInstSuppress(resourceHandle res, bool newValue)
114 {
115     resource *r = resource::handle_to_resource(res);
116     if (r) paradynDaemon::setInstSuppress(r, newValue);
117 }
118
119 bool dataManager::addDaemon(const char *machine,
120                             const char *login,
121                             const char *name)
122 {
123   // fix args so that if char * points to "" then it pts to NULL
124   string m = 0;
125   if(machine && strlen(machine))  m = machine;
126   string l = 0;
127   if(login && strlen(login)) l = login;
128   string n = 0;
129   if(!name) { 
130       char *temp = 0; 
131       if(!paradynDaemon::setDefaultArgs(temp))
132           return false;
133       n = temp;
134       delete temp;
135   }
136   else {
137       n = name;
138   }
139   return (paradynDaemon::getDaemon(m, l, n));
140 }
141
142 //
143 // define a new entry for the daemon dictionary
144 //
145 bool dataManager::defineDaemon(const char *command,
146                                const char *dir,
147                                const char *login,
148                                const char *name,
149                                const char *machine,
150                                const char *flavor)
151 {
152   if(!name || !command)
153       return false;
154   return (paradynDaemon::defineDaemon(command, dir, login, name, machine, flavor));
155 }
156
157
158 bool dataManager::addExecutable(const char *machine,
159                                 const char *login,
160                                 const char *name,
161                                 const char *dir,
162                                 const vector<string> *argv)
163 {
164     string m = machine;
165     string l = login;
166     string n = name;
167     string d = dir;
168     return(paradynDaemon::newExecutable(m, l, n, d, *argv));
169 }
170
171 bool dataManager::applicationDefined()
172 {
173     return(paradynDaemon::applicationDefined());
174 }
175
176 bool dataManager::startApplication()
177 {
178     return(paradynDaemon::startApplication());
179 }
180
181 bool dataManager::pauseApplication()
182 {
183     return(paradynDaemon::pauseAll());
184 }
185
186 bool dataManager::pauseProcess(int pid)
187 {
188     return(paradynDaemon::pauseProcess(pid));
189 }
190
191 bool dataManager::continueApplication()
192 {
193     return(paradynDaemon::continueAll());
194 }
195
196 bool dataManager::continueProcess(int pid)
197 {
198     return(paradynDaemon::continueProcess(pid));
199 }
200
201 bool dataManager::detachApplication(bool pause)
202 {
203    return(paradynDaemon::detachApplication(pause));
204 }
205
206 perfStreamHandle dataManager::createPerformanceStream(dataType dt,
207                                                       dataCallback dc,
208                                                       controlCallback cc)
209 {
210     int td;
211     performanceStream *ps;
212
213     td = getRequestingThread();
214     ps = new performanceStream(dt, dc, cc, td);
215     return(ps->Handle());
216     ps = 0;
217 }
218
219 int dataManager::destroyPerformanceStream(perfStreamHandle handle){
220
221     performanceStream *ps = performanceStream::find(handle);
222     if(!ps) return(0);
223     delete ps;
224     return(1);
225 }
226
227 //
228 // If "all" is true, then all metrics will be passed regardless the mode.
229 // Otherwise, only those metrics corresponding to the current mode will be
230 // passed.
231 //
232 vector<string> *dataManager::getAvailableMetrics(bool all)
233 {
234     return(metric::allMetricNames(all));
235 }
236
237 //
238 // Same comments as for getAvailableMetrics
239 //
240 vector<met_name_id> *dataManager::getAvailableMetInfo(bool all)
241 {
242     return(metric::allMetricNamesIds(all));
243 }
244
245
246 metricHandle *dataManager::findMetric(const char *name)
247 {
248     string n = name;
249     const metricHandle *met = metric::find(n);
250     if(met){
251         metricHandle *ret = new metricHandle;
252         *ret = *met;
253         return(ret);
254     }
255     return 0;
256 }
257
258 vector<resourceHandle> *dataManager::getRootResources()
259 {
260     return(resource::rootResource->getChildren());
261 }
262
263 resourceHandle *dataManager::getRootResource()
264 {
265     resourceHandle *rh = new resourceHandle;
266     *rh = resource::rootResource->getHandle();
267     return(rh);
268 }
269
270 //
271 // make batched enable request to paradyn daemons
272 //
273 void DMdoEnableData(perfStreamHandle ps_handle,
274                     vector<metricRLType> *request,
275                     u_int request_Id,
276                     phaseType type,
277                     phaseHandle phaseId,
278                     u_int persistent_data,
279                     u_int persistent_collection){
280
281     vector<metricInstance *> *miVec = new vector<metricInstance *>;
282     vector<bool> *enabled = new vector<bool>;  // passed to daemons on enable
283     vector<bool> *done = new vector<bool>;  // used for waiting list
284
285    // for each element in list determine if this metric/focus pair is
286    // already enabled, or is currently being enabled: "enabled" is used to 
287    // indicate whether an enable call needs to be made to the daemon, "done"
288    // indicates if the request needs to wait for a reply from the daemon
289    // "mi" indicates if the metric/focus pair exists
290    //
291    //           not enabled     curr. enabling  error   enabled    
292    //           -----------------------------------------------
293    // done      |  false           false        true    true
294    // enabled   |  false           true         true    true
295    // mi*       |  &mi             &mi            0     &mi
296    //
297    bool need_to_enable = false;
298    bool need_to_wait = false;
299    for(u_int i=0; i < request->size(); i++){
300        // does this metric/focus pair already exist?
301        metricInstance *mi = metricInstance::find((*request)[i].met,
302                                                  (*request)[i].res);
303        if(!mi){ // create new metricInstance 
304            mi = new metricInstance((*request)[i].res,(*request)[i].met,phaseId);
305        }
306        *miVec += mi;
307        if(!mi){  // error case, don't try to enable this mi
308            *enabled += true;
309            *done += true;
310        }
311        else if(!mi->isEnabled()){  // mi not enabled
312            if(mi->isCurrentlyEnabling()){
313                *enabled += true;  // don't try to enable from daemons
314                *done += false;   // need to wait for result
315                need_to_wait = true;
316            }
317            else{
318                *enabled += false;
319                *done += false;  
320                need_to_enable = true;
321            }
322        }
323        else{ // mi already is enabled
324            *enabled += true;
325            *done += true;
326        }
327    }
328
329    assert(enabled->size() == done->size());
330    assert(enabled->size() == miVec->size());
331    assert(enabled->size() == request->size());
332
333    DM_enableType *new_entry = new DM_enableType(ps_handle,type,phaseId,
334                             paradynDaemon::next_enable_id++,request_Id,
335                             miVec,done,enabled,paradynDaemon::allDaemons.size(),
336                             persistent_data,persistent_collection);
337
338    // if there is an MI that has not been enabled yet make enable 
339    // request to daemons or if there is an MI that is currently being
340    // enabled then put request on the outstanding requests list
341    if(need_to_enable || need_to_wait){
342        // for each MI on the request list set increment the EnablesWaiting
343        // flag for the correct phase.  These flags are decremented before
344        // the response is sent to the client
345        if(type == CurrentPhase){
346            for(u_int k=0; k < miVec->size(); k++){
347                if((*miVec)[k]) (*miVec)[k]->incrCurrWaiting(); 
348            }
349        } else{
350            for(u_int k=0; k < miVec->size(); k++){
351                if((*miVec)[k]) (*miVec)[k]->incrGlobalWaiting(); 
352            }
353        }
354        paradynDaemon::enableData(miVec,done,enabled,new_entry,need_to_enable);
355        miVec = 0; enabled = 0;
356        done = 0; new_entry = 0;
357    }
358    else {  // else every MI is enabled update state and return result to caller
359        vector<bool> successful(miVec->size());
360        for(u_int j=0; j < successful.size(); j++){
361            if((*miVec)[j]) successful[j] = true;
362            else successful[j] = false;
363        }
364        DMenableResponse(*new_entry,successful);
365    }
366    delete request;
367 }
368
369 //
370 // Request to enable a set of metric/focus pairs
371 // ps_handle - the perfStreamHandle of the calling thread
372 // request   - vector of metic/focus pairs to enable
373 // request_Id - identifier passed by calling thread
374 // type - which phase type to enable data for
375 // phaseId - the identifier of the phase for which data is requested
376 // persistent_data, persistent_collection - flags for data collection
377 //
378 void dataManager::enableDataRequest(perfStreamHandle ps_handle,
379                                     vector<metric_focus_pair> *request,
380                                     u_int request_Id,
381                                     phaseType type,
382                                     phaseHandle phaseId,
383                                     u_int persistent_data,
384                                     u_int persistent_collection){
385
386     if((type == CurrentPhase) && (phaseId != phaseInfo::CurrentPhaseHandle())){
387         // send enable failed response to calling thread
388         vector<metricInstInfo> *response = 
389                                    new vector<metricInstInfo>(request->size());
390         for(u_int i=0; i < response->size();i++){
391             (*response)[i].successfully_enabled = false;            
392         }
393         // make response call
394         dictionary_hash_iter<perfStreamHandle,performanceStream*>
395                 allS(performanceStream::allStreams);
396         perfStreamHandle h; performanceStream *ps;
397         while(allS.next(h,ps)){
398             if(h == (perfStreamHandle)(ps_handle)){
399                 ps->callDataEnableFunc(response,request_Id);
400                 return;
401         } }
402         delete request;
403         response = 0;
404     }
405
406     // convert request to vector of metricRLType
407     vector<metricRLType> *pairList = new vector<metricRLType>;
408     for(u_int i=0; i < request->size(); i++){
409         metricRLType newPair((*request)[i].met,
410                             resourceList::getResourceList((*request)[i].res)); 
411         *pairList += newPair; 
412     }
413     assert(request->size() == pairList->size());
414
415     DMdoEnableData(ps_handle,pairList,request_Id,type,phaseId,
416                    persistent_data,persistent_collection);    
417     delete request;
418     pairList = 0;
419 }
420
421 //
422 // same as enableDataRequest but with diff type for request 
423 //
424 void dataManager::enableDataRequest2(perfStreamHandle ps,
425                                      vector<metricRLType> *request,
426                                      u_int request_Id,
427                                      phaseType type,
428                                      phaseHandle phaseId,
429                                      u_int persistent_data,
430                                      u_int persistent_collection){
431
432     // TODO: if currphase and phaseId != currentPhaseId then make approp.
433     //       response call to client
434     if((type == CurrentPhase) && (phaseId != phaseInfo::CurrentPhaseHandle())){
435         // send enable failed response to calling thread
436         vector<metricInstInfo> *response = 
437                                    new vector<metricInstInfo>(request->size());
438         for(u_int i=0; i < response->size();i++){
439             (*response)[i].successfully_enabled = false;            
440         }
441         // make response call
442         dictionary_hash_iter<perfStreamHandle,performanceStream*>
443                 allS(performanceStream::allStreams);
444         perfStreamHandle h; performanceStream *ps;
445         while(allS.next(h,ps)){
446             if(h == (perfStreamHandle)(ps)){
447                 ps->callDataEnableFunc(response,request_Id);
448                 return;
449         } }
450         delete request;
451         response = 0;
452     }
453
454     DMdoEnableData(ps,request,request_Id,type,phaseId, persistent_data,
455                    persistent_collection);    
456
457 }
458
459
460 // data is really disabled when there are no current or global users and
461 // when the persistent_collection flag is clear
462 // when persistent_data flag is clear:
463 // current histogram is destroyed when there are no curr users 
464 // global histogram is destroyed whern there are no curr or gloabl users
465 // clear active flag on archived histograms rather than deleting them
466 void dataManager::disableDataCollection(perfStreamHandle handle, 
467                                         metricInstanceHandle mh,
468                                         phaseType type)
469 {
470
471     // cout << " in dataManager::disableDataCollection: mh = " << mh << endl;
472     metricInstance *mi = metricInstance::getMI(mh);
473     if (!mi) return;
474
475     // if this mi is not enabled and there are no outstanding enable
476     // requests then ignore this disable  
477     if(!mi->isEnabled() && 
478        !mi->isGlobalEnableOutstanding() && 
479        !mi->isCurrEnableOutstanding()) return;
480
481     u_int num_curr_users = mi->currUsersCount();
482
483     // remove user from appropriate list
484     if (type == CurrentPhase) {
485         mi->removeCurrUser(handle); 
486     }
487     else {
488         mi->removeGlobalUser(handle);
489     }
490
491     if (mi->isCollectionPersistent()) {
492         // just remove handle from appropriate client list and return
493         return;
494     }
495
496     // really disable MI data collection?  
497     // really disable data when there are no subscribers and
498     // there are no outstanding global or curr enables for this MI      
499     if (!(mi->currUsersCount()) && !mi->isCurrEnableOutstanding()) {
500         u_int num_curr_hists = metricInstance::numCurrHists();
501         if (!(mi->isDataPersistent())){
502             // remove histogram
503             if(mi->deleteCurrHistogram()){
504                 assert(metricInstance::numCurrHists());
505                 metricInstance::decrNumCurrHists();
506             }
507         }
508         else {  // clear active flag on current phase histogram
509             if(mi->data) {
510                 mi->data->clearActive();
511                 mi->data->setFoldOnInactive();
512                 if(num_curr_users){
513                     assert(metricInstance::numCurrHists());
514                     metricInstance::decrNumCurrHists();
515                 }
516         }}
517
518         if (!(mi->globalUsersCount())&& !mi->isGlobalEnableOutstanding()) {
519             mi->dataDisable();  // makes disable call to daemons
520             if (!(mi->isDataPersistent())){
521                 delete mi;      
522                 mi = 0;
523                 assert(metricInstance::numGlobalHists());
524                 metricInstance::decrNumGlobalHists();
525             }
526             else {
527                 if(mi->global_data) {
528                     mi->global_data->clearActive();
529                     mi->global_data->setFoldOnInactive();
530                     assert(metricInstance::numGlobalHists());
531                     metricInstance::decrNumGlobalHists();
532             }}
533         }
534
535         // if this was last curr histogram then set sampling rate to global
536         if((num_curr_hists) && 
537            (!metricInstance::numCurrHists()) &&  
538            (metricInstance::numGlobalHists())){
539
540             float rate = Histogram::getGlobalBucketWidth();
541             newSampleRate(rate);
542         }
543     }
544     // cout << "num global hists " << metricInstance::numGlobalHists() << endl;
545     // cout << "num curr hists " << metricInstance::numCurrHists() << endl;
546     return;
547 }
548
549 //
550 // This routine returns a list of foci which are the result of combining
551 // each child of resource rh with the remaining resources that make up rlh
552 // if the resource rh is a component of the focus rlh, otherwise it returns 0
553 //
554 vector<rlNameId> *dataManager::magnify(resourceHandle rh, 
555                                        resourceListHandle rlh){
556
557     resourceList *rl = resourceList::getFocus(rlh);
558     if(rl){
559         return(rl->magnify(rh));
560     }
561     return 0;
562 }
563
564
565 //
566 // This routine returns a list of foci each of which is the result of combining
567 // a child of one of the resources with the remaining resource components of
568 // rlh, this routine returns 0 if no resource components of rlh have children
569 // The DM allocates the vector, the client is responsible for deallocation
570 //
571 vector<rlNameId> *dataManager::magnify2(resourceListHandle rlh){
572     resourceList *rl = resourceList::getFocus(rlh);
573     if(rl){
574         return (rl->magnify());
575     }
576     return 0;
577 }
578
579
580 //
581 // if resource rh is a decendent of a component of the focus, return a new
582 // focus consisting of rh replaced with it's corresponding entry in rlh,
583 // otherwise return the focus rlh
584 //
585 resourceListHandle *dataManager::constrain(resourceHandle rh,
586                                           resourceListHandle rlh){
587     resourceList *rl = resourceList::getFocus(rlh);
588     if (rl) {
589          resourceListHandle *return_handle = rl->constrain(rh);
590         if(return_handle){
591             return return_handle;
592         }
593     }
594     resourceListHandle *default_handle = new resourceListHandle;
595     *default_handle = rlh;
596     return default_handle;
597 }
598
599 //
600 // like constrain, except it returns 0 on failure
601 //
602 resourceListHandle *dataManager::morespecific(resourceHandle rh,
603                                               resourceListHandle rlh){
604     resourceList *rl = resourceList::getFocus(rlh);
605     if (rl) {
606         return(rl->constrain(rh));
607     }
608     return 0;
609 }
610
611 //
612 // returns true if seppressSearch is true for this focus
613 //
614 bool dataManager::isSuppressed(resourceListHandle rlh){
615
616     resourceList *rl = resourceList::getFocus(rlh);
617     if (rl) {
618         return(rl->isSuppressed());
619     }
620     return 0;
621 }
622
623 //
624 // returns the name for the focus associated with this MI
625 // returns 0 on error
626 //
627 const char *dataManager::getFocusNameFromMI(metricInstanceHandle mh){
628     metricInstance *mi = metricInstance::getMI(mh);
629     if(mi){ 
630         return resourceList::getName(mi->getFocusHandle()); 
631     }
632     return 0;
633 }
634
635 //
636 // setting and clearing persistentCollection or persistentData flags
637 // have no enable/disable side effects 
638 //
639 void dataManager::setPersistentCollection(metricInstanceHandle mh){
640     metricInstance *mi = metricInstance::getMI(mh);
641     if(!mi) return;
642     mi->setPersistentCollection();
643 }
644 void dataManager::clearPersistentCollection(metricInstanceHandle mh){
645     metricInstance *mi = metricInstance::getMI(mh);
646     if(!mi) return;
647     mi->clearPersistentCollection();
648 }
649 void dataManager::setPersistentData(metricInstanceHandle mh){
650     metricInstance *mi = metricInstance::getMI(mh);
651     if(!mi) return;
652     mi->setPersistentData();
653
654 }
655 void dataManager::clearPersistentData(metricInstanceHandle mh){
656     metricInstance *mi = metricInstance::getMI(mh);
657     if(!mi) return;
658     if(mi->clearPersistentData()) delete mi;
659 }
660
661 metricHandle *dataManager::getMetric(metricInstanceHandle mh)
662 {
663     metricInstance *mi = metricInstance::getMI(mh);
664     if(!mi) return 0;
665
666     metricHandle *handle = new metricHandle;
667     *handle = mi->getMetricHandle();
668     return(handle);
669 }
670
671 const char *dataManager::getMetricNameFromMI(metricInstanceHandle mh)
672 {
673     metricInstance *mi = metricInstance::getMI(mh);
674     if(mi){ 
675         return(metric::getName(mi->getMetricHandle()));
676     }
677     return 0;
678 }
679
680 const char *dataManager::getMetricName(metricHandle m)
681 {
682     const char *name = (metric::getName(m));
683     if(name)
684         return(name);
685     return 0;
686 }
687
688 sampleValue dataManager::getMetricValue(metricInstanceHandle mh)
689 {
690     metricInstance *mi = metricInstance::getMI(mh);
691     if(mi) 
692         return(mi->getValue());
693     float ret = PARADYN_NaN;
694     return(ret);
695 }
696
697 sampleValue dataManager::getTotValue(metricInstanceHandle mh)
698 {
699     metricInstance *mi = metricInstance::getMI(mh);
700     if(mi) 
701         return(mi->getTotValue());
702     float ret = PARADYN_NaN;
703     return(ret);
704 }
705
706 //
707 // converts from a vector of resourceHandles to a resourceListHandle
708 //
709 resourceListHandle dataManager::getResourceList(const vector<resourceHandle> *h)
710 {
711   
712     resourceListHandle r = resourceList::getResourceList(*h);
713     return r;
714 }
715
716 //
717 // returns the corresponding focus name for a given resourceHandle vector
718 //
719 const char *dataManager::getFocusName(const vector<resourceHandle> *rh)
720 {
721   resourceListHandle rlh = resourceList::getResourceList(*rh);
722   resourceList *rl = resourceList::getFocus(rlh);
723   if (rl) 
724     return(rl->getName());
725   return 0;
726 }
727
728 //
729 // returns the name for the focus associated with this handle
730 // returns 0 on error
731 //
732 const char *dataManager::getFocusNameFromHandle(resourceListHandle rlh){
733   return resourceList::getName(rlh); 
734 }
735
736
737 //
738 // converts from a resourceListHandle to a vector of resourceHandles
739 //
740 vector<resourceHandle> *dataManager::getResourceHandles(resourceListHandle h)
741 {
742     return resourceList::getResourceHandles(h);
743 }
744
745 //
746 // converts from a resource name to a resourceHandle
747 //
748 resourceHandle *dataManager::findResource(const char *name){
749
750     resourceHandle *rl = new resourceHandle;
751     string r_name = name;
752     if(resource::string_to_handle(r_name,rl)){
753         return(rl);
754     }
755     return 0;
756 }
757
758 //
759 // returns name of resource (this is not a unique representation of 
760 // the name instead it is the unique name trunctated)
761 // so for "/Code/blah.c/foo" this routine will return "foo"
762 //
763 const char *dataManager::getResourceLabelName(resourceHandle h){
764
765      const char *s = resource::getName(h);
766      if(s){
767          return(s);
768      }
769      return 0;
770 }
771
772 //
773 // returns full name of resource ie.  "/Code/blah.c/foo"
774 //
775 const char *dataManager::getResourceName(resourceHandle h){
776
777      const char *s = resource::getFullName(h);
778      if(s){
779          return(s);
780      }
781      return 0;
782 }
783
784 //
785 // converts from a focus name to a resourceListHandle
786 //
787 resourceListHandle *dataManager::findResourceList(const char *name){
788
789     string n = name;
790     const resourceListHandle *temp = resourceList::find(n);
791     if(temp){
792         resourceListHandle *h = new resourceListHandle;
793         *h = *temp;
794         return(h);
795     }
796     return 0;
797 }
798
799
800 void dataManager::getPredictedDataCost(perfStreamHandle ps_handle,
801                                        metricHandle m_handle,
802                                        resourceListHandle rl_handle,
803                                        u_int clientId)
804 {
805     metric *m = metric::getMetric(m_handle);
806     resourceList *rl = resourceList::getFocus(rl_handle);
807     if(m && rl){
808         paradynDaemon::getPredictedDataCostCall(ps_handle,m_handle,
809                                                 rl_handle,rl,m,clientId);
810     }
811     else {
812       cerr << "Error in DMpublic.C, m=NULL\n";
813       assert(0);
814     }
815 }
816
817 // caller provides array of sampleValue to be filled
818 // returns number of buckets filled
819 int dataManager::getSampleValues(metricInstanceHandle mh,
820                                  sampleValue *buckets,
821                                  int numberOfBuckets,
822                                  int first,
823                                  phaseType phase)
824 {
825     metricInstance *mi = metricInstance::getMI(mh);
826     if(mi) 
827         return(mi->getSampleValues(buckets, numberOfBuckets, first, phase));
828     return(0); 
829 }
830
831
832 // fill the passed array of buckets with the archived histogram values
833 // of the passed metricInstance
834 // returns number of buckets filled
835 int dataManager::getArchiveValues(metricInstanceHandle mh,
836                      sampleValue *buckets,
837                      int numberOfBuckets,
838                      int first,
839                      phaseHandle phase_id){
840
841     metricInstance *mi = metricInstance::getMI(mh);
842     if(mi) 
843         return(mi->getArchiveValues(buckets, numberOfBuckets, first, phase_id));
844     return 0;
845 }
846
847
848 void dataManager::printResources()
849 {
850     printAllResources();
851 }
852
853 void dataManager::printStatus()
854 {
855     paradynDaemon::printStatus();
856 }
857
858 void dataManager::coreProcess(int pid)
859 {
860     paradynDaemon::dumpCore(pid);
861 }
862
863 void dataManager::StartPhase(timeStamp start_Time, 
864                              const char *name,
865                              bool with_new_pc,
866                              bool with_visis)
867 {
868     string n = name;
869     phaseInfo::startPhase(start_Time,n,with_new_pc,with_visis);
870     // cout << "in dataManager::StartPhase " << endl;
871     // change the sampling rate
872     if(metricInstance::numCurrHists()){
873        // set sampling rate to curr phase histogram bucket width 
874        float rate = phaseInfo::GetLastBucketWidth();
875        newSampleRate(rate);
876     }
877     else {
878        // set sampling rate to global phase histogram bucket width 
879        float rate = Histogram::getGlobalBucketWidth();
880        newSampleRate(rate);
881     }
882     // cout << "num global hists " << metricInstance::numGlobalHists() << endl;
883     // cout << "num curr hists " << metricInstance::numCurrHists() << endl;
884
885 }
886
887 vector<T_visi::phase_info> *dataManager::getAllPhaseInfo(){
888     return(phaseInfo::GetAllPhaseInfo());
889 }
890
891 //
892 // Now for the upcalls.  We provide code that get called in the thread that
893 //   requested the call back.
894 //
895 void dataManagerUser::newMetricDefined(metricInfoCallback cb,
896                                   perfStreamHandle p_handle,
897                                   const char *name,
898                                   int style,
899                                   int aggregate,
900                                   const char *units,
901                                   metricHandle handle,
902                                   dm_MetUnitsType units_type)
903 {
904     
905     (cb)(p_handle, name, style, aggregate, units, handle, units_type);
906 }
907
908 void dataManagerUser::newResourceDefined(resourceInfoCallback cb,
909                                          perfStreamHandle handle,
910                                          resourceHandle parent,
911                                          resourceHandle newResource,
912                                          const char *name,
913                                          const char *abstr)
914 {
915     (cb)(handle, parent, newResource, name, abstr);
916 }
917
918 void dataManagerUser::changeResourceBatchMode(resourceBatchModeCallback cb,
919                                          perfStreamHandle handle,
920                                          batchMode mode)
921 {
922     (cb)(handle, mode);
923 }
924
925 //
926 // response to enableDataRequest call
927 // func - callback function registered by client thread on createPerfStream
928 // response - vector of enable reponses to enable
929 // request_id - identifier passed by client to enableDataRequest
930 //
931 void dataManagerUser::enableDataCallback(enableDataCallbackFunc func,
932                                          vector<metricInstInfo> *response,
933                                          u_int request_id)
934 {
935     (func)(response, request_id);
936 }
937
938
939 void dataManagerUser::histFold(histFoldCallback cb,
940                                perfStreamHandle handle,
941                                timeStamp width,
942                                phaseType phase_type)
943 {
944     (cb)(handle, width, phase_type);
945 }
946
947 void dataManagerUser::changeState(appStateChangeCallback cb,
948                                   perfStreamHandle handle,
949                                   appState state)
950 {
951     (cb)(handle, state);
952 }
953
954 void dataManagerUser::newPerfData(sampleDataCallbackFunc func, 
955                                   vector<dataValueType> *data,
956                                   u_int num_data_values){
957
958     (func)(data, num_data_values);
959 }
960
961 void dataManagerUser::predictedDataCost(predDataCostCallbackFunc func, 
962                                   metricHandle m_handle,
963                                   resourceListHandle rl_handle,
964                                   float cost,
965                                   u_int clientID){
966
967     (func)(clientID, cost);
968 }
969
970 void dataManagerUser::newPhaseInfo(newPhaseCallback cb,
971                                    perfStreamHandle handle,
972                                    const char *name,
973                                    phaseHandle phase,
974                                    timeStamp begin,
975                                    timeStamp end,
976                                    float bucketwidth,
977                                    bool with_new_pc,
978                                    bool with_visis) {
979
980     (cb)(handle,name,phase,begin,end,bucketwidth,with_new_pc,with_visis);
981 }
982
983
984 T_dyninstRPC::metricInfo *dataManager::getMetricInfo(metricHandle m_handle) {
985
986     const T_dyninstRPC::metricInfo *met = metric::getInfo(m_handle);
987     if(met){ 
988         T_dyninstRPC::metricInfo *copy = new T_dyninstRPC::metricInfo;
989         copy->style = met->style;
990         copy->units = met->units;
991         copy->name = met->name;
992         copy->aggregate = met->aggregate;
993         copy->handle = met->handle;
994         copy->unitstype = met->unitstype;
995         return(copy);
996     }
997     return 0;
998 }
999
1000 #ifdef n_def
1001 resourceHandle dataManager::newResource(resourceHandle parent, 
1002                                         const char *newResource) {
1003     // rbi: kludge 
1004     // calls to this method should specify an abstraction,
1005     // but that involves a bunch of other changes that I don't want 
1006     // to make right now.
1007     // the kludge works because we know that all calls to this method 
1008     // are for BASE abstraction resources.  
1009
1010     // TEMP: until this routine is called with vector of strings for new res
1011     string res = resource::resources[parent]->getFullName();
1012     res += string("/");
1013     res += string(newResource);
1014     char *word = strdup(res.string_of());
1015     string next;
1016     vector<string> temp;
1017     unsigned j=1;
1018     for(unsigned i=1; i < res.length(); i++){
1019         if(word[i] == '/'){
1020             word[i] = '\0';
1021             next = &word[j];
1022             temp += next;
1023             j = i+1;
1024         }
1025     }
1026     next = &word[j];
1027     temp += next;
1028     string base = string("BASE");
1029     resourceHandle r = createResource(parent, temp, res, base);  
1030     paradynDaemon::tellDaemonsOfResource(res.string_of(),newResource);
1031     return(r);
1032 }
1033 #endif
1034
1035 resourceHandle dataManager::newResource(resourceHandle parent,
1036                                         const char *name, u_int type)
1037 {
1038
1039     // rbi: kludge
1040     // calls to this method should specify an abstraction,
1041     // but that involves a bunch of other changes that I don't want
1042     // to make right now.
1043     // the kludge works because we know that all calls to this method
1044     // are for BASE abstraction resources.
1045     
1046     string abs = "BASE";
1047     resource *parent_res = resource::handle_to_resource(parent);
1048     vector<string> res_name = parent_res->getParts();
1049     res_name += name;
1050     resourceHandle child = createResource(res_name,abs, type);
1051     paradynDaemon::tellDaemonsOfResource(parent_res->getHandle(), 
1052                                          child, 
1053                                          name, type);
1054     return(child);
1055
1056 }
1057
1058 timeStamp dataManager::getGlobalBucketWidth()
1059 {
1060     return(Histogram::getGlobalBucketWidth());
1061 }
1062
1063 timeStamp dataManager::getCurrentBucketWidth()
1064 {
1065     return(phaseInfo::GetLastBucketWidth());
1066 }
1067
1068 timeStamp dataManager::getCurrentStartTime() 
1069 {
1070     return(phaseInfo::GetLastPhaseStart());
1071 }
1072
1073 u_int dataManager::getCurrentPhaseId() 
1074 {
1075     return(phaseInfo::CurrentPhaseHandle());
1076 }
1077
1078
1079
1080 int dataManager::getMaxBins()
1081 {
1082     return(Histogram::getNumBins());
1083 }
1084
1085 void dataManager::printDaemons()
1086 {
1087   paradynDaemon::printDaemons();
1088 }
1089
1090 vector<string> *dataManager::getAvailableDaemons()
1091 {
1092     return(paradynDaemon::getAvailableDaemons());
1093 }
1094