Fixed poor handling of RCS logs by last CVS checkin
[dyninst.git] / paradyn / src / UIthread / uimpd.tcl.C
1 /*
2  * Copyright (c) 1996-1998 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /* uimpd.C
43    this file contains implementation of "uimpd" tcl command.  This command
44    is used internally by the UIM.
45 */
46
47 /* $Log: uimpd.tcl.C,v $
48 /* Revision 1.41  1999/03/12 22:59:33  pcroth
49 /* Fixed poor handling of RCS logs by last CVS checkin
50 /*
51  * Revision 1.40  1999/03/03 18:16:13  pcroth
52  * Updated to support Windows NT as a front-end platform
53  * Changes made to X code, to use Tcl analogues when appropriate
54  * Also changed in response to modifications in thread library and igen output.
55  *
56  * Revision 1.39  1997/10/28 20:36:30  tamches
57  * dictionary_lite --> dictionary_hash
58  *
59  * Revision 1.38  1997/10/10 00:22:07  tamches
60  * removed a warning
61  *
62  * Revision 1.37  1997/06/02 19:43:53  karavan
63  * changed visi from menu to button.
64  * eliminated uimpd drawStartVisiMenu command
65  *
66  * Revision 1.36  1996/11/26 16:07:00  naim
67  * Fixing asserts - naim
68  *
69  * Revision 1.35  1996/08/16 21:07:31  tamches
70  * updated copyright for release 1.1
71  *
72  * Revision 1.34  1996/05/07 18:06:00  newhall
73  * added threadExiting routine
74  *
75  * Revision 1.33  1996/04/01  22:31:47  tamches
76  * refs to uim_AvailMets etc. gone
77  * added UI_all_metric_names, UI_all_metrics_set_yet
78  *
79  * Revision 1.32  1996/02/07 18:50:35  tamches
80  * added uimpd_startPhaseCmd
81  * made copy of uim_visiSelections before calling chosenMetricsAndResources
82  *
83  * Revision 1.31  1996/02/02 18:55:19  tamches
84  * removed a lot of obsolete code that had been commented out
85  *
86  * Revision 1.30  1996/02/02 01:01:36  karavan
87  * Changes to support the new PC/UI interface
88  *
89  *
90  */
91  
92 #include <stdlib.h>
93 #include "util/h/odometer.h"
94
95 extern "C" {
96   int atoi(const char*);
97 }
98 #include "UIglobals.h"
99 #include "../pdMain/paradyn.h"
100 #include "../DMthread/DMinclude.h"
101 #include "abstractions.h"
102
103 void printMFPlist (vector<metric_focus_pair> *list) 
104 {
105   for (unsigned i = 0; i < list->size(); i++) {
106     cout << "   metric: " <<  
107       dataMgr->getMetricName (((*list)[i]).met) << "||| focus: ";
108     for (unsigned j = 0; j < ((*list)[i]).res.size(); j++)
109       cout << dataMgr->getResourceLabelName (((*list)[i]).res[j]);
110     cout << endl;
111   }
112 }
113
114 /* 
115    Sends metric-focus pair representation of menu selections to requesting
116    visi thread.  Pairs are collected in global list uim_VisiSelections, 
117    number of pairs is in uim_VisiSelectionsSize.
118    arguments:
119        1: msgID
120        2: cancelFlag
121
122    note: space allocated for chosenMets and localFocusList must be 
123          freed by the visi thread which gets the callback.
124 */
125 int sendVisiSelectionsCmd(ClientData,
126                 Tcl_Interp *,
127                 int,
128                 char *argv[])
129 {
130   Tcl_HashEntry *entry;
131   UIMReplyRec *msgRec;
132
133 #if UIM_DEBUG
134   cout << "processing " << uim_VisiSelections.size() << " visiselections...\n";
135   if (uim_VisiSelections->size() > 0) {
136     printMFPlist (uim_VisiSelections);
137   }
138 #endif
139   
140   // get callback and thread id for this msg
141   int msgID = atoi(argv[1]);
142   if (!(entry = Tcl_FindHashEntry (&UIMMsgReplyTbl, (char *) msgID))) {
143     // this case can occur if a thread has exited between making the
144     // menuing request and choosing accept on the menu...ignore it
145     return TCL_OK;
146   }
147   msgRec = (UIMReplyRec *) Tcl_GetHashValue(entry);
148
149      /* set thread id for return */
150   uim_server->setTid(msgRec->tid);
151   chooseMandRCBFunc mcb = (chooseMandRCBFunc) msgRec->cb;
152
153   // if cancel was selected invoke callback with null list
154   int cancelFlag = atoi(argv[2]);
155   if (cancelFlag == 1) {
156     uim_server->chosenMetricsandResources(mcb, 0);
157   }    
158   else {
159 #ifdef n_def      
160       printf("uim_VisiSelections.size() = %d\n",uim_VisiSelections->size());
161       for(unsigned l = 0; l < uim_VisiSelections->size(); l++){
162           printf("metric %d: %d\n",l,(*uim_VisiSelections)[l].met);
163           for(unsigned blah =0; blah < (*uim_VisiSelections)[l].res.size(); 
164               blah++){
165               printf("resource %d:%d:  %d\n",
166                         l,blah,(*uim_VisiSelections)[l].res[blah]);
167           }
168       }
169 #endif
170
171       // Since the following igen call is async, we must unfortunately make
172       // a copy of uim_VisiSelections, and pass that in.  The consumer
173       // will deallocate the memory.
174       vector<metric_focus_pair> *temp_igen_vec = new vector<metric_focus_pair> (uim_VisiSelections);
175       assert(temp_igen_vec);
176       uim_server->chosenMetricsandResources(mcb, temp_igen_vec);
177   }
178
179   // cleanup data structures
180   Tcl_DeleteHashEntry (entry);   // cleanup hash table record
181
182   return TCL_OK;
183 }
184
185 typedef vector<unsigned> numlist;
186 void printResSelectList (vector<numlist> *v, char *name)
187 {
188   cout << "[Focus List " << name << "|" << v->size() << "] "; 
189   for (unsigned i = 0; i < v->size(); i++) {
190     numlist temp = (*v)[i];
191     cout << "                    ";
192     for (unsigned j = 0; j < temp.size(); j++) 
193       cout << temp[j] << " ";
194     cout << endl;
195   }
196   cout << endl;
197 }
198
199 /* parseSelections
200  * takes a list with one resourceHandle vector per resource hierarchy; result 
201  * is the cross product list of valid foci, represented as vectors of 
202  * nodeID vectors; each element on resulting list can be converted into 
203  * one focus.
204  */
205 vector<numlist> parseSelections(vector<numlist> &theHierarchy,
206                                 bool plusWholeProgram,
207                                 numlist wholeProgramFocus) {
208    // how many resources are in each hierarchy?:
209    vector<unsigned> numResourcesByHierarchy(theHierarchy.size());
210    for (unsigned hier=0; hier < theHierarchy.size(); hier++)
211       numResourcesByHierarchy[hier] = theHierarchy[hier].size();
212
213    odometer theOdometer(numResourcesByHierarchy);
214    vector<numlist> result;
215
216    while (!theOdometer.done()) {
217       // create a focus using the odometer's current setting
218       // Make a note if we have added the equivalent of "Whole Program"
219
220       numlist theFocus(theHierarchy.size());
221
222       bool addedEquivOfWholeProgram = plusWholeProgram; // so far...
223
224       for (unsigned hier=0; hier < theHierarchy.size(); hier++) {
225          theFocus[hier] = theHierarchy[hier][theOdometer[hier]];
226          if (addedEquivOfWholeProgram)
227             addedEquivOfWholeProgram = (theFocus[hier] == wholeProgramFocus[hier]);
228       }
229
230       if (!addedEquivOfWholeProgram)
231          result += theFocus;
232 //      else
233 //         cout << "Suppressing duplicate of whole program" << endl;
234
235       theOdometer++;
236    }
237
238    // There is one final thing to check for: whole-program
239    if (plusWholeProgram)
240       result += wholeProgramFocus;
241
242 //   cout << "parseSelections: returning result of " << result.size() << " foci" << endl;
243    return result;
244 }
245
246 /* arguments:
247        0: "processVisiSelection"
248        1: list of selected metrics
249 */
250 extern dictionary_hash<unsigned, string> UI_all_metric_names;
251 extern bool UI_all_metrics_set_yet;
252
253 int processVisiSelectionCmd(ClientData,
254                             Tcl_Interp *interp, 
255                             int,
256                             char *argv[])
257 {
258    extern abstractions *theAbstractions;
259    bool wholeProgram;
260    numlist wholeProgramFocus;
261    vector< vector<resourceHandle> > theHierarchySelections = theAbstractions->getCurrAbstractionSelections(wholeProgram, wholeProgramFocus);
262
263 #if UIM_DEBUG
264    for (int i=0; i < theHierarchySelections.size(); i++) {
265       cout << "ResHierarchy " << i << " selections: ";
266       for (int j=0; j < theHierarchySelections[i].size(); j++)
267          cout << " " << theHierarchySelections[i][j];
268       cout << endl;
269    }
270 #endif
271
272   vector<numlist> fociList = parseSelections (theHierarchySelections,
273                                               wholeProgram, wholeProgramFocus);
274
275 #if UIM_DEBUG
276   printResSelectList(fociList, "list of selected focii");
277 #endif
278
279 //** and, list of metric indices from selections put into metlst
280
281   assert(UI_all_metrics_set_yet);
282
283   int metcnt;
284   char **metlst;
285   // reminder: argv[1] is the list of selected metrics (each is an integer id)
286   bool aflag;
287   aflag = (TCL_OK == Tcl_SplitList (interp, argv[1], &metcnt, &metlst));
288   assert(aflag);
289
290 //   cout << "Here are the selections (in metric-ids)" << endl;
291 //   for (unsigned i=0; i < metcnt; i++)
292 //      cout << metlst[i] << " ";
293 //   cout << endl;
294
295    uim_VisiSelections.resize(0);
296    
297    for (int i = 0; i < metcnt; i++) {
298       unsigned metric_id = atoi(metlst[i]);
299       assert(UI_all_metric_names.defines(metric_id)); // just a sanity check
300
301       for (unsigned focuslcv = 0; focuslcv < fociList.size(); focuslcv++)
302          uim_VisiSelections += metric_focus_pair(metric_id, fociList[focuslcv]);
303    }
304
305    Tcl_Free ((char*)metlst);   // cleanup after Tcl_SplitList
306
307    sprintf (interp->result, "%d", 1);
308    return TCL_OK;
309 }
310
311 /*
312  * argv[1] = error number
313  * argv[2] = error string
314  */
315 int showErrorCmd (ClientData,
316                 Tcl_Interp *,
317                 int,
318                 char *argv[])
319 {
320   int code = atoi(argv[1]);
321   uim_server->showError (code, argv[2]);
322   return TCL_OK;
323 }
324
325 int uimpd_startPhaseCmd(ClientData, Tcl_Interp *,
326                         int argc, char **argv) {
327    assert(argc == 2);
328    if (0==strcmp(argv[1], "plain")) {
329       dataMgr->StartPhase(-1, NULL,
330                               false, false);
331       return TCL_OK;
332    }
333    else if (0==strcmp(argv[1], "pc")) {
334       dataMgr->StartPhase(-1, NULL,
335                               true, false);
336       return TCL_OK;
337    }
338    else if (0==strcmp(argv[1], "visis")) {
339       dataMgr->StartPhase(-1, NULL,
340                               false, true);
341       return TCL_OK;
342    }
343    else if (0==strcmp(argv[1], "both")) {
344       dataMgr->StartPhase(-1, NULL,
345                               true, true);
346       return TCL_OK;
347    }
348    else {
349       cerr << "uimpd_startPhaseCmd: unknown cmd " << argv[1] << endl;
350       return TCL_ERROR;
351    }
352 }
353
354 struct cmdTabEntry uimpd_Cmds[] = {
355   {"sendVisiSelections", sendVisiSelectionsCmd},
356   {"processVisiSelection", processVisiSelectionCmd},
357   {"tclTunable", TclTunableCommand},
358   {"showError", showErrorCmd},
359   {"startPhase", uimpd_startPhaseCmd},
360   { NULL, NULL}
361 };
362
363 int UimpdCmd(ClientData clientData, 
364                 Tcl_Interp *interp, 
365                 int argc, 
366                 char *argv[])
367 {
368   int i;
369
370   if (argc < 2) {
371     sprintf(interp->result,"USAGE: %s <cmd>", argv[0]);
372     return TCL_ERROR;
373   }
374
375   for (i = 0; uimpd_Cmds[i].cmdname; i++) {
376     if (strcmp(uimpd_Cmds[i].cmdname,argv[1]) == 0) {
377       return ((uimpd_Cmds[i].func)(clientData,interp,argc-1,argv+1));      
378       }
379   }
380
381   sprintf(interp->result,"unknown UIM cmd '%s'",argv[1]);
382   return TCL_ERROR;  
383 }