/*-1* Copyright (c) 2006, Stephan Uphoff <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice unmodified, this list of conditions, and the following9* disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/252627#include <sys/types.h>28#include <unistd.h>29#include <sys/stat.h>30#include <fcntl.h>31#include <stdio.h>32#include <stdlib.h>33#include <sys/mman.h>343536int prepareFile(const char* filename,int* fdp);37int mapBuffer(char** bufferp,int fd1,int fd2);38int startIO(int fd,char *buffer);3940static int pagesize;4142#define FILESIZE (32*1024)43static char wbuffer[FILESIZE];4445/* Create a FILESIZE sized file - then remove file data from the cache*/46int prepareFile(const char* filename,int* fdp)47{48int fd;49int len;50int status;51void *addr;5253fd = open(filename,O_CREAT | O_TRUNC | O_RDWR,S_IRWXU);54if (fd == -1)55{56perror("Creating file");57return fd;58}5960len = write(fd,wbuffer,FILESIZE);61if (len < 0)62{63perror("Write failed");64return 1;65}6667status = fsync(fd);68if (status != 0)69{70perror("fsync failed");71return 1;72}7374addr = mmap(NULL,FILESIZE, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0);75if (addr == MAP_FAILED)76{77perror("Mmap failed");78return 1;79}8081status = msync(addr,FILESIZE,MS_INVALIDATE | MS_SYNC);82if (status != 0)83{84perror("Msync failed");85return 1;86}8788munmap(addr,FILESIZE);8990*fdp = fd;91return 0;92}939495/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */96int mapBuffer(char** bufferp,int fd1,int fd2)97{98void* addr;99char *buffer;100101addr = mmap(NULL,pagesize*2, PROT_READ | PROT_WRITE , MAP_SHARED, fd1, 0);102if (addr == MAP_FAILED)103{104perror("Mmap failed");105return 1;106}107108buffer = addr;109addr = mmap(buffer + pagesize,pagesize, PROT_READ | PROT_WRITE , MAP_FIXED |110MAP_SHARED, fd2, 0);111112if (addr == MAP_FAILED)113{114perror("Mmap2 failed");115return 1;116}117*bufferp = buffer;118return 0;119}120121122int startIO(int fd,char *buffer)123{124ssize_t len;125len = write(fd,buffer,2*pagesize);126if (len == -1)127{128perror("write failed");129return 1;130}131return 0;132}133134135int main(int argc __unused, char *argv[] __unused)136{137138int fdA,fdB,fdDelayA,fdDelayB;139int status;140char *bufferA,*bufferB;141pid_t pid;142143pagesize = getpagesize();144145if ((prepareFile("A",&fdA))146|| (prepareFile("B",&fdB))147|| (prepareFile("DelayA",&fdDelayA))148|| (prepareFile("DelayB",&fdDelayB))149|| (mapBuffer(&bufferA,fdDelayA,fdB))150|| (mapBuffer(&bufferB,fdDelayB,fdA)))151exit(1);152153pid = fork();154155if (pid == 0)156{157status = startIO(fdA,bufferA);158exit(status);159}160161if (pid == -1)162{163exit(1);164}165status = startIO(fdB,bufferB);166exit(status);167168}169170171172173174175176