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