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 2004 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_batch; 44 int ts_res; 45} tsd_t; 46 47#define DEFF "/dev/zero" 48#define DEFL 8192 49 50static char *optf = DEFF; 51static long long optl = DEFL; 52static int optr = 0; 53static int optw = 0; 54static int opts = 0; 55static int optt = 0; 56static int fd = -1; 57static int anon = 0; 58static int foo = 0; 59static vchar_t *seg; 60static int pagesize; 61 62int 63benchmark_init() 64{ 65 lm_tsdsize = sizeof (tsd_t); 66 67 (void) sprintf(lm_optstr, "f:l:rstw"); 68 69 (void) sprintf(lm_usage, 70 " [-f file-to-map (default %s)]\n" 71 " [-l mapping-length (default %d)]\n" 72 " [-r] (read a byte from each page)\n" 73 " [-w] (write a byte on each page)\n" 74 " [-s] (use MAP_SHARED)\n" 75 " [-t] (touch each page after restoring permissions)\n" 76 "notes: measures mprotect()\n", 77 DEFF, DEFL); 78 79 (void) sprintf(lm_header, "%8s %5s", "size", "flags"); 80 81 return (0); 82} 83 84int 85benchmark_optswitch(int opt, char *optarg) 86{ 87 switch (opt) { 88 case 'f': 89 optf = optarg; 90 anon = strcmp(optf, "MAP_ANON") == 0; 91 break; 92 case 'l': 93 optl = sizetoll(optarg); 94 break; 95 case 'r': 96 optr = 1; 97 break; 98 case 's': 99 opts = 1; 100 break; 101 case 't': 102 optt = 1; 103 break; 104 case 'w': 105 optw = 1; 106 break; 107 default: 108 return (-1); 109 } 110 return (0); 111} 112 113int 114benchmark_initrun() 115{ 116 int flags; 117 int i; 118 119 if (!anon) 120 fd = open(optf, O_RDWR); 121 122 flags = opts ? MAP_SHARED : MAP_PRIVATE; 123 flags |= anon ? MAP_ANON : 0; 124 125 seg = (vchar_t *)mmap(NULL, lm_optB * optl, PROT_READ | PROT_WRITE, 126 flags, anon ? -1 : fd, 0L); 127 128 if (seg == MAP_FAILED) { 129 return (-1); 130 } 131 132 if (optr) { 133 for (i = 0; i < lm_optB * optl; i += 4096) { 134 foo += seg[i]; 135 } 136 } 137 138 if (optw) { 139 for (i = 0; i < lm_optB * optl; i += 4096) { 140 seg[i] = 1; 141 } 142 } 143 144 pagesize = getpagesize(); 145 146 return (0); 147} 148 149int 150benchmark(void *tsd, result_t *res) 151{ 152 tsd_t *ts = (tsd_t *)tsd; 153 int i; 154 int us; 155 int prot = PROT_NONE; 156 int j, k; 157 158 us = (getpindex() * lm_optT) + gettindex(); 159 for (i = 0; i < lm_optB; i++) { 160 switch ((us + ts->ts_batch + i) % 2) { 161 case 0: 162 prot = PROT_NONE; 163 if (optt) { 164 for (j = k = 0; j < optl; j += pagesize) 165 k += seg[i * optl + j]; 166 ts->ts_res += k; 167 } 168 break; 169 default: 170 prot = PROT_READ | PROT_WRITE; 171 break; 172 } 173 174 if (mprotect((void *)&seg[i * optl], optl, prot) == -1) { 175 res->re_errors++; 176 } 177 } 178 res->re_count += lm_optB; 179 ts->ts_batch++; 180 181 return (0); 182} 183 184char * 185benchmark_result() 186{ 187 static char result[256]; 188 char flags[6]; 189 190 flags[0] = anon ? 'a' : '-'; 191 flags[1] = optr ? 'r' : '-'; 192 flags[2] = optw ? 'w' : '-'; 193 flags[3] = opts ? 's' : '-'; 194 flags[4] = optt ? 't' : '-'; 195 flags[5] = 0; 196 197 (void) sprintf(result, "%8lld %5s", optl, flags); 198 199 return (result); 200} 201