h_stresscli.c revision 1.5 1 /* $NetBSD: h_stresscli.c,v 1.5 2011/01/11 11:26:28 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;
73 int rounds;
74
75 if (argc != 2)
76 errx(1, "need roundcount");
77
78 memset(clis, 0, sizeof(clis));
79 for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) {
80 while (ncli < NCLI) {
81 switch ((apid = fork())) {
82 case -1:
83 err(1, "fork failed");
84 case 0:
85 if (rumpclient_init() == -1)
86 err(1, "rumpclient init");
87
88 mypid = rump_sys_getpid();
89 sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid);
90 if (rump_sys___sysctl(hostnamemib,
91 __arraycount(hostnamemib), NULL, NULL,
92 hostnamebuf, strlen(hostnamebuf)+1) == -1)
93 err(1, "sethostname");
94
95 signal(SIGUSR1, signaali);
96
97 for (j = 0; j < NTHR-1; j++)
98 if (pthread_create(&pt[j], NULL,
99 client, NULL) != 0)
100 err(1, "pthread create");
101 client(NULL);
102 for (j = 0; j < NTHR-1; j++)
103 pthread_join(pt[j], NULL);
104 membar_consumer();
105 fprintf(stderr, "done %d\n", syscalls);
106 exit(0);
107 /* NOTREACHED */
108 default:
109 ncli++;
110 clis[i] = apid;
111 break;
112 }
113
114 i = (i + 1) % NCLI;
115 }
116
117 usleep(100000);
118 kill(clis[i], SIGUSR1);
119
120 apid = wait(&status);
121 if (apid != clis[i])
122 errx(1, "wanted pid %d, got %d\n", clis[i], apid);
123 clis[i] = 0;
124 ncli--;
125 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
126 fprintf(stderr, "child died with 0x%x\n", status);
127 exit(1);
128 }
129 }
130
131 for (i = 0; i < NCLI; i++)
132 if (clis[i])
133 kill(clis[i], SIGKILL);
134 }
135