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