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 40 typedef volatile char vchar_t; 41 42 typedef struct { 43 int ts_batch; 44 int ts_res; 45 } tsd_t; 46 47 #define DEFF "/dev/zero" 48 #define DEFL 8192 49 50 static char *optf = DEFF; 51 static long long optl = DEFL; 52 static int optr = 0; 53 static int optw = 0; 54 static int opts = 0; 55 static int optt = 0; 56 static int fd = -1; 57 static int anon = 0; 58 static int foo = 0; 59 static vchar_t *seg; 60 static int pagesize; 61 62 int 63 benchmark_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 84 int 85 benchmark_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 113 int 114 benchmark_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 149 int 150 benchmark(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 184 char * 185 benchmark_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