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