6N/A/*
6N/A * CDDL HEADER START
6N/A *
6N/A * The contents of this file are subject to the terms
6N/A * of the Common Development and Distribution License
6N/A * (the "License"). You may not use this file except
6N/A * in compliance with the License.
6N/A *
6N/A * You can obtain a copy of the license at
6N/A * src/OPENSOLARIS.LICENSE
6N/A * or http://www.opensolaris.org/os/licensing.
6N/A * See the License for the specific language governing
6N/A * permissions and limitations under the License.
6N/A *
6N/A * When distributing Covered Code, include this CDDL
6N/A * HEADER in each file and include the License file at
6N/A * usr/src/OPENSOLARIS.LICENSE. If applicable,
6N/A * add the following below this CDDL HEADER, with the
6N/A * fields enclosed by brackets "[]" replaced with your
6N/A * own identifying information: Portions Copyright [yyyy]
6N/A * [name of copyright owner]
6N/A *
6N/A * CDDL HEADER END
6N/A */
6N/A
0N/A/*
0N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
0N/A * Use is subject to license terms.
0N/A */
0N/A
0N/A#include <unistd.h>
0N/A#include <stdlib.h>
0N/A#include <stdio.h>
0N/A#include <sys/mman.h>
0N/A#include <fcntl.h>
0N/A#include <strings.h>
0N/A
0N/A#include "libmicro.h"
0N/A
0N/Atypedef volatile char vchar_t;
0N/A
0N/Atypedef struct {
0N/A int ts_batch;
0N/A int ts_res;
0N/A} tsd_t;
0N/A
0N/A#define DEFF "/dev/zero"
0N/A#define DEFL 8192
0N/A
0N/Astatic char *optf = DEFF;
0N/Astatic long long optl = DEFL;
0N/Astatic int optr = 0;
0N/Astatic int optw = 0;
0N/Astatic int opts = 0;
0N/Astatic int optt = 0;
0N/Astatic int fd = -1;
0N/Astatic int anon = 0;
0N/Astatic int foo = 0;
0N/Astatic vchar_t *seg;
0N/Astatic int pagesize;
0N/A
0N/Aint
0N/Abenchmark_init()
0N/A{
0N/A lm_tsdsize = sizeof (tsd_t);
0N/A
0N/A (void) sprintf(lm_optstr, "f:l:rstw");
0N/A
0N/A (void) sprintf(lm_usage,
0N/A " [-f file-to-map (default %s)]\n"
0N/A " [-l mapping-length (default %d)]\n"
0N/A " [-r] (read a byte from each page)\n"
0N/A " [-w] (write a byte on each page)\n"
0N/A " [-s] (use MAP_SHARED)\n"
0N/A " [-t] (touch each page after restoring permissions)\n"
0N/A "notes: measures mprotect()\n",
0N/A DEFF, DEFL);
0N/A
0N/A (void) sprintf(lm_header, "%8s %5s", "size", "flags");
0N/A
0N/A return (0);
0N/A}
0N/A
0N/Aint
0N/Abenchmark_optswitch(int opt, char *optarg)
0N/A{
0N/A switch (opt) {
0N/A case 'f':
0N/A optf = optarg;
0N/A anon = strcmp(optf, "MAP_ANON") == 0;
0N/A break;
0N/A case 'l':
0N/A optl = sizetoll(optarg);
0N/A break;
0N/A case 'r':
0N/A optr = 1;
0N/A break;
0N/A case 's':
0N/A opts = 1;
0N/A break;
0N/A case 't':
0N/A optt = 1;
0N/A break;
0N/A case 'w':
0N/A optw = 1;
0N/A break;
0N/A default:
0N/A return (-1);
0N/A }
0N/A return (0);
0N/A}
0N/A
0N/Aint
0N/Abenchmark_initrun()
0N/A{
0N/A int flags;
0N/A int i;
0N/A
0N/A if (!anon)
0N/A fd = open(optf, O_RDWR);
0N/A
0N/A flags = opts ? MAP_SHARED : MAP_PRIVATE;
0N/A flags |= anon ? MAP_ANON : 0;
0N/A
0N/A seg = (vchar_t *)mmap(NULL, lm_optB * optl, PROT_READ | PROT_WRITE,
0N/A flags, anon ? -1 : fd, 0L);
0N/A
0N/A if (seg == MAP_FAILED) {
0N/A return (-1);
0N/A }
0N/A
0N/A if (optr) {
0N/A for (i = 0; i < lm_optB * optl; i += 4096) {
0N/A foo += seg[i];
0N/A }
0N/A }
0N/A
0N/A if (optw) {
0N/A for (i = 0; i < lm_optB * optl; i += 4096) {
0N/A seg[i] = 1;
0N/A }
0N/A }
0N/A
0N/A pagesize = getpagesize();
0N/A
0N/A return (0);
0N/A}
0N/A
0N/Aint
0N/Abenchmark(void *tsd, result_t *res)
0N/A{
0N/A tsd_t *ts = (tsd_t *)tsd;
0N/A int i;
0N/A int us;
0N/A int prot = PROT_NONE;
0N/A int j, k;
0N/A
0N/A us = (getpindex() * lm_optT) + gettindex();
0N/A for (i = 0; i < lm_optB; i++) {
0N/A switch ((us + ts->ts_batch + i) % 2) {
0N/A case 0:
0N/A prot = PROT_NONE;
0N/A if (optt) {
0N/A for (j = k = 0; j < optl; j += pagesize)
0N/A k += seg[i * optl + j];
0N/A ts->ts_res += k;
0N/A }
0N/A break;
0N/A default:
0N/A prot = PROT_READ | PROT_WRITE;
0N/A break;
0N/A }
0N/A
0N/A if (mprotect((void *)&seg[i * optl], optl, prot) == -1) {
0N/A res->re_errors++;
0N/A }
0N/A }
0N/A res->re_count += lm_optB;
0N/A ts->ts_batch++;
0N/A
0N/A return (0);
0N/A}
0N/A
0N/Achar *
0N/Abenchmark_result()
0N/A{
0N/A static char result[256];
0N/A char flags[6];
0N/A
0N/A flags[0] = anon ? 'a' : '-';
0N/A flags[1] = optr ? 'r' : '-';
0N/A flags[2] = optw ? 'w' : '-';
0N/A flags[3] = opts ? 's' : '-';
0N/A flags[4] = optt ? 't' : '-';
0N/A flags[5] = 0;
0N/A
0N/A (void) sprintf(result, "%8lld %5s", optl, flags);
0N/A
0N/A return (result);
0N/A}