xref: /plan9-contrib/sys/src/cmd/ptrace/pm.c (revision af198995f3f1f1d87a386835b2bcd15ca90a6fed)
1 /*
2  * Program to cause a synthesized load for profiling.
3  * Spawns n processes each of which would do r rounds of
4  * io + compute.
5  */
6 
7 #include <u.h>
8 #include <libc.h>
9 
10 enum
11 {
12 	Nprocs = 10,
13 	Nrounds = 4,
14 	Ncpu = 10000,
15 	Nio = 10000,
16 	Nstack = 10,
17 	Nsleep = 10,
18 	Bufsz = 1024,
19 };
20 
21 #include "rnd.c"
22 
23 int nprocs, nrounds, ncpu, nio, nstack, nsleep;
24 
25 
26 static void
docpu(void)27 docpu(void)
28 {
29 	int *dv;
30 	int i, j, x;
31 
32 	dv = malloc(sizeof vals);
33 	for(i = 0; i < nelem(vals); i++)
34 		dv[i] = vals[i];
35 	for(i = 0; i < nelem(dv); i++)
36 		for(j = i; j < nelem(dv); j++)
37 			if(dv[i] > dv[j]){
38 				x = dv[i];
39 				dv[i] = dv[j];
40 				dv[j] = x;
41 			}
42 	free(dv);
43 }
44 
45 static void
doio(char buf[],int sz)46 doio(char buf[], int sz)
47 {
48 	int i, p[2];
49 	long n;
50 
51 	if(pipe(p) < 0)
52 		sysfatal("pipe");
53 	switch(fork()){
54 	case -1:
55 		sysfatal("fork: %r");
56 	case 0:
57 		close(p[1]);
58 		for(i = 0; i < nio; i++){
59 			n = readn(p[0], buf, sz);
60 			if(n != sz)
61 				sysfatal("read: %r");
62 		}
63 		close(p[0]);
64 		exits(nil);
65 	default:
66 		close(p[0]);
67 		for(i = 0; i < nio; i++){
68 			n = write(p[1], buf, sz);
69 			if(n != sz)
70 				sysfatal("write: %r");
71 		}
72 		close(p[1]);
73 		waitpid();
74 	}
75 }
76 
77 static void
stk(int lvl)78 stk(int lvl)
79 {
80 	int i, c;
81 	char buf[Bufsz];
82 
83 	if(lvl < Nstack){
84 		stk(lvl+1);
85 		return;
86 	}
87 	for(i = 0; i <nrounds; i++){
88 		for(c = 0; c < ncpu; c++)
89 			docpu();
90 		doio(buf, sizeof buf);
91 		sleep(nsleep);
92 	}
93 }
94 
95 static void
usage(void)96 usage(void)
97 {
98 	fprint(2, "usage: %s [-p procs] [-r nrounds] [-c ncpu]"
99 		" [-i nio] [-s nstack]\n", argv0);
100 	exits("usage");
101 }
102 
103 void
main(int argc,char * argv[])104 main(int argc, char *argv[])
105 {
106 	int p;
107 
108 	nprocs = Nprocs;
109 	nrounds = Nrounds;
110 	ncpu = Ncpu;
111 	nio = Nio;
112 	nstack = Nstack;
113 	nsleep = Nsleep;
114 	ARGBEGIN{
115 	case 'p':
116 		nprocs = atoi(EARGF(usage()));
117 		break;
118 	case 'r':
119 		nrounds = atoi(EARGF(usage()));
120 		break;
121 	case 'c':
122 		ncpu = atoi(EARGF(usage()));
123 		break;
124 	case 'i':
125 		nio = atoi(EARGF(usage()));
126 		break;
127 	case 's':
128 		nstack = atoi(EARGF(usage()));
129 		break;
130 	case 'w':
131 		nsleep = atoi(EARGF(usage()));
132 		break;
133 	default:
134 		usage();
135 	}ARGEND
136 
137 	if(nprocs < 2)
138 		nprocs = 2;
139 	for(p = 0; p < nprocs/2; p++){
140 		switch(fork()){
141 		case -1:
142 			sysfatal("fork: %r");
143 		case 0:
144 			stk(0);
145 			exits(nil);
146 		}
147 		docpu();
148 	}
149 	for(p = 0; p < nprocs; p++)
150 		waitpid();
151 	exits(nil);
152 }
153