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

251 lines
5.6 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.9 $ $Author: jwag $"
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "getopt.h"
#include "fcntl.h"
#include "signal.h"
#include "malloc.h"
#include "errno.h"
#include "sys/wait.h"
#include "sys/types.h"
#include "sys/prctl.h"
#include "sys/mman.h"
#include "stress.h"
void slave2(void *);
void slave(void *);
char *Cmd;
char *pmaddr;
#define NBYTES (64*1024)
caddr_t
addrattach(pid_t pid, void *addr)
{
caddr_t vaddr;
if ((vaddr = (caddr_t)prctl(PR_ATTACHADDR, pid, addr)) == (caddr_t) -1L)
return(NULL);
return(vaddr);
}
/* ARGSUSED */
void
rtcatch(int sig, siginfo_t *si, void *unused)
{
if (sig != SIGRTMIN || si->si_code != SI_QUEUE) {
errprintf(ERR_EXIT, "invalid signal");
/* NOTREACHED */
}
pmaddr = si->si_value.sival_ptr;
}
int buf[100];
pid_t ppid;
char *maddr;
int
main(int argc, char **argv)
{
caddr_t newaddr, vaddr, caddr;
pid_t cpid, spid;
int c, fd, i;
int nbytes = NBYTES;
int private = 0;
struct sigaction sa;
Cmd = errinit(argv[0]);
while((c = getopt(argc, argv, "n:p")) != EOF)
switch (c) {
case 'n':
nbytes = atoi(optarg);
break;
case 'p':
private = 1;
break;
default:
fprintf(stderr, "Usage:addrattach [-n nbytes][-p]\n");
exit(-1);
}
ppid = getpid();
sa.sa_handler = rtcatch;
bzero(&sa.sa_mask, sizeof(sa.sa_mask));
sa.sa_flags = SA_SIGINFO;
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
errprintf(ERR_ERRNO_EXIT, "sigaction");
/* NOTREACHED */
}
prctl(PR_SETEXITSIG, SIGTERM);
if ((spid = sproc(slave, private ? 0 : PR_SALL, nbytes)) < 0) {
errprintf(ERR_ERRNO_EXIT, "sproc");
/* NOTREACHED */
}
blockproc(ppid);
/* attach in a portion on the slaves address space (it and our
* data space
*/
if ((vaddr = addrattach(spid, buf)) == NULL) {
errprintf(ERR_ERRNO_EXIT, "addrattach");
/* NOTREACHED */
}
/* slave has initialized maddr, sent us a signal and we have
* initialized pmaddr
* check memory via back door
*/
caddr = (pmaddr - (caddr_t)buf) + vaddr;
printf("parent checking starting at 0x%x (vaddr = 0x%x)\n",
caddr, vaddr);
for (i = 0; i < nbytes; i++)
if (*(pmaddr + i) != *(caddr + i)) {
errprintf(ERR_EXIT, "mismatch at 0x%x", caddr+i);
/* NOTREACHED */
}
if ((cpid = fork()) < 0) {
errprintf(ERR_ERRNO_EXIT, "fork");
/* NOTREACHED */
} else if (cpid != 0) {
/* parent */
blockproc(ppid);
/* shouldn't have changed! */
printf("parent checking starting at 0x%x (vaddr = 0x%x)\n",
caddr, vaddr);
for (i = 0; i < nbytes; i++)
if (*(pmaddr + i) != *(caddr + i)) {
errprintf(ERR_EXIT, "mismatch at 0x%x", caddr+i);
/* NOTREACHED */
}
} else {
/* child */
for (i = 0; i < nbytes; i++)
*(pmaddr + i) = (~i) & 0xff;
printf("child write %d bytes starting at 0x%x\n", nbytes, pmaddr);
unblockproc(ppid);
exit(0);
}
/*kill(cpid, SIGKILL);*/
prctl(PR_SETEXITSIG, 0);
kill(spid, SIGKILL);
while (wait(0) >= 0 || errno == EINTR)
;
/* now set up mmap region to see if sproc child gets own copy */
if ((fd = open("/dev/zero", O_RDWR)) < 0) {
errprintf(ERR_ERRNO_EXIT, "open of dev/zero");
/* NOTREACHED */
}
if ((newaddr = mmap(0, nbytes, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_LOCAL, fd, 0)) == (caddr_t) -1L) {
errprintf(ERR_ERRNO_EXIT, "mmap");
/* NOTREACHED */
}
maddr = newaddr; /* set for sproc child */
/* fill in parent copy */
printf("parent filling in at 0x%x\n", newaddr);
for (i = 0; i < nbytes; i++)
*(newaddr + i) = (~i) & 0xff;
/* spawn sproc child, should get own copy */
prctl(PR_SETEXITSIG, SIGTERM);
if ((spid = sproc(slave2, PR_SALL, nbytes)) < 0) {
errprintf(ERR_ERRNO_EXIT, "sproc");
/* NOTREACHED */
}
/* wait for it to init its area */
blockproc(ppid);
/* our area shouldn't have changed */
printf("Checking parents area not disturbed by child\n");
for (i = 0; i < nbytes; i++)
if (*(newaddr + i) != ((~i) & 0xff)) {
errprintf(ERR_EXIT, "mismatch at 0x%x", newaddr+i);
/* NOTREACHED */
}
/* remap childs area */
if ((vaddr = addrattach(spid, newaddr)) == NULL) {
errprintf(ERR_ERRNO_EXIT, "addrattach");
/* NOTREACHED */
}
/* check it to match what child put in */
printf("Checking childs area as remapped into parent @ 0x%x\n",
vaddr);
for (i = 0; i < nbytes; i++)
if (*(vaddr + i) != ((i) & 0xff)) {
errprintf(ERR_EXIT, "mismatch at 0x%x", vaddr+i);
/* NOTREACHED */
}
prctl(PR_SETEXITSIG, 0);
kill(spid, SIGKILL);
while (wait(0) >= 0 || errno == EINTR)
;
return 0;
}
void
slave(void *a)
{
int i;
int n = (int)(ptrdiff_t)a;
sigval_t sg;
/* malloc n bytes, and write pattern */
if ((maddr = malloc(n)) == NULL) {
perror("malloc");
exit(-1);
}
for (i = 0; i < n; i++)
*(maddr + i) = i & 0xff;
printf("slave write %d bytes starting at 0x%x\n", n, maddr);
/* send maddr to parent */
sg.sival_ptr = maddr;
sigqueue(ppid, SIGRTMIN, sg);
unblockproc(ppid);
for (;;)
pause();
}
void
slave2(void *a)
{
int i;
int n = (int)(ptrdiff_t)a;
for (i = 0; i < n; i++)
*(maddr + i) = i & 0xff;
printf("slave1 write %d bytes starting at 0x%x\n", n, maddr);
unblockproc(ppid);
for (;;)
pause();
}