X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e2fac8b15b12a7979f72090454d850e612fc5b13..b0d623f7f2ae71ed96e60569f61f9a9a27016e80:/tools/tests/libMicro/mprotect.c?ds=inline diff --git a/tools/tests/libMicro/mprotect.c b/tools/tests/libMicro/mprotect.c new file mode 100644 index 000000000..db6ecaae4 --- /dev/null +++ b/tools/tests/libMicro/mprotect.c @@ -0,0 +1,205 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the "License"). You may not use this file except + * in compliance with the License. + * + * You can obtain a copy of the license at + * src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * HEADER in each file and include the License file at + * usr/src/OPENSOLARIS.LICENSE. If applicable, + * add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your + * own identifying information: Portions Copyright [yyyy] + * [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include +#include +#include +#include + +#include "libmicro.h" + +typedef volatile char vchar_t; + +typedef struct { + int ts_batch; + int ts_res; +} tsd_t; + +#define DEFF "/dev/zero" +#define DEFL 8192 + +static char *optf = DEFF; +static long long optl = DEFL; +static int optr = 0; +static int optw = 0; +static int opts = 0; +static int optt = 0; +static int fd = -1; +static int anon = 0; +static int foo = 0; +static vchar_t *seg; +static int pagesize; + +int +benchmark_init() +{ + lm_tsdsize = sizeof (tsd_t); + + (void) sprintf(lm_optstr, "f:l:rstw"); + + (void) sprintf(lm_usage, + " [-f file-to-map (default %s)]\n" + " [-l mapping-length (default %d)]\n" + " [-r] (read a byte from each page)\n" + " [-w] (write a byte on each page)\n" + " [-s] (use MAP_SHARED)\n" + " [-t] (touch each page after restoring permissions)\n" + "notes: measures mprotect()\n", + DEFF, DEFL); + + (void) sprintf(lm_header, "%8s %5s", "size", "flags"); + + return (0); +} + +int +benchmark_optswitch(int opt, char *optarg) +{ + switch (opt) { + case 'f': + optf = optarg; + anon = strcmp(optf, "MAP_ANON") == 0; + break; + case 'l': + optl = sizetoll(optarg); + break; + case 'r': + optr = 1; + break; + case 's': + opts = 1; + break; + case 't': + optt = 1; + break; + case 'w': + optw = 1; + break; + default: + return (-1); + } + return (0); +} + +int +benchmark_initrun() +{ + int flags; + int i; + + if (!anon) + fd = open(optf, O_RDWR); + + flags = opts ? MAP_SHARED : MAP_PRIVATE; + flags |= anon ? MAP_ANON : 0; + + seg = (vchar_t *)mmap(NULL, lm_optB * optl, PROT_READ | PROT_WRITE, + flags, anon ? -1 : fd, 0L); + + if (seg == MAP_FAILED) { + return (-1); + } + + if (optr) { + for (i = 0; i < lm_optB * optl; i += 4096) { + foo += seg[i]; + } + } + + if (optw) { + for (i = 0; i < lm_optB * optl; i += 4096) { + seg[i] = 1; + } + } + + pagesize = getpagesize(); + + return (0); +} + +int +benchmark(void *tsd, result_t *res) +{ + tsd_t *ts = (tsd_t *)tsd; + int i; + int us; + int prot = PROT_NONE; + int j, k; + +#if !defined(__APPLE__) + us = (getpindex() * lm_optT) + gettindex(); +#else + us = gettsdindex(tsd); +#endif /* __APPLE__ */ + + for (i = 0; i < lm_optB; i++) { + switch ((us + ts->ts_batch + i) % 2) { + case 0: + prot = PROT_NONE; + if (optt) { + for (j = k = 0; j < optl; j += pagesize) + k += seg[i * optl + j]; + ts->ts_res += k; + } + break; + default: + prot = PROT_READ | PROT_WRITE; + break; + } + + if (mprotect((void *)&seg[i * optl], optl, prot) == -1) { + res->re_errors++; + } + } + res->re_count += lm_optB; + ts->ts_batch++; + + return (0); +} + +char * +benchmark_result() +{ + static char result[256]; + char flags[6]; + + flags[0] = anon ? 'a' : '-'; + flags[1] = optr ? 'r' : '-'; + flags[2] = optw ? 'w' : '-'; + flags[3] = opts ? 's' : '-'; + flags[4] = optt ? 't' : '-'; + flags[5] = 0; + + (void) sprintf(result, "%8lld %5s", optl, flags); + + return (result); +}