1
0
Files
irix-657m-src/irix/cmd/stress/Mmap/agsync.c
2022-09-29 17:59:04 +03:00

369 lines
7.5 KiB
C

/**************************************************************************
* *
* Copyright (C) 1986, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "$Revision: 1.7 $ $Author: sfc $"
/**************************************************************************
msync0.c, used to test functionality of msync(), had following testing cases.
1. check msync() with 0 flag synchronize memory with mapped file.
2. check msync() with MS_INVALIDATE get memory to be invalidated.
3. check msync() with MS_ASYNC synchronize memory with mapped file after
return.
note : Since this test depends the timing of processes and I/O, it might
get different results for future kernels.
***************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/schedctl.h>
#include "stress.h"
#define DIV 32
#define BS (DIV<<5)
#define NB 20
caddr_t paddr;
char cstring[] = ":<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buf[BS];
char ops[8] = "ABCDEFG";
int nops;
int verbose;
pid_t cpid, ppid;
int fd;
char *filename;
char *Cmd;
void child(void *), bail(void);
int
main(int argc, char **argv)
{
int psize, i;
caddr_t p;
int c;
int errflg = 0;
Cmd = errinit(argv[0]);
filename = tempnam(NULL, "Tmags");
while ((c = getopt(argc, argv, "vf:")) != -1)
switch (c) {
case 'v':
verbose++;
break;
case 'f':
filename = optarg;
break;
case '?':
errflg++;
break;
}
if (errflg) {
fprintf(stderr, "Usage: agsync [-v][-f filename]\n");
exit(1);
}
if ((fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0666)) < 0) {
errprintf(ERR_ERRNO_EXIT, "open of %s failed", filename);
/* NOTREACHED */
}
p = mmap(0, BS*NB, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_AUTOGROW, fd, 0);
if (p == (caddr_t) -1L) {
errprintf(ERR_ERRNO_RET, "mmap autogrow failed");
bail();
}
for (i = 0; i < BS*NB; i++)
p[i] = cstring[i % DIV];
if (munmap(p, BS*NB) < 0) {
errprintf(ERR_ERRNO_RET, "munmap failed");
bail();
}
paddr = mmap(0, BS*NB, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (paddr == (caddr_t) -1L) {
errprintf(ERR_ERRNO_RET, "mmap failed");
bail();
}
if (lseek(fd, BS*(NB-1), 0) < 0) {
errprintf(ERR_ERRNO_RET, "lseek");
bail();
}
if (read(fd, buf, BS) != BS) {
errprintf(ERR_ERRNO_RET, "read1 tempfile failed");
bail();
}
for (i = 0; i < BS; i++)
if (buf[i] != cstring[i%DIV]) {
errprintf(ERR_RET, "tempfile is not synchronized\n");
bail();
}
ppid = getpid();
parentexinit(0);
if ((cpid = sproc(child, PR_SALL, 0)) < 0) {
if (errno != EAGAIN) {
errprintf(ERR_ERRNO_RET, "sproc failed i:%d", i);
bail();
} else {
fprintf(stderr, "%s:can't sproc:%s\n",
Cmd, strerror(errno));
unlink(filename);
exit(1);
}
}
/*
* NOPS == 1
*/
nops++;
for (i = 0; i < BS*NB; i++)
paddr[i] = ops[nops];
if (msync(paddr, BS*NB, MS_INVALIDATE) < 0) {
errprintf(ERR_ERRNO_RET, "msync MS_INVALIDATE failed");
bail();
}
/*
* NOPS == 2
*/
nops++;
if (lseek(fd, 0, 0) < 0) {
errprintf(ERR_ERRNO_RET, "parent lseek 0");
bail();
}
for (i = 0; i < BS; i++)
buf[i] = ops[nops];
for (i = 0; i < NB; i++)
if (write(fd, buf, BS) != BS) {
errprintf(ERR_ERRNO_RET, "write tempfile failed");
bail();
}
if (unblockproc(cpid)) {
errprintf(ERR_ERRNO_RET, "unblock child");
bail();
}
if (blockproc(ppid)) {
errprintf(ERR_ERRNO_RET, "block self (parent)");
bail();
}
/*
* NOPS == 3
*/
/* check that after msync(MS_INVALIDATE) read gets mmapped data */
if (lseek(fd, 0, 0) < 0) {
errprintf(ERR_ERRNO_RET, "parent lseek 1");
bail();
}
if (read(fd, buf, BS) != BS) {
errprintf(ERR_ERRNO_RET, "read2 tempfile failed");
bail();
}
for (i = 0; i < BS; i++)
if (buf[i] != ops[nops]) {
errprintf(ERR_RET, "did not read mmapped data after msync(INVAL)");
break;
}
if (i != BS) {
errprintf(ERR_RET, "buf[%d] is %x, ops[%d] is %x",
i, buf[i], nops, ops[nops]);
bail();
}
/*
* NOPS == 4
*/
nops++;
for (i = 0; i < BS; i++)
paddr[i] = ops[nops];
if (msync(paddr, BS*NB, 0) < 0) {
errprintf(ERR_ERRNO_RET, "msync failed");
bail();
}
if (unblockproc(cpid)) {
errprintf(ERR_ERRNO_RET, "parent unblock child");
bail();
}
if (blockproc(ppid)) {
errprintf(ERR_ERRNO_RET, "parent block self");
bail();
}
for (i = 0; i < BS; i++)
buf[i] = ops[0];
if (verbose)
printf("agsync:testing msync(MS_ASYNC) ");
for (;;) {
lseek(fd, BS*(NB-1), 0);
if (read(fd, buf, BS) != BS) {
errprintf(ERR_ERRNO_RET, "read tempfile failed");
bail();
}
for (i = 0; i < BS; i++)
if (buf[i] != ops[nops]) {
if (verbose)
printf("...");
}
if (i == BS) {
if (verbose)
printf("%d : succeed\n", nops);
break;
}
}
if (unblockproc(cpid)) {
errprintf(ERR_ERRNO_RET, "parent unblock child");
bail();
}
if (munmap(paddr, BS*NB) < 0) {
errprintf(ERR_ERRNO_RET, "munmap failed");
bail();
}
printf("%s:%d:PASSED\n", Cmd, getpid());
unlink(filename);
exit(0);
}
void
child(void *arg)
{
int i;
slaveexinit();
/*
* Since parent probably hasn't executed
* cpid = sproc(....) yet, can't access
* cpid and expect to find the actual id.
*/
if (blockproc(getpid())) {
errprintf(ERR_ERRNO_RET, "block self (child)");
bail();
}
/*
* NOPS == 2
*/
/* check results of msync with MS_INVALIDATE */
for (i = 0; i < BS*NB; i++)
if (paddr[i] != ops[nops]) {
errprintf(ERR_RET, "memory is not invalidated correctly");
break;
}
if (i == BS*NB) {
if (verbose)
printf("agsync:%d : succeed\n", nops);
} else {
errprintf(ERR_RET, "ops[%d] is %x, paddr[%d] is %x\n",
nops, ops[nops], i, paddr[i]);
bail();
}
/*
* NOPS == 3
*/
nops++;
for (i = 0; i < BS*NB; i++)
paddr[i] = ops[nops];
if (msync(paddr, BS*NB, MS_INVALIDATE) < 0) {
errprintf(ERR_ERRNO_RET, "msync MS_INVALIDATE failed");
bail();
}
if (unblockproc(ppid)) {
errprintf(ERR_ERRNO_RET, "unblock parent (child)");
bail();
}
if (blockproc(getpid())) {
errprintf(ERR_ERRNO_RET, "block self (child)");
bail();
}
/*
* NOPS == 4
*/
/* check results of msync without MS_INVALIDATE */
lseek(fd, 0, 0);
if (read(fd, buf, BS) != BS) {
errprintf(ERR_ERRNO_RET, "slave read2 tempfile failed");
bail();
}
for (i = 0; i < BS; i++)
if (buf[i] != ops[nops]) {
errprintf(ERR_RET, "read incorrect data after msync(..0)");
break;
}
if (i == BS) {
if (verbose)
printf("agsync:%d : succeed\n", nops);
} else {
errprintf(ERR_RET, "buf[%d] is %x, ops[%d] is %x",
i, buf[i], nops, ops[nops]);
bail();
}
/*
* NOPS == 5
*/
nops++;
for (i = 0; i < BS*NB; i++)
paddr[i] = ops[nops];
if (msync(paddr, BS*NB, MS_ASYNC) < 0) {
errprintf(ERR_ERRNO_RET, "msync MS_INVALIDATE failed");
bail();
}
if (unblockproc(ppid)) {
errprintf(ERR_ERRNO_RET, "unblock parent (child)");
bail();
}
if (blockproc(getpid())) {
errprintf(ERR_ERRNO_RET, "block self (child)");
bail();
}
exit(0);
}
void
bail(void)
{
unlink(filename);
abort();
}