xref: /xnu-11215/tools/tests/execperf/run.c (revision a5e72196)
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdint.h>
5 #include <errno.h>
6 #include <err.h>
7 #include <pthread.h>
8 #include <spawn.h>
9 
10 extern char **environ;
11 
12 char * const *newargv;
13 
14 void usage(void);
15 
16 void *work(void *);
17 
18 int
main(int argc,char * argv[])19 main(int argc, char *argv[])
20 {
21 	int i, count, threadcount;
22 	int ret;
23 	pthread_t *threads;
24 
25 	if (argc < 4) {
26 		usage();
27 	}
28 
29 	threadcount = atoi(argv[1]);
30 	count = atoi(argv[2]);
31 
32 	newargv = &argv[3];
33 
34 	threads = (pthread_t *)calloc(threadcount, sizeof(pthread_t));
35 	for (i = 0; i < threadcount; i++) {
36 		ret = pthread_create(&threads[i], NULL, work, (void *)(intptr_t)count);
37 		if (ret) {
38 			err(1, "pthread_create");
39 		}
40 	}
41 
42 	for (i = 0; i < threadcount; i++) {
43 		ret = pthread_join(threads[i], NULL);
44 		if (ret) {
45 			err(1, "pthread_join");
46 		}
47 	}
48 
49 	return 0;
50 }
51 
52 void
usage(void)53 usage(void)
54 {
55 	fprintf(stderr, "Usage: %s <threadcount> <count> <program> [<arg1> [<arg2> ...]]\n",
56 	    getprogname());
57 	exit(1);
58 }
59 
60 void *
work(void * arg)61 work(void *arg)
62 {
63 	int count = (int)(intptr_t)arg;
64 	int i;
65 	int ret;
66 	pid_t pid;
67 
68 	for (i = 0; i < count; i++) {
69 		ret = posix_spawn(&pid, newargv[0], NULL, NULL, newargv, environ);
70 		if (ret != 0) {
71 			errc(1, ret, "posix_spawn(%s)", newargv[0]);
72 		}
73 
74 		while (-1 == waitpid(pid, &ret, 0)) {
75 			if (errno != EINTR) {
76 				err(1, "waitpid(%d)", pid);
77 			}
78 		}
79 
80 		if (WIFSIGNALED(ret)) {
81 			errx(1, "process exited with signal %d", WTERMSIG(ret));
82 		} else if (WIFSTOPPED(ret)) {
83 			errx(1, "process stopped with signal %d", WSTOPSIG(ret));
84 		} else if (WIFEXITED(ret)) {
85 			if (WEXITSTATUS(ret) != 42) {
86 				errx(1, "process exited with unexpected exit code %d", WEXITSTATUS(ret));
87 			}
88 		} else {
89 			errx(1, "unknown exit condition %x", ret);
90 		}
91 	}
92 
93 	return NULL;
94 }
95