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 2002 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31#include <sys/mman.h> 32#include <unistd.h> 33#include <stdlib.h> 34#include <stdio.h> 35#include <fcntl.h> 36#include <strings.h> 37 38#include "libmicro.h" 39 40typedef volatile char vchar_t; 41 42typedef struct { 43 int ts_once; 44 vchar_t ** ts_map; 45 vchar_t ts_foo; 46} tsd_t; 47 48#define DEFF "/dev/zero" 49#define DEFL 8192 50 51static char *optf = DEFF; 52static long long optl = DEFL; 53static int optr = 0; 54static int opts = 0; 55static int optw = 0; 56static int fd = -1; 57static int anon = 0; 58 59int 60benchmark_init() 61{ 62 lm_tsdsize = sizeof (tsd_t); 63 64 (void) sprintf(lm_optstr, "f:l:rsw"); 65 66 (void) sprintf(lm_usage, 67 " [-f file-to-map (default %s)]\n" 68 " [-l mapping-length (default %d)]\n" 69 " [-r] (read a byte from each page)\n" 70 " [-w] (write a byte on each page)\n" 71 " [-s] (use MAP_SHARED)\n" 72 "notes: measures mmap()\n", 73 DEFF, DEFL); 74 75 (void) sprintf(lm_header, "%8s %5s", "length", "flags"); 76 77 return (0); 78} 79 80int 81benchmark_optswitch(int opt, char *optarg) 82{ 83 switch (opt) { 84 case 'f': 85 optf = optarg; 86 anon = strcmp(optf, "MAP_ANON") == 0; 87 break; 88 case 'l': 89 optl = sizetoll(optarg); 90 break; 91 case 'r': 92 optr = 1; 93 break; 94 case 's': 95 opts = 1; 96 break; 97 case 'w': 98 optw = 1; 99 break; 100 default: 101 return (-1); 102 } 103 return (0); 104} 105 106int 107benchmark_initrun() 108{ 109 if (!anon) 110 fd = open(optf, O_RDWR); 111 112 return (0); 113} 114 115int 116benchmark_initbatch(void *tsd) 117{ 118 tsd_t *ts = (tsd_t *)tsd; 119 int errors = 0; 120 121 if (ts->ts_once++ == 0) { 122 ts->ts_map = (vchar_t **)malloc(lm_optB * sizeof (void *)); 123 if (ts->ts_map == NULL) { 124 errors++; 125 } 126 } 127 128 return (errors); 129} 130 131int 132benchmark(void *tsd, result_t *res) 133{ 134 tsd_t *ts = (tsd_t *)tsd; 135 int i, j; 136 137 for (i = 0; i < lm_optB; i++) { 138 if (anon) { 139 ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 140 PROT_READ | PROT_WRITE, 141 MAP_ANON | (opts ? MAP_SHARED : MAP_PRIVATE), 142 -1, 0L); 143 } else { 144 ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 145 PROT_READ | PROT_WRITE, 146 opts ? MAP_SHARED : MAP_PRIVATE, 147 fd, 0L); 148 } 149 150 if (ts->ts_map[i] == MAP_FAILED) { 151 res->re_errors++; 152 continue; 153 } 154 155 if (optr) { 156 for (j = 0; j < optl; j += 4096) { 157 ts->ts_foo += ts->ts_map[i][j]; 158 } 159 } 160 if (optw) { 161 for (j = 0; j < optl; j += 4096) { 162 ts->ts_map[i][j] = 1; 163 } 164 } 165 } 166 res->re_count = i; 167 168 return (0); 169} 170 171int 172benchmark_finibatch(void *tsd) 173{ 174 tsd_t *ts = (tsd_t *)tsd; 175 int i; 176 177 for (i = 0; i < lm_optB; i++) { 178 (void) munmap((void *)ts->ts_map[i], optl); 179 } 180 return (0); 181} 182 183char * 184benchmark_result() 185{ 186 static char result[256]; 187 char flags[5]; 188 189 flags[0] = anon ? 'a' : '-'; 190 flags[1] = optr ? 'r' : '-'; 191 flags[2] = optw ? 'w' : '-'; 192 flags[3] = opts ? 's' : '-'; 193 flags[4] = 0; 194 195 (void) sprintf(result, "%8lld %5s", optl, flags); 196 197 return (result); 198} 199