Home | History | Annotate | Download | only in libmicro
      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 
     40 typedef 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 
     48 static char			*optf = DEFF;
     49 static long long		optl = DEFL;
     50 static int			optr = 0;
     51 static int			opts = 0;
     52 static int			optw = 0;
     53 static int			opta = MS_SYNC;
     54 static int			opti = 0;
     55 static int			anon = 0;
     56 static int			pagesize;
     57 
     58 int
     59 benchmark_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 
     81 int
     82 benchmark_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 
    118 int
    119 benchmark_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 
    143 int
    144 benchmark(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 
    174 char *
    175 benchmark_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