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 <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 struct { 41 char *ts_map; 42 int ts_foo; /* defeat optimizers */ 43} tsd_t; 44 45#define DEFF "/dev/zero" 46#define DEFL 8192 47 48static char *optf = DEFF; 49static long long optl = DEFL; 50static int optr = 0; 51static int opts = 0; 52static int optw = 0; 53static int opta = MS_SYNC; 54static int opti = 0; 55static int anon = 0; 56static int pagesize; 57 58int 59benchmark_init() 60{ 61 lm_tsdsize = sizeof (tsd_t); 62 63 (void) sprintf(lm_optstr, "af:il:rsw"); 64 65 (void) sprintf(lm_usage, 66 " [-f file-to-map (default %s)]\n" 67 " [-l mapping-length (default %d)]\n" 68 " [-r] (read a byte from each page between msyncs)\n" 69 " [-w] (write a byte to each page between msyncs)\n" 70 " [-s] (use MAP_SHARED instead of MAP_PRIVATE)\n" 71 " [-a (specify MS_ASYNC rather than default MS_SYNC)\n" 72 " [-i (specify MS_INVALIDATE)\n" 73 "notes: measures msync()\n", 74 DEFF, DEFL); 75 76 (void) sprintf(lm_header, "%8s %6s", "length", "flags"); 77 78 return (0); 79} 80 81int 82benchmark_optswitch(int opt, char *optarg) 83{ 84 switch (opt) { 85 case 'a': 86 opta = MS_ASYNC; 87 break; 88 89 case 'f': 90 optf = optarg; 91 break; 92 93 case 'i': 94 opti = MS_INVALIDATE; 95 break; 96 97 case 'l': 98 optl = sizetoll(optarg); 99 break; 100 case 'r': 101 optr = 1; 102 break; 103 case 's': 104 opts = 1; 105 break; 106 case 'w': 107 optw = 1; 108 break; 109 default: 110 return (-1); 111 } 112 113 pagesize = getpagesize(); 114 115 return (0); 116} 117 118int 119benchmark_initworker(void *tsd) 120{ 121 tsd_t *ts = (tsd_t *)tsd; 122 123 int fd; 124 125 if ((fd = open(optf, O_RDWR)) < 0) { 126 perror("open:"); 127 return (1); 128 } 129 130 (void) ftruncate(fd, optl); 131 132 if ((ts->ts_map = (char *)mmap(NULL, optl, 133 PROT_READ | PROT_WRITE, opts ? MAP_SHARED : MAP_PRIVATE, 134 fd, 0L)) == MAP_FAILED) { 135 perror("mmap:"); 136 (void) close(fd); 137 return (1); 138 } 139 140 return (0); 141} 142 143int 144benchmark(void *tsd, result_t *res) 145{ 146 tsd_t *ts = (tsd_t *)tsd; 147 int i, j; 148 149 for (i = 0; i < lm_optB; i++) { 150 151 if (msync(ts->ts_map, optl, opta | opti) < 0) { 152 perror("msync:"); 153 res->re_errors++; 154 break; 155 } 156 157 if (optr) { 158 for (j = 0; j < optl; j += pagesize) { 159 ts->ts_foo += ts->ts_map[j]; 160 } 161 } 162 163 if (optw) { 164 for (j = 0; j < optl; j += pagesize) { 165 ts->ts_map[j] = 1; 166 } 167 } 168 } 169 res->re_count = i; 170 171 return (0); 172} 173 174char * 175benchmark_result() 176{ 177 static char result[256]; 178 char flags[6]; 179 180 flags[0] = anon ? 'a' : '-'; 181 flags[1] = optr ? 'r' : '-'; 182 flags[2] = optw ? 'w' : '-'; 183 flags[3] = opts ? 's' : '-'; 184 flags[4] = opti ? 'i' : '-'; 185 flags[5] = 0; 186 187 (void) sprintf(result, "%8lld %6s", optl, flags); 188 189 return (result); 190} 191