1*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
2*49cdfc7eSAndroid Build Coastguard Worker /* Copyright Rusty Russell, */
3*49cdfc7eSAndroid Build Coastguard Worker /* Copyright Pierre Peiffer */
4*49cdfc7eSAndroid Build Coastguard Worker /* Copyright Zhang, Yanmin, */
5*49cdfc7eSAndroid Build Coastguard Worker /* Copyright Ingo Molnar, */
6*49cdfc7eSAndroid Build Coastguard Worker /* Copyright Arjan van de Ven, */
7*49cdfc7eSAndroid Build Coastguard Worker /* Copyright (c) International Business Machines Corp., 2008 */
8*49cdfc7eSAndroid Build Coastguard Worker /* */
9*49cdfc7eSAndroid Build Coastguard Worker /* This program is free software; you can redistribute it and/or modify */
10*49cdfc7eSAndroid Build Coastguard Worker /* it under the terms of the GNU General Public License as published by */
11*49cdfc7eSAndroid Build Coastguard Worker /* the Free Software Foundation; either version 2 of the License, or */
12*49cdfc7eSAndroid Build Coastguard Worker /* (at your option) any later version. */
13*49cdfc7eSAndroid Build Coastguard Worker /* */
14*49cdfc7eSAndroid Build Coastguard Worker /* This program is distributed in the hope that it will be useful, */
15*49cdfc7eSAndroid Build Coastguard Worker /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
16*49cdfc7eSAndroid Build Coastguard Worker /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
17*49cdfc7eSAndroid Build Coastguard Worker /* the GNU General Public License for more details. */
18*49cdfc7eSAndroid Build Coastguard Worker /* */
19*49cdfc7eSAndroid Build Coastguard Worker /* You should have received a copy of the GNU General Public License */
20*49cdfc7eSAndroid Build Coastguard Worker /* along with this program; if not, write to the Free Software */
21*49cdfc7eSAndroid Build Coastguard Worker /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
22*49cdfc7eSAndroid Build Coastguard Worker /* */
23*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
24*49cdfc7eSAndroid Build Coastguard Worker
25*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
26*49cdfc7eSAndroid Build Coastguard Worker /* */
27*49cdfc7eSAndroid Build Coastguard Worker /* File: hackbench.c */
28*49cdfc7eSAndroid Build Coastguard Worker /* */
29*49cdfc7eSAndroid Build Coastguard Worker /* Description: hackbench tests the Linux scheduler. Test groups of 20 */
30*49cdfc7eSAndroid Build Coastguard Worker /* processes spraying to 20 receivers */
31*49cdfc7eSAndroid Build Coastguard Worker /* */
32*49cdfc7eSAndroid Build Coastguard Worker /* Total Tests: 1 */
33*49cdfc7eSAndroid Build Coastguard Worker /* */
34*49cdfc7eSAndroid Build Coastguard Worker /* Test Name: hackbench01 and hackbench02 */
35*49cdfc7eSAndroid Build Coastguard Worker /* */
36*49cdfc7eSAndroid Build Coastguard Worker /* Test Assertion: */
37*49cdfc7eSAndroid Build Coastguard Worker /* */
38*49cdfc7eSAndroid Build Coastguard Worker /* Author(s): Rusty Russell <[email protected]>, */
39*49cdfc7eSAndroid Build Coastguard Worker /* Pierre Peiffer <[email protected]>, */
40*49cdfc7eSAndroid Build Coastguard Worker /* Ingo Molnar <[email protected]>, */
41*49cdfc7eSAndroid Build Coastguard Worker /* Arjan van de Ven <[email protected]>, */
42*49cdfc7eSAndroid Build Coastguard Worker /* "Zhang, Yanmin" <[email protected]>, */
43*49cdfc7eSAndroid Build Coastguard Worker /* Nathan Lynch <[email protected]> */
44*49cdfc7eSAndroid Build Coastguard Worker /* */
45*49cdfc7eSAndroid Build Coastguard Worker /* History: Included into LTP */
46*49cdfc7eSAndroid Build Coastguard Worker /* - June 26 2008 - Subrata Modak<[email protected]>*/
47*49cdfc7eSAndroid Build Coastguard Worker /* */
48*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
49*49cdfc7eSAndroid Build Coastguard Worker #include <pthread.h>
50*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
51*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
52*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
53*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
54*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
55*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
56*49cdfc7eSAndroid Build Coastguard Worker #include <sys/socket.h>
57*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
58*49cdfc7eSAndroid Build Coastguard Worker #include <sys/time.h>
59*49cdfc7eSAndroid Build Coastguard Worker #include <sys/poll.h>
60*49cdfc7eSAndroid Build Coastguard Worker #include <limits.h>
61*49cdfc7eSAndroid Build Coastguard Worker
62*49cdfc7eSAndroid Build Coastguard Worker #define SAFE_FREE(p) { if (p) { free(p); (p)=NULL; } }
63*49cdfc7eSAndroid Build Coastguard Worker #define DATASIZE 100
64*49cdfc7eSAndroid Build Coastguard Worker static struct sender_context **snd_ctx_tab; /*Table for sender context pointers. */
65*49cdfc7eSAndroid Build Coastguard Worker static struct receiver_context **rev_ctx_tab; /*Table for receiver context pointers. */
66*49cdfc7eSAndroid Build Coastguard Worker static int gr_num = 0; /*For group calculation */
67*49cdfc7eSAndroid Build Coastguard Worker static unsigned int loops = 100;
68*49cdfc7eSAndroid Build Coastguard Worker /*
69*49cdfc7eSAndroid Build Coastguard Worker * 0 means thread mode and others mean process (default)
70*49cdfc7eSAndroid Build Coastguard Worker */
71*49cdfc7eSAndroid Build Coastguard Worker static unsigned int process_mode = 1;
72*49cdfc7eSAndroid Build Coastguard Worker
73*49cdfc7eSAndroid Build Coastguard Worker static int use_pipes = 0;
74*49cdfc7eSAndroid Build Coastguard Worker
75*49cdfc7eSAndroid Build Coastguard Worker struct sender_context {
76*49cdfc7eSAndroid Build Coastguard Worker unsigned int num_fds;
77*49cdfc7eSAndroid Build Coastguard Worker int ready_out;
78*49cdfc7eSAndroid Build Coastguard Worker int wakefd;
79*49cdfc7eSAndroid Build Coastguard Worker int out_fds[0];
80*49cdfc7eSAndroid Build Coastguard Worker };
81*49cdfc7eSAndroid Build Coastguard Worker
82*49cdfc7eSAndroid Build Coastguard Worker struct receiver_context {
83*49cdfc7eSAndroid Build Coastguard Worker unsigned int num_packets;
84*49cdfc7eSAndroid Build Coastguard Worker int in_fds[2];
85*49cdfc7eSAndroid Build Coastguard Worker int ready_out;
86*49cdfc7eSAndroid Build Coastguard Worker int wakefd;
87*49cdfc7eSAndroid Build Coastguard Worker };
88*49cdfc7eSAndroid Build Coastguard Worker
barf(const char * msg)89*49cdfc7eSAndroid Build Coastguard Worker static void barf(const char *msg)
90*49cdfc7eSAndroid Build Coastguard Worker {
91*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
92*49cdfc7eSAndroid Build Coastguard Worker exit(1);
93*49cdfc7eSAndroid Build Coastguard Worker }
94*49cdfc7eSAndroid Build Coastguard Worker
print_usage_exit(void)95*49cdfc7eSAndroid Build Coastguard Worker static void print_usage_exit(void)
96*49cdfc7eSAndroid Build Coastguard Worker {
97*49cdfc7eSAndroid Build Coastguard Worker printf
98*49cdfc7eSAndroid Build Coastguard Worker ("Usage: hackbench [-pipe] <num groups> [process|thread] [loops]\n");
99*49cdfc7eSAndroid Build Coastguard Worker exit(1);
100*49cdfc7eSAndroid Build Coastguard Worker }
101*49cdfc7eSAndroid Build Coastguard Worker
fdpair(int fds[2])102*49cdfc7eSAndroid Build Coastguard Worker static void fdpair(int fds[2])
103*49cdfc7eSAndroid Build Coastguard Worker {
104*49cdfc7eSAndroid Build Coastguard Worker if (use_pipes) {
105*49cdfc7eSAndroid Build Coastguard Worker if (pipe(fds) == 0)
106*49cdfc7eSAndroid Build Coastguard Worker return;
107*49cdfc7eSAndroid Build Coastguard Worker } else {
108*49cdfc7eSAndroid Build Coastguard Worker if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0)
109*49cdfc7eSAndroid Build Coastguard Worker return;
110*49cdfc7eSAndroid Build Coastguard Worker }
111*49cdfc7eSAndroid Build Coastguard Worker barf("Creating fdpair");
112*49cdfc7eSAndroid Build Coastguard Worker }
113*49cdfc7eSAndroid Build Coastguard Worker
114*49cdfc7eSAndroid Build Coastguard Worker /* Block until we're ready to go */
ready(int ready_out,int wakefd)115*49cdfc7eSAndroid Build Coastguard Worker static void ready(int ready_out, int wakefd)
116*49cdfc7eSAndroid Build Coastguard Worker {
117*49cdfc7eSAndroid Build Coastguard Worker char dummy;
118*49cdfc7eSAndroid Build Coastguard Worker struct pollfd pollfd = {.fd = wakefd,.events = POLLIN };
119*49cdfc7eSAndroid Build Coastguard Worker
120*49cdfc7eSAndroid Build Coastguard Worker /* Tell them we're ready. */
121*49cdfc7eSAndroid Build Coastguard Worker if (write(ready_out, &dummy, 1) != 1)
122*49cdfc7eSAndroid Build Coastguard Worker barf("CLIENT: ready write");
123*49cdfc7eSAndroid Build Coastguard Worker
124*49cdfc7eSAndroid Build Coastguard Worker /* Wait for "GO" signal */
125*49cdfc7eSAndroid Build Coastguard Worker if (poll(&pollfd, 1, -1) != 1)
126*49cdfc7eSAndroid Build Coastguard Worker barf("poll");
127*49cdfc7eSAndroid Build Coastguard Worker }
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard Worker /* Sender sprays loops messages down each file descriptor */
sender(struct sender_context * ctx)130*49cdfc7eSAndroid Build Coastguard Worker static void *sender(struct sender_context *ctx)
131*49cdfc7eSAndroid Build Coastguard Worker {
132*49cdfc7eSAndroid Build Coastguard Worker char data[DATASIZE];
133*49cdfc7eSAndroid Build Coastguard Worker unsigned int i, j;
134*49cdfc7eSAndroid Build Coastguard Worker
135*49cdfc7eSAndroid Build Coastguard Worker ready(ctx->ready_out, ctx->wakefd);
136*49cdfc7eSAndroid Build Coastguard Worker
137*49cdfc7eSAndroid Build Coastguard Worker /* Now pump to every receiver. */
138*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < loops; i++) {
139*49cdfc7eSAndroid Build Coastguard Worker for (j = 0; j < ctx->num_fds; j++) {
140*49cdfc7eSAndroid Build Coastguard Worker int ret, done = 0;
141*49cdfc7eSAndroid Build Coastguard Worker
142*49cdfc7eSAndroid Build Coastguard Worker again:
143*49cdfc7eSAndroid Build Coastguard Worker ret =
144*49cdfc7eSAndroid Build Coastguard Worker write(ctx->out_fds[j], data + done,
145*49cdfc7eSAndroid Build Coastguard Worker sizeof(data) - done);
146*49cdfc7eSAndroid Build Coastguard Worker if (ret < 0)
147*49cdfc7eSAndroid Build Coastguard Worker barf("SENDER: write");
148*49cdfc7eSAndroid Build Coastguard Worker done += ret;
149*49cdfc7eSAndroid Build Coastguard Worker if (done < sizeof(data))
150*49cdfc7eSAndroid Build Coastguard Worker goto again;
151*49cdfc7eSAndroid Build Coastguard Worker }
152*49cdfc7eSAndroid Build Coastguard Worker }
153*49cdfc7eSAndroid Build Coastguard Worker
154*49cdfc7eSAndroid Build Coastguard Worker return NULL;
155*49cdfc7eSAndroid Build Coastguard Worker }
156*49cdfc7eSAndroid Build Coastguard Worker
157*49cdfc7eSAndroid Build Coastguard Worker /* One receiver per fd */
receiver(struct receiver_context * ctx)158*49cdfc7eSAndroid Build Coastguard Worker static void *receiver(struct receiver_context *ctx)
159*49cdfc7eSAndroid Build Coastguard Worker {
160*49cdfc7eSAndroid Build Coastguard Worker unsigned int i;
161*49cdfc7eSAndroid Build Coastguard Worker
162*49cdfc7eSAndroid Build Coastguard Worker if (process_mode)
163*49cdfc7eSAndroid Build Coastguard Worker close(ctx->in_fds[1]);
164*49cdfc7eSAndroid Build Coastguard Worker
165*49cdfc7eSAndroid Build Coastguard Worker /* Wait for start... */
166*49cdfc7eSAndroid Build Coastguard Worker ready(ctx->ready_out, ctx->wakefd);
167*49cdfc7eSAndroid Build Coastguard Worker
168*49cdfc7eSAndroid Build Coastguard Worker /* Receive them all */
169*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < ctx->num_packets; i++) {
170*49cdfc7eSAndroid Build Coastguard Worker char data[DATASIZE];
171*49cdfc7eSAndroid Build Coastguard Worker int ret, done = 0;
172*49cdfc7eSAndroid Build Coastguard Worker
173*49cdfc7eSAndroid Build Coastguard Worker again:
174*49cdfc7eSAndroid Build Coastguard Worker ret = read(ctx->in_fds[0], data + done, DATASIZE - done);
175*49cdfc7eSAndroid Build Coastguard Worker if (ret < 0)
176*49cdfc7eSAndroid Build Coastguard Worker barf("SERVER: read");
177*49cdfc7eSAndroid Build Coastguard Worker done += ret;
178*49cdfc7eSAndroid Build Coastguard Worker if (done < DATASIZE)
179*49cdfc7eSAndroid Build Coastguard Worker goto again;
180*49cdfc7eSAndroid Build Coastguard Worker }
181*49cdfc7eSAndroid Build Coastguard Worker
182*49cdfc7eSAndroid Build Coastguard Worker return NULL;
183*49cdfc7eSAndroid Build Coastguard Worker }
184*49cdfc7eSAndroid Build Coastguard Worker
create_worker(void * ctx,void * (* func)(void *))185*49cdfc7eSAndroid Build Coastguard Worker pthread_t create_worker(void *ctx, void *(*func) (void *))
186*49cdfc7eSAndroid Build Coastguard Worker {
187*49cdfc7eSAndroid Build Coastguard Worker pthread_attr_t attr;
188*49cdfc7eSAndroid Build Coastguard Worker pthread_t childid;
189*49cdfc7eSAndroid Build Coastguard Worker int err;
190*49cdfc7eSAndroid Build Coastguard Worker
191*49cdfc7eSAndroid Build Coastguard Worker if (process_mode) {
192*49cdfc7eSAndroid Build Coastguard Worker /* process mode */
193*49cdfc7eSAndroid Build Coastguard Worker /* Fork the receiver. */
194*49cdfc7eSAndroid Build Coastguard Worker switch (fork()) {
195*49cdfc7eSAndroid Build Coastguard Worker case -1:
196*49cdfc7eSAndroid Build Coastguard Worker barf("fork()");
197*49cdfc7eSAndroid Build Coastguard Worker case 0:
198*49cdfc7eSAndroid Build Coastguard Worker (*func) (ctx);
199*49cdfc7eSAndroid Build Coastguard Worker exit(0);
200*49cdfc7eSAndroid Build Coastguard Worker }
201*49cdfc7eSAndroid Build Coastguard Worker
202*49cdfc7eSAndroid Build Coastguard Worker return (pthread_t) 0;
203*49cdfc7eSAndroid Build Coastguard Worker }
204*49cdfc7eSAndroid Build Coastguard Worker
205*49cdfc7eSAndroid Build Coastguard Worker if (pthread_attr_init(&attr) != 0)
206*49cdfc7eSAndroid Build Coastguard Worker barf("pthread_attr_init:");
207*49cdfc7eSAndroid Build Coastguard Worker
208*49cdfc7eSAndroid Build Coastguard Worker #ifndef __ia64__
209*49cdfc7eSAndroid Build Coastguard Worker if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
210*49cdfc7eSAndroid Build Coastguard Worker barf("pthread_attr_setstacksize");
211*49cdfc7eSAndroid Build Coastguard Worker #endif
212*49cdfc7eSAndroid Build Coastguard Worker
213*49cdfc7eSAndroid Build Coastguard Worker if ((err = pthread_create(&childid, &attr, func, ctx)) != 0) {
214*49cdfc7eSAndroid Build Coastguard Worker fprintf(stderr, "pthread_create failed: %s (%d)\n",
215*49cdfc7eSAndroid Build Coastguard Worker strerror(err), err);
216*49cdfc7eSAndroid Build Coastguard Worker exit(-1);
217*49cdfc7eSAndroid Build Coastguard Worker }
218*49cdfc7eSAndroid Build Coastguard Worker return (childid);
219*49cdfc7eSAndroid Build Coastguard Worker }
220*49cdfc7eSAndroid Build Coastguard Worker
reap_worker(pthread_t id)221*49cdfc7eSAndroid Build Coastguard Worker void reap_worker(pthread_t id)
222*49cdfc7eSAndroid Build Coastguard Worker {
223*49cdfc7eSAndroid Build Coastguard Worker int status;
224*49cdfc7eSAndroid Build Coastguard Worker
225*49cdfc7eSAndroid Build Coastguard Worker if (process_mode) {
226*49cdfc7eSAndroid Build Coastguard Worker /* process mode */
227*49cdfc7eSAndroid Build Coastguard Worker wait(&status);
228*49cdfc7eSAndroid Build Coastguard Worker if (!WIFEXITED(status))
229*49cdfc7eSAndroid Build Coastguard Worker exit(1);
230*49cdfc7eSAndroid Build Coastguard Worker } else {
231*49cdfc7eSAndroid Build Coastguard Worker void *status;
232*49cdfc7eSAndroid Build Coastguard Worker
233*49cdfc7eSAndroid Build Coastguard Worker pthread_join(id, &status);
234*49cdfc7eSAndroid Build Coastguard Worker }
235*49cdfc7eSAndroid Build Coastguard Worker }
236*49cdfc7eSAndroid Build Coastguard Worker
237*49cdfc7eSAndroid Build Coastguard Worker /* One group of senders and receivers */
group(pthread_t * pth,unsigned int num_fds,int ready_out,int wakefd)238*49cdfc7eSAndroid Build Coastguard Worker static unsigned int group(pthread_t * pth,
239*49cdfc7eSAndroid Build Coastguard Worker unsigned int num_fds, int ready_out, int wakefd)
240*49cdfc7eSAndroid Build Coastguard Worker {
241*49cdfc7eSAndroid Build Coastguard Worker unsigned int i;
242*49cdfc7eSAndroid Build Coastguard Worker struct sender_context *snd_ctx = malloc(sizeof(struct sender_context) + num_fds * sizeof(int));
243*49cdfc7eSAndroid Build Coastguard Worker if (!snd_ctx)
244*49cdfc7eSAndroid Build Coastguard Worker barf("malloc()");
245*49cdfc7eSAndroid Build Coastguard Worker else
246*49cdfc7eSAndroid Build Coastguard Worker snd_ctx_tab[gr_num] = snd_ctx;
247*49cdfc7eSAndroid Build Coastguard Worker
248*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
249*49cdfc7eSAndroid Build Coastguard Worker int fds[2];
250*49cdfc7eSAndroid Build Coastguard Worker struct receiver_context *ctx = malloc(sizeof(*ctx));
251*49cdfc7eSAndroid Build Coastguard Worker
252*49cdfc7eSAndroid Build Coastguard Worker if (!ctx)
253*49cdfc7eSAndroid Build Coastguard Worker barf("malloc()");
254*49cdfc7eSAndroid Build Coastguard Worker else
255*49cdfc7eSAndroid Build Coastguard Worker rev_ctx_tab[gr_num * num_fds + i] = ctx;
256*49cdfc7eSAndroid Build Coastguard Worker
257*49cdfc7eSAndroid Build Coastguard Worker /* Create the pipe between client and server */
258*49cdfc7eSAndroid Build Coastguard Worker fdpair(fds);
259*49cdfc7eSAndroid Build Coastguard Worker
260*49cdfc7eSAndroid Build Coastguard Worker ctx->num_packets = num_fds * loops;
261*49cdfc7eSAndroid Build Coastguard Worker ctx->in_fds[0] = fds[0];
262*49cdfc7eSAndroid Build Coastguard Worker ctx->in_fds[1] = fds[1];
263*49cdfc7eSAndroid Build Coastguard Worker ctx->ready_out = ready_out;
264*49cdfc7eSAndroid Build Coastguard Worker ctx->wakefd = wakefd;
265*49cdfc7eSAndroid Build Coastguard Worker
266*49cdfc7eSAndroid Build Coastguard Worker pth[i] = create_worker(ctx, (void *)(void *)receiver);
267*49cdfc7eSAndroid Build Coastguard Worker
268*49cdfc7eSAndroid Build Coastguard Worker snd_ctx->out_fds[i] = fds[1];
269*49cdfc7eSAndroid Build Coastguard Worker if (process_mode)
270*49cdfc7eSAndroid Build Coastguard Worker close(fds[0]);
271*49cdfc7eSAndroid Build Coastguard Worker }
272*49cdfc7eSAndroid Build Coastguard Worker
273*49cdfc7eSAndroid Build Coastguard Worker /* Now we have all the fds, fork the senders */
274*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
275*49cdfc7eSAndroid Build Coastguard Worker snd_ctx->ready_out = ready_out;
276*49cdfc7eSAndroid Build Coastguard Worker snd_ctx->wakefd = wakefd;
277*49cdfc7eSAndroid Build Coastguard Worker snd_ctx->num_fds = num_fds;
278*49cdfc7eSAndroid Build Coastguard Worker
279*49cdfc7eSAndroid Build Coastguard Worker pth[num_fds + i] =
280*49cdfc7eSAndroid Build Coastguard Worker create_worker(snd_ctx, (void *)(void *)sender);
281*49cdfc7eSAndroid Build Coastguard Worker }
282*49cdfc7eSAndroid Build Coastguard Worker
283*49cdfc7eSAndroid Build Coastguard Worker /* Close the fds we have left */
284*49cdfc7eSAndroid Build Coastguard Worker if (process_mode)
285*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++)
286*49cdfc7eSAndroid Build Coastguard Worker close(snd_ctx->out_fds[i]);
287*49cdfc7eSAndroid Build Coastguard Worker
288*49cdfc7eSAndroid Build Coastguard Worker gr_num++;
289*49cdfc7eSAndroid Build Coastguard Worker /* Return number of children to reap */
290*49cdfc7eSAndroid Build Coastguard Worker return num_fds * 2;
291*49cdfc7eSAndroid Build Coastguard Worker }
292*49cdfc7eSAndroid Build Coastguard Worker
main(int argc,char * argv[])293*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char *argv[])
294*49cdfc7eSAndroid Build Coastguard Worker {
295*49cdfc7eSAndroid Build Coastguard Worker unsigned int i, j, num_groups = 10, total_children;
296*49cdfc7eSAndroid Build Coastguard Worker struct timeval start, stop, diff;
297*49cdfc7eSAndroid Build Coastguard Worker unsigned int num_fds = 20;
298*49cdfc7eSAndroid Build Coastguard Worker int readyfds[2], wakefds[2];
299*49cdfc7eSAndroid Build Coastguard Worker char dummy;
300*49cdfc7eSAndroid Build Coastguard Worker pthread_t *pth_tab;
301*49cdfc7eSAndroid Build Coastguard Worker
302*49cdfc7eSAndroid Build Coastguard Worker if (argv[1] && strcmp(argv[1], "-pipe") == 0) {
303*49cdfc7eSAndroid Build Coastguard Worker use_pipes = 1;
304*49cdfc7eSAndroid Build Coastguard Worker argc--;
305*49cdfc7eSAndroid Build Coastguard Worker argv++;
306*49cdfc7eSAndroid Build Coastguard Worker }
307*49cdfc7eSAndroid Build Coastguard Worker
308*49cdfc7eSAndroid Build Coastguard Worker if (argc >= 2 && (num_groups = atoi(argv[1])) == 0)
309*49cdfc7eSAndroid Build Coastguard Worker print_usage_exit();
310*49cdfc7eSAndroid Build Coastguard Worker
311*49cdfc7eSAndroid Build Coastguard Worker printf("Running with %d*40 (== %d) tasks.\n",
312*49cdfc7eSAndroid Build Coastguard Worker num_groups, num_groups * 40);
313*49cdfc7eSAndroid Build Coastguard Worker
314*49cdfc7eSAndroid Build Coastguard Worker fflush(NULL);
315*49cdfc7eSAndroid Build Coastguard Worker
316*49cdfc7eSAndroid Build Coastguard Worker if (argc > 2) {
317*49cdfc7eSAndroid Build Coastguard Worker if (!strcmp(argv[2], "process"))
318*49cdfc7eSAndroid Build Coastguard Worker process_mode = 1;
319*49cdfc7eSAndroid Build Coastguard Worker else if (!strcmp(argv[2], "thread"))
320*49cdfc7eSAndroid Build Coastguard Worker process_mode = 0;
321*49cdfc7eSAndroid Build Coastguard Worker else
322*49cdfc7eSAndroid Build Coastguard Worker print_usage_exit();
323*49cdfc7eSAndroid Build Coastguard Worker }
324*49cdfc7eSAndroid Build Coastguard Worker
325*49cdfc7eSAndroid Build Coastguard Worker if (argc > 3)
326*49cdfc7eSAndroid Build Coastguard Worker loops = atoi(argv[3]);
327*49cdfc7eSAndroid Build Coastguard Worker
328*49cdfc7eSAndroid Build Coastguard Worker pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
329*49cdfc7eSAndroid Build Coastguard Worker snd_ctx_tab = malloc(num_groups * sizeof(void *));
330*49cdfc7eSAndroid Build Coastguard Worker rev_ctx_tab = malloc(num_groups * num_fds * sizeof(void *));
331*49cdfc7eSAndroid Build Coastguard Worker if (!pth_tab || !snd_ctx_tab || !rev_ctx_tab)
332*49cdfc7eSAndroid Build Coastguard Worker barf("main:malloc()");
333*49cdfc7eSAndroid Build Coastguard Worker
334*49cdfc7eSAndroid Build Coastguard Worker fdpair(readyfds);
335*49cdfc7eSAndroid Build Coastguard Worker fdpair(wakefds);
336*49cdfc7eSAndroid Build Coastguard Worker
337*49cdfc7eSAndroid Build Coastguard Worker total_children = 0;
338*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < num_groups; i++)
339*49cdfc7eSAndroid Build Coastguard Worker total_children +=
340*49cdfc7eSAndroid Build Coastguard Worker group(pth_tab + total_children, num_fds, readyfds[1],
341*49cdfc7eSAndroid Build Coastguard Worker wakefds[0]);
342*49cdfc7eSAndroid Build Coastguard Worker
343*49cdfc7eSAndroid Build Coastguard Worker /* Wait for everyone to be ready */
344*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < total_children; i++)
345*49cdfc7eSAndroid Build Coastguard Worker if (read(readyfds[0], &dummy, 1) != 1)
346*49cdfc7eSAndroid Build Coastguard Worker barf("Reading for readyfds");
347*49cdfc7eSAndroid Build Coastguard Worker
348*49cdfc7eSAndroid Build Coastguard Worker gettimeofday(&start, NULL);
349*49cdfc7eSAndroid Build Coastguard Worker
350*49cdfc7eSAndroid Build Coastguard Worker /* Kick them off */
351*49cdfc7eSAndroid Build Coastguard Worker if (write(wakefds[1], &dummy, 1) != 1)
352*49cdfc7eSAndroid Build Coastguard Worker barf("Writing to start them");
353*49cdfc7eSAndroid Build Coastguard Worker
354*49cdfc7eSAndroid Build Coastguard Worker /* Reap them all */
355*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < total_children; i++)
356*49cdfc7eSAndroid Build Coastguard Worker reap_worker(pth_tab[i]);
357*49cdfc7eSAndroid Build Coastguard Worker
358*49cdfc7eSAndroid Build Coastguard Worker gettimeofday(&stop, NULL);
359*49cdfc7eSAndroid Build Coastguard Worker
360*49cdfc7eSAndroid Build Coastguard Worker /* Print time... */
361*49cdfc7eSAndroid Build Coastguard Worker timersub(&stop, &start, &diff);
362*49cdfc7eSAndroid Build Coastguard Worker printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec / 1000);
363*49cdfc7eSAndroid Build Coastguard Worker
364*49cdfc7eSAndroid Build Coastguard Worker /* free the memory */
365*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < num_groups; i++) {
366*49cdfc7eSAndroid Build Coastguard Worker for (j = 0; j < num_fds; j++) {
367*49cdfc7eSAndroid Build Coastguard Worker SAFE_FREE(rev_ctx_tab[i * num_fds + j])
368*49cdfc7eSAndroid Build Coastguard Worker }
369*49cdfc7eSAndroid Build Coastguard Worker SAFE_FREE(snd_ctx_tab[i]);
370*49cdfc7eSAndroid Build Coastguard Worker }
371*49cdfc7eSAndroid Build Coastguard Worker SAFE_FREE(pth_tab);
372*49cdfc7eSAndroid Build Coastguard Worker SAFE_FREE(snd_ctx_tab);
373*49cdfc7eSAndroid Build Coastguard Worker SAFE_FREE(rev_ctx_tab);
374*49cdfc7eSAndroid Build Coastguard Worker exit(0);
375*49cdfc7eSAndroid Build Coastguard Worker }
376