Home | History | Annotate | Line # | Download | only in h_client
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