]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/execperf/run.c
xnu-3248.20.55.tar.gz
[apple/xnu.git] / tools / tests / execperf / run.c
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
20 int i, count, threadcount;
21 int ret;
22 pthread_t *threads;
23
24 if (argc < 4) {
25 usage();
26 }
27
28 threadcount = atoi(argv[1]);
29 count = atoi(argv[2]);
30
31 newargv = &argv[3];
32
33 threads = (pthread_t *)calloc(threadcount, sizeof(pthread_t));
34 for (i=0; i < threadcount; i++) {
35 ret = pthread_create(&threads[i], NULL, work, (void *)(intptr_t)count);
36 if (ret) {
37 err(1, "pthread_create");
38 }
39 }
40
41 for (i=0; i < threadcount; i++) {
42 ret = pthread_join(threads[i], NULL);
43 if (ret) {
44 err(1, "pthread_join");
45 }
46 }
47
48 return 0;
49 }
50
51 void usage(void) {
52 fprintf(stderr, "Usage: %s <threadcount> <count> <program> [<arg1> [<arg2> ...]]\n",
53 getprogname());
54 exit(1);
55 }
56
57 void *work(void *arg)
58 {
59 int count = (int)(intptr_t)arg;
60 int i;
61 int ret;
62 pid_t pid;
63
64 for (i=0; i < count; i++) {
65 ret = posix_spawn(&pid, newargv[0], NULL, NULL, newargv, environ);
66 if (ret != 0) {
67 errc(1, ret, "posix_spawn(%s)", newargv[0]);
68 }
69
70 while (-1 == waitpid(pid, &ret, 0)) {
71 if (errno != EINTR) {
72 err(1, "waitpid(%d)", pid);
73 }
74 }
75
76 if (WIFSIGNALED(ret)) {
77 errx(1, "process exited with signal %d", WTERMSIG(ret));
78 } else if (WIFSTOPPED(ret)) {
79 errx(1, "process stopped with signal %d", WSTOPSIG(ret));
80 } else if (WIFEXITED(ret)) {
81 if (WEXITSTATUS(ret) != 42) {
82 errx(1, "process exited with unexpected exit code %d", WEXITSTATUS(ret));
83 }
84 } else {
85 errx(1, "unknown exit condition %x", ret);
86 }
87 }
88
89 return NULL;
90 }