Home | History | Annotate | Line # | Download | only in h_client
h_stresscli.c revision 1.2
      1 /*	$NetBSD: h_stresscli.c,v 1.2 2011/01/06 06:59:25 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 		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
    122 			exit(1);
    123 	}
    124 
    125 	for (i = 0; i < NCLI; i++)
    126 		if (clis[i])
    127 			kill(clis[i], SIGKILL);
    128 }
    129