Added code to change sampling rate as bucket width changes (this is not
[dyninst.git] / paradyn / src / DMthread / DMresource.C
1 /*
2  *  Copyright 1993 Jeff Hollingsworth.  All rights reserved.
3  *
4  */
5
6 /*
7  * resource.C - handle resource creation and queries.
8  * 
9  * $Log: DMresource.C,v $
10  * Revision 1.31  1995/10/13 22:06:56  newhall
11  * Added code to change sampling rate as bucket width changes (this is not
12  * completely implemented in daemon code yet, so now it has no effect).
13  * Purify fixes.  Added phaseType parameter to sampleDataCallbackFunc
14  * Added 2 new DM interface routines: getResourceName, getResourceLabelName
15  *
16  * Revision 1.30  1995/09/18  18:22:14  newhall
17  * changes to avoid for-scope problem
18  *
19  * Revision 1.29  1995/09/05  16:24:18  newhall
20  * added DM interface routines for PC, added resourceList method functions
21  *
22  * Revision 1.28  1995/08/20  03:51:36  newhall
23  * *** empty log message ***
24  *
25  * Revision 1.27  1995/08/20 03:37:15  newhall
26  * changed parameters to DM_sequential_init
27  * added persistent data and persistent collection flags
28  *
29  * Revision 1.26  1995/08/08  03:10:08  newhall
30  * bug fix to DMresourceListNameCompare
31  * changed newPerfData and sampleDataCallbackFunc definitions
32  *
33  * Revision 1.25  1995/08/01  02:11:20  newhall
34  * complete implementation of phase interface:
35  *   - additions and changes to DM interface functions
36  *   - changes to DM classes to support data collection at current or
37  *     global phase granularity
38  * added alphabetical ordering to foci name creation
39  *
40  * Revision 1.23  1995/07/15 03:34:53  karavan
41  * fixed "paradyn suppress searchChildren" command by checking for parent's
42  * suppress value in resource constructor.
43  *
44  * Revision 1.22  1995/06/02  20:48:28  newhall
45  * * removed all pointers to datamanager class objects from datamanager
46  *    interface functions and from client threads, objects are now
47  *    refered to by handles or by passing copies of DM internal data
48  * * removed applicationContext class from datamanager
49  * * replaced List and HTable container classes with STL containers
50  * * removed global variables from datamanager
51  * * remove redundant lists of class objects from datamanager
52  * * some reorginization and clean-up of data manager classes
53  * * removed all stringPools and stringHandles
54  * * KLUDGE: there are PC friend members of DM classes that should be
55  *    removed when the PC is re-written
56  *
57  * Revision 1.20  1995/03/02  04:23:21  krisna
58  * warning and bug fixes.
59  *
60  * Revision 1.19  1995/02/16  08:17:30  markc
61  * Changed Boolean to bool
62  * Added function to convert char* lists to vector<string>
63  *
64  * Revision 1.18  1995/01/26  17:58:24  jcargill
65  * Changed igen-generated include files to new naming convention; fixed
66  * some bugs compiling with gcc-2.6.3.
67  *
68  * Revision 1.17  1994/11/07  08:24:40  jcargill
69  * Added ability to suppress search on children of a resource, rather than
70  * the resource itself.
71  *
72  * Revision 1.16  1994/11/04  08:46:00  jcargill
73  * Made suppressSearch flag be inherited from parent resource.  Solves the
74  * problem of having to wait for processes to be defined to suppress them.
75  *
76  * Revision 1.15  1994/09/30  21:17:44  newhall
77  * changed convertToStringList method function return value from
78  * stringHandle * to char**
79  *
80  * Revision 1.14  1994/09/30  19:17:51  rbi
81  * Abstraction interface change.
82  *
83  * Revision 1.13  1994/09/22  00:57:16  markc
84  * Entered stringHandles into stringPool rather than assigning from const char *
85  * Added casts to remove compiler warnings
86  *
87  * Revision 1.12  1994/08/05  16:04:00  hollings
88  * more consistant use of stringHandle vs. char *.
89  *
90  * Revision 1.11  1994/07/28  22:31:09  krisna
91  * include <rpc/types.h>
92  * stringCompare to match qsort prototype
93  * proper prorotypes for starting DMmain
94  *
95  * Revision 1.10  1994/07/26  20:03:06  hollings
96  * added suppressSearch.
97  *
98  * Revision 1.9  1994/07/14  23:45:31  hollings
99  * Changed printf of resource to be TCL list like.
100  *
101  * Revision 1.8  1994/06/27  21:23:31  rbi
102  * Abstraction-specific resources and mapping info
103  *
104  * Revision 1.7  1994/06/17  00:11:55  hollings
105  * Fixed off by one error in string canonical string name code.
106  *
107  * Revision 1.6  1994/06/14  15:25:03  markc
108  * Added new call (sameRoot) to the resource class.  This call is used to
109  * determine if two resources have the same parent but are not in an
110  * ancestor-descendant relationship.  Such a relationship implies a conflict
111  * in the two foci.
112  *
113  * Revision 1.5  1994/06/02  16:08:17  hollings
114  * fixed duplicate naming problem for printResources.
115  *
116  * Revision 1.4  1994/05/31  19:11:34  hollings
117  * Changes to permit direct access to resources and resourceLists.
118  *
119  * Revision 1.3  1994/04/18  22:28:33  hollings
120  * Changes to create a canonical form of a resource list.
121  *
122  * Revision 1.2  1994/02/03  23:26:59  hollings
123  * Changes to work with g++ version 2.5.2.
124  *
125  * Revision 1.1  1994/02/02  00:42:35  hollings
126  * Changes to the Data manager to reflect the file naming convention and
127  * to support the integration of the Performance Consultant.
128  *
129  *
130  */
131 #include <stdio.h>
132 #include <stdlib.h>
133 #include <string.h>
134
135 #include "dataManager.thread.h"
136 #include "DMresource.h"
137
138 //
139 // used only to construct root.
140 //
141 resource::resource()
142 {
143     string temp = ""; 
144     if(!allResources.defines(temp)){
145         name = temp; 
146         res_handle = resources.size();
147         parent = res_handle; 
148         suppressSearch = FALSE;
149         suppressChildSearch = FALSE;
150         abstr = NULL;
151         resource *res = this;
152         resources += res;
153         allResources[name] = res;
154     }
155 }
156
157 resource::resource(resourceHandle p_handle, 
158                    vector<string>& resource_name,
159                    string& r_name,
160                    string& a) 
161 {
162     
163     if(!allResources.defines(r_name)){
164         name = r_name;
165         res_handle = resources.size();
166         parent = p_handle;
167         fullName = resource_name;
168         resource *p = resources[parent];
169          
170         suppressSearch = p->getSuppressChildren();
171         suppressChildSearch = suppressSearch; // check for suppress
172                                               // of parent's children
173         abstr = AMfind(a.string_of());
174         resource *res = this;
175         allResources[name] = res;
176         resources += res;
177         p->AddChild(res_handle);
178     }
179 }
180
181 resource *resource::handle_to_resource(resourceHandle r_handle) {
182      if (r_handle < resources.size()) {
183          return(resources[r_handle]);    
184      }
185      return(NULL);
186 }
187 vector<resourceHandle> *resource::getChildren(){
188
189     vector<resourceHandle> *temp = new vector<resourceHandle>;
190     for(unsigned i=0; i < children.size(); i++){
191         *temp += (resources[children[i]])->getHandle();      
192     }
193     return(temp);
194 }
195
196 resourceHandle *resource::findChild(const char *nm){
197     string temp = nm;
198     for(unsigned i=0; i < children.size(); i++){
199         if((resources[children[i]])->match(temp)){
200              resourceHandle *h = new resourceHandle;
201              *h = children[i];
202              return(h);
203              h = 0;
204         }
205     }
206     return(0);  // not found
207 }
208
209
210 void resource::print()
211 {
212     printf("%s ", name.string_of());
213 }
214
215 bool resource::string_to_handle(string res,resourceHandle *h){
216     if(allResources.defines(res)){
217        resource *temp = allResources[res];
218        *h = temp->getHandle();
219        return(TRUE);
220     }
221     else
222     return(FALSE);
223 }
224
225 /*
226  * Convinence function.
227  *
228  */
229
230 bool resource::isDescendent(resourceHandle child_handle)
231 {
232     resourceHandle root_handle = rootResource->getHandle();
233     resourceHandle this_handle = getHandle();
234     if (this_handle == child_handle) 
235         return FALSE;
236     if (this_handle == root_handle) 
237             return TRUE;
238     while (child_handle != root_handle) {
239         if (child_handle == this_handle) {
240             return TRUE;
241         } else {
242             child_handle = handle_to_resource(child_handle)->getParent();
243         }
244     }
245     return FALSE;
246 }
247
248
249
250 /*
251  * Do the two resources have the same base?
252  * Note, since the there is a common root for all nodes,
253  * the test for a common base checks the node below the
254  * common root.
255  */
256 bool resource::sameRoot(resourceHandle other)
257 {
258   resource *myBase=0, *otherBase=0, *temp;
259
260   temp = this;
261   resourceHandle root = rootResource->getHandle(); 
262   while (temp->getHandle() != root) {
263     myBase = temp;
264     temp = handle_to_resource(temp->parent);
265   }
266   temp = handle_to_resource(other);
267   while (temp->getHandle() != root) {
268     otherBase = temp;
269     temp = handle_to_resource(temp->parent);
270   }
271   if (myBase == otherBase)
272     return TRUE;
273   else
274     return FALSE;
275 }
276
277 const char *resource::getName(resourceHandle h){
278
279     if(h < resources.size()){
280         resource *res = resources[h];
281         return(res->getName());
282     }
283     return 0;
284 }
285
286 const char *resource::getFullName(resourceHandle h){
287
288     if(h < resources.size()){
289         resource *res = resources[h];
290         return(res->getFullName());
291     }
292     return 0;
293 }
294
295 resource *resource::string_to_resource(string res){
296
297     if(allResources.defines(res)){
298         return(allResources[res]);
299     }
300     return 0;
301 }
302
303 int DMresourceListNameCompare(const void *n1, const void *n2){
304     
305     const string *s1 = (const string*)n1, *s2 = (const string*)n2;
306     if(*s1 > *s2)
307        return(1);
308     if(*s1 == *s2)
309        return(0);
310     else
311        return(-1);
312
313 }
314
315 string DMcreateRLname(const vector<resourceHandle> &res){
316     // create a unique name
317     string temp;
318     resource *next;
319
320     vector <string> sorted_names;
321
322     for(unsigned i=0; i < res.size(); i++){
323         next = resource::handle_to_resource(res[i]);
324         sorted_names += next->getFullName();
325     }
326     sorted_names.sort(DMresourceListNameCompare);
327
328     for(unsigned j=0; j < (res.size() - 1); j++){
329         temp += sorted_names[j].string_of();
330         temp += ",";
331     }
332     if(res.size() > 0){
333         temp += sorted_names[(res.size()-1)].string_of();
334     }
335     return(temp);
336 }
337
338 resourceList::resourceList(const vector<resourceHandle> &res){
339     // create a unique name
340     string temp = DMcreateRLname(res);
341     // see if this resourceList has been created already, if not add it
342     if(!allFoci.defines(temp)){
343         id = foci.size();
344         resourceList *rl = this;
345         allFoci[temp] = rl;
346         fullName = temp;
347         foci += rl;
348
349         // create elements vector 
350         for(unsigned i=0; i < res.size(); i++){
351             resource *r = resource::handle_to_resource(res[i]);
352             if(r){
353                 elements += r;
354                 if(r->getSuppress()){
355                     suppressed = true;
356                 }
357             }
358     } }
359     else {
360         printf("ERROR: this resourceList already created: %s\n",temp.string_of());
361     }
362 }
363
364 // this should be called with strings of fullNames for resources
365 // ex.  "/Procedure/blah.c/foo"  rather than "foo"
366 resourceList::resourceList(const vector<string> &names){
367     // create a unique name
368     unsigned size = names.size();
369     string temp;
370     for(unsigned i=0; i < size; i++){
371        temp += names[i]; 
372        if(i < (size-1)){
373            temp += ",";
374        }
375     }
376     // see if this resourceList has been created already, if not add it
377     if(!allFoci.defines(temp)){
378         id = foci.size();
379         resourceList *rl = this;
380         allFoci[temp] = rl;
381         fullName = temp;
382         foci += rl;
383         // create elements vector 
384         for(unsigned j=0; j < size; j++){
385             resource *r = resource::string_to_resource(names[j]);
386             if(r){
387                 elements += r;
388                 if(r->getSuppress()){
389                     suppressed = true;
390                 }
391             }
392         } 
393     }
394     else {
395         printf("ERROR: this resourceList already created: %s\n",temp.string_of());
396     }
397 }
398
399
400 void resourceList::print()
401 {
402     printf("{");
403     for (unsigned i=0; i < elements.size(); i++) {
404         if (i) printf(" ");
405         printf("{");
406         elements[i]->print();
407         printf("}");
408     }
409     printf("}");
410 }
411
412 bool resourceList::convertToStringList(vector< vector<string> > &fs) {
413     for (unsigned i=0; i < elements.size(); i++)
414         fs += elements[i]->getParts();
415     return true;
416 }
417
418 bool resourceList::convertToIDList(vector<u_int> &fs) {
419     for (unsigned i=0; i < elements.size(); i++){
420         fs += elements[i]->getHandle();
421     }
422     return true;
423 }
424
425 // This routine returns a list of foci which are the result of combining
426 // each child of resource rh with the remaining resources that make up the
427 // focus, otherwise it returns 0
428 vector<resourceListHandle> *resourceList::magnify(resourceHandle rh){
429
430     // check to see if rh is a component of this resourceList
431     unsigned rIndex = elements.size();
432     for(unsigned i=0; i < elements.size(); i++){
433         if(rh == elements[i]->getHandle()){
434             rIndex = i;
435             break;
436         }
437     }
438     if(rIndex < elements.size()){
439         vector<resourceListHandle> *return_list = 
440                                     new vector<resourceListHandle>;
441         vector<resourceHandle> *children = (elements[rIndex])->getChildren();
442         if(children->size()){ // for each child create a new focus
443             vector<resourceHandle> new_focus; 
444             for(unsigned i=0; i < elements.size(); i++){
445                 new_focus += (elements[i])->getHandle();
446             }
447             for(unsigned j=0; j < children->size(); j++){
448                 new_focus[rIndex] = (*children)[j];
449                 *return_list += resourceList::getResourceList(new_focus);
450             }
451             delete children;
452             return return_list;
453         }
454     }
455     return 0;
456 }
457
458 // if resource rh is a decendent of a component of the focus, return a new
459 // focus consisting of rh replaced with it's corresponding entry, 
460 // otherwise return 0 
461 //
462 resourceListHandle *resourceList::constrain(resourceHandle rh){
463
464     unsigned rIndex = elements.size(); 
465     for(unsigned i=0; i < elements.size(); i++){
466         if(elements[i]->isDescendent(rh)){
467             rIndex = i;
468             break;
469     }}
470     if(rIndex < elements.size()){
471         vector<resourceHandle> new_focus; 
472         for(unsigned j=0; j < elements.size(); j++){
473             new_focus += (elements[j])->getHandle();
474         }
475         new_focus[rIndex] = rh;
476         resourceListHandle *new_handle = new resourceListHandle;
477         *new_handle = this->getResourceList(new_focus);
478         return new_handle;
479     }
480     return 0;
481 }
482
483 // This routine returns a list of foci each of which is the result of combining
484 // each child of one of the resources with the remaining resource components of
485 // the focus. this is iterated over all resources in the focus.
486 // returns 0 if all resources in the focus have no children
487 vector<resourceListHandle> *resourceList::magnify(){
488     
489     vector<resourceListHandle> *return_list = new vector<resourceListHandle>;
490     for(unsigned i=0; i < elements.size(); i++){
491         vector<resourceListHandle> *next = 
492                                    this->magnify((elements[i])->getHandle());
493         if(next) *return_list += *next;
494         delete next;
495     }
496     if(return_list->size()) return return_list;
497     return 0;
498 }
499
500
501 const char *resourceList::getName(resourceListHandle rh){
502
503     if(rh < foci.size()){
504         resourceList *rl = foci[rh];
505         return(rl->getName());
506     }
507     return(NULL);
508 }
509
510 vector<resourceHandle> *resourceList::getResourceHandles(resourceListHandle h){
511
512     resourceList *focus = getFocus(h);
513     if(focus){
514         vector<resourceHandle> *handles = new vector<resourceHandle>;
515         for(unsigned i=0; i < focus->elements.size(); i++){
516             resource *part = focus->elements[i];
517             *handles += part->getHandle(); 
518         }
519         return(handles);
520     }
521     return(NULL);
522
523 }
524
525 const resourceListHandle *resourceList::find(const string &name){
526
527     if(allFoci.defines(name)){
528         resourceList *res_list = allFoci[name]; 
529         const resourceListHandle *h = &res_list->id;
530         return(h);
531         res_list = 0;
532     }
533     return 0;
534
535
536 }
537
538 resourceListHandle resourceList::getResourceList(
539                                 const vector<resourceHandle>& h){
540
541     // does this resourceList already exist?
542     string temp = DMcreateRLname(h);
543     if(allFoci.defines(temp)){
544         resourceList *rl = allFoci[temp];
545         return(rl->getHandle());
546     }
547     // create a new resourceList
548     resourceList *res = new resourceList(h);
549     assert(res);
550     return(res->getHandle());
551 }
552
553 resourceList *resourceList::findRL(const char *name){
554     string temp = name;
555     if(allFoci.defines(name)){
556         return allFoci[name];
557     }
558     return NULL;
559 }
560
561 void printAllResources()
562 {
563     for(unsigned i=0; i < resource::resources.size(); i++){
564         printf("{");
565         (resource::resources[i])->print();
566         printf("}");
567         printf("\n");
568     }
569 }