Added correct machine name reporting.
[dyninst.git] / paradynd / src / main.C
1 /*
2  * Main loop for the default paradynd.
3  *
4  * $Log: main.C,v $
5  * Revision 1.9  1994/04/06 21:35:39  markc
6  * Added correct machine name reporting.
7  *
8  * Revision 1.8  1994/04/01  20:06:41  hollings
9  * Added ability to start remote paradynd's
10  *
11  * Revision 1.7  1994/03/31  01:57:27  markc
12  * Added support for pauseProcess, continueProcess.  Added pvm interface code.
13  *
14  * Revision 1.6  1994/03/20  01:53:09  markc
15  * Added a buffer to each process structure to allow for multiple writers on the
16  * traceStream.  Replaced old inst-pvm.C.  Changed addProcess to return type
17  * int.
18  *
19  * Revision 1.5  1994/02/28  05:09:42  markc
20  * Added pvm hooks and ifdefs.
21  *
22  * Revision 1.4  1994/02/25  13:40:55  markc
23  * Added hooks for pvm support.
24  *
25  * Revision 1.3  1994/02/24  04:32:33  markc
26  * Changed header files to reflect igen changes.  main.C does not look at the number of command line arguments now.
27  *
28  * Revision 1.2  1994/02/01  18:46:52  hollings
29  * Changes for adding perfConsult thread.
30  *
31  * Revision 1.1  1994/01/27  20:31:27  hollings
32  * Iinital version of paradynd speaking dynRPC igend protocol.
33  *
34  *
35  */
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <sys/types.h>
39 #include <sys/time.h>
40 #include <assert.h>
41
42 #include "util/h/list.h"
43 #include "rtinst/h/rtinst.h"
44
45 #include "symtab.h"
46 #include "process.h"
47 #include "inst.h"
48 #include "instP.h"
49 #include "ast.h"
50 #include "util.h"
51 #include "dyninstP.h"
52 #include "metric.h"
53 #include "dyninstRPC.SRVR.h"
54
55 dynRPC *tp;
56 extern void controllerMainLoop();
57 extern void initLibraryFunctions();
58
59 #ifdef PARADYND_PVM
60 static dynRPC *init_pvm_code(char *argv[], char *machine, int family,
61                              int type, int well_known_socket, int flag);
62 static char machine_name[80];
63 #endif     
64
65 int ready;
66
67 main(int argc, char *argv[])
68 {
69     int i, family, type, well_known_socket, flag;
70     char *machine;
71     metricList stuff;
72
73     initLibraryFunctions();
74
75     // process command line args passed in
76     // flag == 1 --> started by paradyn
77     assert (RPC_undo_arg_list (argc, argv, &machine, family, type,
78                        well_known_socket, flag) == 0);
79
80 #ifdef PARADYND_PVM
81     tp = init_pvm_code(argv, machine, family, type, well_known_socket, flag);
82 #else
83     if (!flag) {
84         int pid;
85
86
87         pid = fork();
88         if (pid == 0) {
89             close(0);
90             close(1);
91             close(2);
92
93             // setup socket
94             tp = new dynRPC(family, well_known_socket, type, machine, 
95                             NULL, NULL, 0);
96         } else if (pid > 0) {
97             printf("PARADYND %d\n", pid);
98             fflush(stdout);
99             _exit(-1);
100         } else {
101             fflush(stdout);
102             exit(-1);
103         }
104     } else {
105         // already setup on this FD.
106         tp = new dynRPC(0, NULL, NULL);
107     }
108 #endif
109
110     //
111     // tell client about our metrics.
112     //
113     stuff = getMetricList();
114     for (i=0; i < stuff->count; i++) {
115         tp->newMetricCallback(stuff->elements[i].info);
116         if (tp->callErr < 0) {
117             printf("RPC error\n");
118             exit(-1);
119         }
120     }
121
122     controllerMainLoop();
123 }
124
125 void dynRPC::addResource(String parent, String name)
126 {
127     resource pr;
128     extern resource findResource(char*);
129
130     pr = findResource(parent);
131     if (pr) (void) newResource(pr, NULL, name, 0.0);
132 }
133
134 void dynRPC::coreProcess(int pid)
135 {
136     process *proc;
137
138     proc = processList.find((void *) pid);
139     dumpCore(proc);
140 }
141
142 String dynRPC::getStatus(int pid)
143 {
144     process *proc;
145     extern char *getProcessStatus(process *proc);
146     char ret[50];
147
148     proc = processList.find((void *) pid);
149
150     if (!proc) {
151         sprintf (ret, "PID:%d not found for getStatus\n", pid);
152         return (ret);
153     }
154     else
155         return(getProcessStatus(proc));
156 }
157
158 //
159 // NOTE: This version of getAvailableMetrics assumes that new metrics are
160 //   NOT added during execution.
161 //
162 metricInfo_Array dynRPC::getAvailableMetrics(void)
163 {
164     int i;
165     static int inited;
166     static metricInfo_Array metInfo;
167
168     if (!inited) {
169         metricList stuff;
170
171         stuff = getMetricList();
172         metInfo.count = stuff->count;
173         metInfo.data = (metricInfo*) calloc(sizeof(metricInfo), metInfo.count);
174         for (i=0; i < metInfo.count; i++) {
175             metInfo.data[i] = stuff->elements[i].info;
176         }
177         inited = 1;
178     }
179     return(metInfo);
180 }
181
182 double dynRPC::getPredictedDataCost(String_Array focusString, String metric)
183 {
184     metric m;
185     double val;
186     resourceList l;
187
188     m = findMetric(metric);
189     l = findFocus(focusString.count, focusString.data);
190     if (!l) return(0.0);
191     val = guessCost(l, m);
192
193     return(val);
194 }
195
196 void dynRPC::disableDataCollection(int mid)
197 {
198     metricInstance mi;
199     extern void printResourceList(resourceList);
200
201     printf("disable of %s for RL =", getMetricName(mi->met));
202     printResourceList(mi->resList);
203     printf("\n");
204
205     mi = allMIs.find((void *) mid);
206     mi->disable();
207     allMIs.remove(mi);
208     delete(mi);
209 }
210
211 int dynRPC::enableDataCollection(String_Array foucsString,String metric)
212 {
213     int id;
214     metric m;
215     resourceList l;
216
217     m = findMetric(metric);
218     l = findFocus(foucsString.count, foucsString.data);
219     if (!l) return(-1);
220     id = startCollecting(l, m);
221     return(id);
222 }
223
224 //
225 // not implemented yet.
226 //
227 void dynRPC::setSampleRate(double sampleInterval)
228 {
229     return;
230 }
231
232 Boolean dynRPC::detachProgram(int program,Boolean pause)
233 {
234     return(detachProcess(program, pause));
235 }
236
237 //
238 // Continue all processes
239 //
240 void dynRPC::continueApplication()
241 {
242     struct List<process *> curr;
243
244     for (curr = processList; *curr; curr++) {
245         continueProcess(*curr);
246     }
247 }
248
249 //
250 // Continue a process
251 //
252 void dynRPC::continueProgram(int program)
253 {
254     struct List<process *> curr;
255
256     for (curr = processList; *curr; curr++) {
257         if ((*curr)->pid == pid) break;
258     }
259     if (*curr)
260         continueProcess(*curr);
261     else
262         printf("Can't continue PID %d\n", program);
263 }
264
265 //
266 //  Stop all processes 
267 //
268 Boolean dynRPC::pauseApplication()
269 {
270     struct List<process *> curr;
271
272     for (curr = processList; *curr; curr++) {
273         pauseProcess(*curr);
274     }
275     flushPtrace();
276     return TRUE;
277 }
278
279 //
280 //  Stop a single process
281 //
282 Boolean dynRPC::pauseProgram(int program)
283 {
284     struct List<process *> curr;
285
286     for (curr = processList; *curr; curr++) {
287         if ((*curr)->pid == program) break;
288     }
289     if (!(*curr)) {
290         printf("Can't pause PID %d\n", program);
291         return FALSE;
292     }
293     pauseProcess(*curr);
294     flushPtrace();
295     return TRUE;
296 }
297
298 Boolean dynRPC::startProgram(int program)
299 {
300     continueApplication();
301     return(False);
302 }
303
304 //
305 // This is not implemented yet.
306 //
307 Boolean dynRPC::attachProgram(int pid)
308 {
309     return(FALSE);
310 }
311
312 //
313 // start a new program for the tool.
314 //
315 int dynRPC::addExecutable(int argc,String_Array argv)
316 {
317     return(addProcess(argc, argv.data));
318 }
319
320 #ifdef PARADYND_PVM
321 dynRPC *
322 init_pvm_code(char *argv[], char *machine, int family,
323               int type, int well_known_socket, int flag)
324 {
325   dynRPC *temp;
326   extern int PDYN_initForPVM (char **, char *, int, int, int, int);
327
328   assert(PDYN_initForPVM (argv, machine, family, type, well_known_socket,
329                          flag) == 0);
330
331   assert(!gethostname(machine_name, 99));
332
333   // connect to paradyn
334   if (flag == 1)
335     temp = new dynRPC(0, NULL, NULL);
336   else
337     {
338       temp = new dynRPC(family, well_known_socket, type, machine, NULL, NULL);
339       temp->reportSelf (machine_name, argv[0], getpid());
340     }
341
342     return temp;
343 }
344
345 int
346 PDYND_report_to_paradyn (int pid, int argc, char **argv)
347 {
348     String_Array sa;
349
350     sa.count = argc;
351     sa.data = argv;
352     
353     assert(tp);
354     tp->newProgramCallbackFunc(pid, argc, sa, machine_name);
355     return 0;
356 }
357 #endif