1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms 5 * of the Common Development and Distribution License 6 * (the "License"). You may not use this file except 7 * in compliance with the License. 8 * 9 * You can obtain a copy of the license at 10 * src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing 13 * permissions and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL 16 * HEADER in each file and include the License file at 17 * usr/src/OPENSOLARIS.LICENSE. If applicable, 18 * add the following below this CDDL HEADER, with the 19 * fields enclosed by brackets "[]" replaced with your 20 * own identifying information: Portions Copyright [yyyy] 21 * [name of copyright owner] 22 * 23 * CDDL HEADER END 24 */ 25 26/* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31#define MAX(x, y) ((x) > (y) ? (x) : (y)) 32#define MIN(x, y) ((x) > (y) ? (y) : (x)) 33 34#include <unistd.h> 35#include <stdlib.h> 36#include <stdio.h> 37#include <string.h> 38#include <poll.h> 39#include <sys/socket.h> 40 41#include "libmicro.h" 42 43#define DEFN 256 44 45static int optn = DEFN; 46static int optr = 0; 47static int optw = 0; 48static int optx = 0; 49static int *fds; 50static int target = 0; 51 52typedef struct pollfd pfd_t; 53 54typedef struct { 55 int ts_once; 56 pfd_t *ts_pfds; 57} tsd_t; 58 59int 60benchmark_init() 61{ 62 lm_tsdsize = sizeof (tsd_t); 63 64 (void) sprintf(lm_optstr, "n:r:w:x"); 65 66 (void) sprintf(lm_usage, 67 " [-n fds-per-thread (default %d)]\n" 68 " [-r readable-fds (default 0)]\n" 69 " [-w writeable-fds (default 0)]\n" 70 " [-x] (start -r option with highest fd first; " 71 "default is lowest first)\n" 72 "notes: measures poll()\n", 73 DEFN); 74 75 (void) sprintf(lm_header, "%8s %5s", "nfds", "flags"); 76 77 return (0); 78} 79 80int 81benchmark_optswitch(int opt, char *optarg) 82{ 83 switch (opt) { 84 case 'n': 85 optn = atoi(optarg); 86 break; 87 case 'r': 88 optr = atoi(optarg); 89 break; 90 case 'w': 91 optw = atoi(optarg); 92 break; 93 case 'x': 94 optx = 1; 95 break; 96 default: 97 return (-1); 98 } 99 return (0); 100} 101 102int 103benchmark_initrun() 104{ 105 int i; 106 int j; 107 int pair[2]; 108 109 if (optn % 2 != 0) { 110 (void) printf("ERROR: -n value must be even\n"); 111 optn = optr = optw = 0; 112 return (-1); 113 } 114 115 if (optn < 0 || optr < 0 || optw < 0) { 116 (void) printf("ERROR: -n, -r and -w values must be > 0\n"); 117 optn = optr = optw = 0; 118 return (-1); 119 } 120 121 if (optr > optn || optw > optn) { 122 (void) printf("ERROR: -r and -w values must be <= maxfd\n"); 123 optn = optr = optw = 0; 124 return (-1); 125 } 126 127 fds = (int *)malloc(optn * sizeof (int)); 128 if (fds == NULL) { 129 (void) printf("ERROR: malloc() failed\n"); 130 optn = optr = optw = 0; 131 return (-1); 132 } 133 134 (void) setfdlimit(optn + 10); 135 136 137 for (i = 0; i < optn; i += 2) { 138 if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) == -1) { 139 (void) printf("ERROR: socketpair() failed\n"); 140 return (-1); 141 } 142 143 fds[i] = MIN(pair[0], pair[1]); 144 fds[i+1] = MAX(pair[0], pair[1]); 145 } 146 147 if (optx) { 148 target = MIN(optr + optw, optn); 149 for (i = 0, j = optn - 1; i < optr; i++, j--) { 150 (void) write(fds[j+1 - (2*(j%2))], "", 1); 151 } 152 } else { 153 target = MAX(optr, optw); 154 for (i = 0; i < optr; i++) { 155 (void) write(fds[i+1 - (2*(i%2))], "", 1); 156 } 157 } 158 159 return (0); 160} 161 162int 163benchmark_initbatch(void *tsd) 164{ 165 tsd_t *ts = (tsd_t *)tsd; 166 int i; 167 int errors = 0; 168 169 if (ts->ts_once++ == 0) { 170 ts->ts_pfds = (pfd_t *)malloc(optn * sizeof (pfd_t)); 171 if (ts->ts_pfds == NULL) { 172 errors++; 173 } 174 175 for (i = 0; i < optn; i++) { 176 ts->ts_pfds[i].fd = fds[i]; 177 ts->ts_pfds[i].events = POLLIN; 178 } 179 180 for (i = 0; i < optw; i++) { 181 ts->ts_pfds[i].events |= POLLOUT; 182 } 183 } 184 185 return (errors); 186} 187 188int 189benchmark(void *tsd, result_t *res) 190{ 191 tsd_t *ts = (tsd_t *)tsd; 192 int i; 193 194 for (i = 0; i < lm_optB; i++) { 195 if (poll(ts->ts_pfds, optn, 0) != target) { 196 res->re_errors++; 197 } 198 } 199 res->re_count = i; 200 201 return (0); 202} 203 204char * 205benchmark_result() 206{ 207 static char result[256]; 208 char flags[4]; 209 210 flags[0] = optr ? 'r' : '-'; 211 flags[1] = optw ? 'w' : '-'; 212 flags[2] = optx ? 'x' : '-'; 213 flags[3] = 0; 214 215 (void) sprintf(result, "%8d %5s", optn, flags); 216 217 return (result); 218} 219