/* * 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 usr/src/OPENSOLARIS.LICENSE * or http://opensource.org/licenses/CDDL-1.0. * 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 */ #include #include #include #include #include #include #include #include #include static void cleanup(char *file) { (void) remove(file); } int main(int argc, char *argv[]) { char *testdir = getenv("TESTDIR"); if (!testdir) { fprintf(stderr, "environment variable TESTDIR not set\n"); return (1); } struct stat st; umask(0); if (stat(testdir, &st) != 0 && mkdir(testdir, 0777) != 0) { perror("mkdir"); return (1); } if (argc > 3) { fprintf(stderr, "usage: %s " "[run time in mins] " "[max msync time in ms]\n", argv[0]); return (1); } int run_time_mins = 1; if (argc >= 2) { run_time_mins = atoi(argv[1]); } int max_msync_time_ms = 2000; if (argc >= 3) { max_msync_time_ms = atoi(argv[2]); } char filepath[512]; filepath[0] = '\0'; char *file = &filepath[0]; (void) snprintf(file, 512, "%s/msync_file", testdir); const int LEN = 8; cleanup(file); int fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd == -1) { (void) fprintf(stderr, "%s: %s: ", argv[0], file); perror("open"); return (1); } if (ftruncate(fd, LEN) != 0) { perror("ftruncate"); cleanup(file); return (1); } void *ptr = mmap(NULL, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap"); cleanup(file); return (1); } struct timeval tstart; gettimeofday(&tstart, NULL); long long x = 0LL; for (;;) { *((long long *)ptr) = x; x++; struct timeval t1, t2; gettimeofday(&t1, NULL); if (msync(ptr, LEN, MS_SYNC|MS_INVALIDATE) != 0) { perror("msync"); cleanup(file); return (1); } gettimeofday(&t2, NULL); double elapsed = (t2.tv_sec - t1.tv_sec) * 1000.0; elapsed += ((t2.tv_usec - t1.tv_usec) / 1000.0); if (elapsed > max_msync_time_ms) { fprintf(stderr, "slow msync: %f ms\n", elapsed); if (munmap(ptr, LEN) != 0) perror("munmap"); cleanup(file); return (1); } double elapsed_start = (t2.tv_sec - tstart.tv_sec) * 1000.0; elapsed_start += ((t2.tv_usec - tstart.tv_usec) / 1000.0); if (elapsed_start > run_time_mins * 60 * 1000) { break; } } if (munmap(ptr, LEN) != 0) { perror("munmap"); cleanup(file); return (1); } if (close(fd) != 0) { perror("close"); } cleanup(file); return (0); }