h_stresscli.c revision 1.7 1 /* $NetBSD: h_stresscli.c,v 1.7 2011/01/12 11:37:45 pooka Exp $ */
2
3 #include <sys/types.h>
4 #include <sys/atomic.h>
5 #include <sys/sysctl.h>
6 #include <sys/wait.h>
7
8 #include <err.h>
9 #include <pthread.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14
15 #include <rump/rump_syscalls.h>
16 #include <rump/rumpclient.h>
17
18 static unsigned int syscalls;
19 static pid_t mypid;
20 static volatile sig_atomic_t doquit;
21
22 static void
23 signaali(int sig)
24 {
25
26 doquit = 1;
27 }
28
29 static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
30 static char hostnamebuf[128];
31 #define HOSTNAMEBASE "rumpclient"
32
33 static void *
34 client(void *arg)
35 {
36 char buf[256];
37 size_t blen;
38
39 while (!doquit) {
40 pid_t pidi;
41 blen = sizeof(buf);
42 if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
43 buf, &blen, NULL, 0) == -1)
44 err(1, "sysctl");
45 if (strncmp(buf, hostnamebuf, sizeof(HOSTNAMEBASE)-1) != 0)
46 errx(1, "hostname (%s/%s) mismatch", buf, hostnamebuf);
47 atomic_inc_uint(&syscalls);
48
49 pidi = rump_sys_getpid();
50 if (pidi == -1)
51 err(1, "getpid");
52 if (pidi != mypid)
53 errx(1, "mypid mismatch");
54 atomic_inc_uint(&syscalls);
55 }
56
57 return NULL;
58 }
59
60 /* Stress with max 32 clients, 8 threads each (256 concurrent threads) */
61 #define NCLI 32
62 #define NTHR 8
63
64 int
65 main(int argc, char *argv[])
66 {
67 pthread_t pt[NTHR-1];
68 pid_t clis[NCLI];
69 pid_t apid;
70 int ncli = 0;
71 int i = 0, j;
72 int status, thesig;
73 int rounds;
74
75 if (argc != 2 && argc != 3)
76 errx(1, "need roundcount");
77
78 if (argc == 3) {
79 if (strcmp(argv[2], "kill") != 0)
80 errx(1, "optional 3rd param must be kill");
81 thesig = SIGKILL;
82 } else {
83 thesig = SIGUSR1;
84 }
85
86 signal(SIGUSR1, signaali);
87
88 memset(clis, 0, sizeof(clis));
89 for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) {
90 while (ncli < NCLI) {
91 switch ((apid = fork())) {
92 case -1:
93 err(1, "fork failed");
94 case 0:
95 if (rumpclient_init() == -1)
96 err(1, "rumpclient init");
97
98 mypid = rump_sys_getpid();
99 sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid);
100 if (rump_sys___sysctl(hostnamemib,
101 __arraycount(hostnamemib), NULL, NULL,
102 hostnamebuf, strlen(hostnamebuf)+1) == -1)
103 err(1, "sethostname");
104
105 for (j = 0; j < NTHR-1; j++)
106 if (pthread_create(&pt[j], NULL,
107 client, NULL) != 0)
108 err(1, "pthread create");
109 client(NULL);
110 for (j = 0; j < NTHR-1; j++)
111 pthread_join(pt[j], NULL);
112 membar_consumer();
113 fprintf(stderr, "done %d\n", syscalls);
114 exit(0);
115 /* NOTREACHED */
116 default:
117 ncli++;
118 clis[i] = apid;
119 break;
120 }
121
122 i = (i + 1) % NCLI;
123 }
124
125 usleep(100000);
126 kill(clis[i], thesig);
127
128 apid = wait(&status);
129 if (apid != clis[i])
130 errx(1, "wanted pid %d, got %d\n", clis[i], apid);
131 clis[i] = 0;
132 ncli--;
133 if (thesig == SIGUSR1) {
134 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
135 fprintf(stderr, "child died with 0x%x\n",
136 status);
137 exit(1);
138 }
139 } else {
140 if (!WIFSIGNALED(status) || WTERMSIG(status) != thesig){
141 fprintf(stderr, "child died with 0x%x\n",
142 status);
143 exit(1);
144 }
145 }
146 }
147
148 for (i = 0; i < NCLI; i++)
149 if (clis[i])
150 kill(clis[i], SIGKILL);
151 }
152