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