xref: /netbsd-src/tests/rump/rumpkern/h_client/h_stresscli.c (revision 4817a0b0b8fe9612e8ebe21a9bf2d97b95038a97)
1 /*	$NetBSD: h_stresscli.c,v 1.1 2010/11/30 22:09:15 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 
21 static void
22 signaali(int sig)
23 {
24 
25 	membar_consumer();
26 	printf("process did %d syscalls\n", syscalls);
27 	_exit(0);
28 }
29 
30 static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
31 static char hostnamebuf[128];
32 #define HOSTNAMEBASE "rumpclient"
33 
34 static void *
35 client(void *arg)
36 {
37 	char buf[256];
38 	size_t blen;
39 
40 	for (;;) {
41 		pid_t pidi;
42 		blen = sizeof(buf);
43 		if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
44 		    buf, &blen, NULL, 0) == -1)
45 			err(1, "sysctl");
46 		if (strncmp(buf, hostnamebuf, sizeof(HOSTNAMEBASE)-1) != 0)
47 			errx(1, "hostname (%s/%s) mismatch", buf, hostnamebuf);
48 		atomic_inc_uint(&syscalls);
49 
50 		pidi = rump_sys_getpid();
51 		if (pidi == -1)
52 			err(1, "getpid");
53 		if (pidi != mypid)
54 			errx(1, "mypid mismatch");
55 		atomic_inc_uint(&syscalls);
56 	}
57 
58 	return NULL;
59 }
60 
61 /* Stress with max 32 clients, 8 threads each (256 concurrent threads) */
62 #define NCLI 32
63 #define NTHR 8
64 
65 int
66 main(int argc, char *argv[])
67 {
68 	pthread_t pt;
69 	pid_t clis[NCLI];
70 	pid_t apid;
71 	int ncli = 0;
72 	int i = 0, j;
73 	int status;
74 	int rounds;
75 
76 	if (argc != 2)
77 		errx(1, "need roundcount");
78 
79 	memset(clis, 0, sizeof(clis));
80 	for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) {
81 		while (ncli < NCLI) {
82 			switch ((apid = fork())) {
83 			case -1:
84 				err(1, "fork failed");
85 			case 0:
86 				if (rumpclient_init() == -1)
87 					err(1, "rumpclient init");
88 
89 				mypid = rump_sys_getpid();
90 				sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid);
91 				if (rump_sys___sysctl(hostnamemib,
92 				    __arraycount(hostnamemib), NULL, NULL,
93 				    hostnamebuf, strlen(hostnamebuf)+1) == -1)
94 					err(1, "sethostname");
95 
96 				signal(SIGUSR1, signaali);
97 
98 				for (j = 0; j < NTHR-1; j++)
99 					if (pthread_create(&pt, NULL,
100 					    client, NULL) != 0)
101 						err(1, "pthread create");
102 				client(NULL);
103 				/* NOTREACHED */
104 			default:
105 				ncli++;
106 				clis[i] = apid;
107 				break;
108 			}
109 
110 			i = (i + 1) % NCLI;
111 		}
112 
113 		usleep(100000);
114 		kill(clis[i], SIGUSR1);
115 
116 		apid = wait(&status);
117 		if (apid != clis[i])
118 			errx(1, "wanted pid %d, got %d\n", clis[i], apid);
119 		clis[i] = 0;
120 		ncli--;
121 	}
122 
123 	for (i = 0; i < NCLI; i++)
124 		if (clis[i])
125 			kill(clis[i], SIGKILL);
126 }
127