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