1138568Ssam/* 2138568Ssam * CDDL HEADER START 3139530Ssam * 4138568Ssam * The contents of this file are subject to the terms 5138568Ssam * of the Common Development and Distribution License 6138568Ssam * (the "License"). You may not use this file except 7138568Ssam * in compliance with the License. 8138568Ssam * 9138568Ssam * You can obtain a copy of the license at 10138568Ssam * src/OPENSOLARIS.LICENSE 11138568Ssam * or http://www.opensolaris.org/os/licensing. 12138568Ssam * See the License for the specific language governing 13138568Ssam * permissions and limitations under the License. 14138568Ssam * 15138568Ssam * When distributing Covered Code, include this CDDL 16138568Ssam * HEADER in each file and include the License file at 17138568Ssam * usr/src/OPENSOLARIS.LICENSE. If applicable, 18138568Ssam * add the following below this CDDL HEADER, with the 19138568Ssam * fields enclosed by brackets "[]" replaced with your 20138568Ssam * own identifying information: Portions Copyright [yyyy] 21138568Ssam * [name of copyright owner] 22138568Ssam * 23138568Ssam * CDDL HEADER END 24138568Ssam */ 25138568Ssam 26138568Ssam/* 27138568Ssam * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28138568Ssam * Use is subject to license terms. 29138568Ssam */ 30138568Ssam 31138568Ssam#include <sys/mman.h> 32138568Ssam#include <unistd.h> 33138568Ssam#include <stdlib.h> 34138568Ssam#include <stdio.h> 35138568Ssam#include <fcntl.h> 36138568Ssam#include <strings.h> 37138568Ssam 38138568Ssam#include "libmicro.h" 39138568Ssam 40138568Ssamtypedef volatile char vchar_t; 41138568Ssam 42138568Ssamtypedef struct { 43138568Ssam int ts_once; 44138568Ssam vchar_t ** ts_map; 45138568Ssam vchar_t ts_foo; 46138568Ssam} tsd_t; 47138568Ssam 48138568Ssam#define DEFF "/dev/zero" 49138568Ssam#define DEFL 8192 50138568Ssam 51138568Ssamstatic char *optf = DEFF; 52138568Ssamstatic long long optl = DEFL; 53138568Ssamstatic int optr = 0; 54138568Ssamstatic int opts = 0; 55138568Ssamstatic int optw = 0; 56138568Ssamstatic int fd = -1; 57138568Ssamstatic int anon = 0; 58138568Ssam 59138568Ssamint 60138568Ssambenchmark_init() 61138568Ssam{ 62138568Ssam lm_tsdsize = sizeof (tsd_t); 63138568Ssam 64138568Ssam (void) sprintf(lm_optstr, "f:l:rsw"); 65138568Ssam 66138568Ssam (void) sprintf(lm_usage, 67138568Ssam " [-f file-to-map (default %s)]\n" 68138568Ssam " [-l mapping-length (default %d)]\n" 69138568Ssam " [-r] (read a byte from each page)\n" 70138568Ssam " [-w] (write a byte on each page)\n" 71138568Ssam " [-s] (use MAP_SHARED)\n" 72138568Ssam "notes: measures mmap()\n", 73138568Ssam DEFF, DEFL); 74138568Ssam 75138568Ssam (void) sprintf(lm_header, "%8s %5s", "length", "flags"); 76138568Ssam 77138568Ssam return (0); 78138568Ssam} 79138568Ssam 80138568Ssamint 81138568Ssambenchmark_optswitch(int opt, char *optarg) 82138568Ssam{ 83138568Ssam switch (opt) { 84138568Ssam case 'f': 85138568Ssam optf = optarg; 86138568Ssam anon = strcmp(optf, "MAP_ANON") == 0; 87138568Ssam break; 88138568Ssam case 'l': 89138568Ssam optl = sizetoll(optarg); 90138568Ssam break; 91138568Ssam case 'r': 92138568Ssam optr = 1; 93138568Ssam break; 94138568Ssam case 's': 95138568Ssam opts = 1; 96138568Ssam break; 97138568Ssam case 'w': 98138568Ssam optw = 1; 99138568Ssam break; 100138568Ssam default: 101138568Ssam return (-1); 102138568Ssam } 103138568Ssam return (0); 104138568Ssam} 105138568Ssam 106138568Ssamint 107138568Ssambenchmark_initrun() 108138568Ssam{ 109138568Ssam if (!anon) 110138568Ssam fd = open(optf, O_RDWR); 111138568Ssam 112138568Ssam return (0); 113138568Ssam} 114138568Ssam 115138568Ssamint 116138568Ssambenchmark_initbatch(void *tsd) 117138568Ssam{ 118138568Ssam tsd_t *ts = (tsd_t *)tsd; 119138568Ssam int errors = 0; 120138568Ssam 121138568Ssam if (ts->ts_once++ == 0) { 122138568Ssam ts->ts_map = (vchar_t **)malloc(lm_optB * sizeof (void *)); 123138568Ssam if (ts->ts_map == NULL) { 124138568Ssam errors++; 125138568Ssam } 126166012Ssam } 127165569Ssam 128165569Ssam return (errors); 129138568Ssam} 130138568Ssam 131138568Ssamint 132138568Ssambenchmark(void *tsd, result_t *res) 133138568Ssam{ 134138568Ssam tsd_t *ts = (tsd_t *)tsd; 135138568Ssam int i, j; 136138568Ssam 137138568Ssam for (i = 0; i < lm_optB; i++) { 138138568Ssam if (anon) { 139138568Ssam ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 140138568Ssam PROT_READ | PROT_WRITE, 141138568Ssam MAP_ANON | (opts ? MAP_SHARED : MAP_PRIVATE), 142138568Ssam -1, 0L); 143138568Ssam } else { 144138568Ssam ts->ts_map[i] = (vchar_t *)mmap(NULL, optl, 145138568Ssam PROT_READ | PROT_WRITE, 146138568Ssam opts ? MAP_SHARED : MAP_PRIVATE, 147138568Ssam fd, 0L); 148153347Ssam } 149153347Ssam 150153347Ssam if (ts->ts_map[i] == MAP_FAILED) { 151153347Ssam res->re_errors++; 152153347Ssam continue; 153153347Ssam } 154138568Ssam 155138568Ssam if (optr) { 156138568Ssam for (j = 0; j < optl; j += 4096) { 157138568Ssam ts->ts_foo += ts->ts_map[i][j]; 158138568Ssam } 159138568Ssam } 160138568Ssam if (optw) { 161138568Ssam for (j = 0; j < optl; j += 4096) { 162138568Ssam ts->ts_map[i][j] = 1; 163138568Ssam } 164148941Ssam } 165148941Ssam } 166138568Ssam res->re_count = i; 167138568Ssam 168138568Ssam return (0); 169138568Ssam} 170138568Ssam 171138568Ssamint 172138568Ssambenchmark_finibatch(void *tsd) 173138568Ssam{ 174138568Ssam tsd_t *ts = (tsd_t *)tsd; 175138568Ssam int i; 176138568Ssam 177138568Ssam for (i = 0; i < lm_optB; i++) { 178138568Ssam (void) munmap((void *)ts->ts_map[i], optl); 179138568Ssam } 180138568Ssam return (0); 181165569Ssam} 182165569Ssam 183165569Ssamchar * 184165569Ssambenchmark_result() 185166012Ssam{ 186166012Ssam static char result[256]; 187166012Ssam char flags[5]; 188166012Ssam 189138568Ssam flags[0] = anon ? 'a' : '-'; 190138568Ssam flags[1] = optr ? 'r' : '-'; 191138568Ssam flags[2] = optw ? 'w' : '-'; 192138568Ssam flags[3] = opts ? 's' : '-'; 193138568Ssam flags[4] = 0; 194138568Ssam 195138568Ssam (void) sprintf(result, "%8lld %5s", optl, flags); 196138568Ssam 197138568Ssam return (result); 198138568Ssam} 199138568Ssam