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 <unistd.h> 32#include <stdlib.h> 33#include <stdio.h> 34#include <sys/mman.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 optw = 0; 55static int opts = 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 munmap()\n", 73 DEFF, DEFL); 74 75 (void) sprintf(lm_header, "%8s %5s", "size", "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 i, j; 120 int errors = 0; 121 122 if (ts->ts_once++ == 0) { 123 ts->ts_map = (vchar_t **)malloc(lm_optB * sizeof (void *)); 124 if (ts->ts_map == NULL) { 125 errors++; 126 } 127 } 128 129 for (i = 0; i < lm_optB; i++) { 130 if (anon) { 131 ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 132 PROT_READ | PROT_WRITE, 133 MAP_ANON | (opts ? MAP_SHARED : MAP_PRIVATE), 134 -1, 0L); 135 } else { 136 ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 137 PROT_READ | PROT_WRITE, 138 opts ? MAP_SHARED : MAP_PRIVATE, 139 fd, 0L); 140 } 141 142 if (ts->ts_map[i] == MAP_FAILED) { 143 errors++; 144 continue; 145 } 146 if (optr) { 147 for (j = 0; j < optl; j += 4096) { 148 ts->ts_foo += ts->ts_map[i][j]; 149 } 150 } 151 if (optw) { 152 for (j = 0; j < optl; j += 4096) { 153 ts->ts_map[i][j] = 1; 154 } 155 } 156 } 157 158 return (0); 159} 160 161int 162benchmark(void *tsd, result_t *res) 163{ 164 tsd_t *ts = (tsd_t *)tsd; 165 int i; 166 167 for (i = 0; i < lm_optB; i++) { 168 if (munmap((void *)ts->ts_map[i], optl) == -1) { 169 res->re_errors++; 170 } 171 } 172 res->re_count += lm_optB; 173 174 return (0); 175} 176 177char * 178benchmark_result() 179{ 180 static char result[256]; 181 char flags[5]; 182 183 flags[0] = anon ? 'a' : '-'; 184 flags[1] = optr ? 'r' : '-'; 185 flags[2] = optw ? 'w' : '-'; 186 flags[3] = opts ? 's' : '-'; 187 flags[4] = 0; 188 189 (void) sprintf(result, "%8lld %5s", optl, flags); 190 191 return (result); 192} 193