4 # Copyright (c) 2009 Peter Holm <pho@FreeBSD.org>
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # Threaded variation of datamove.sh
33 # Based on a test scenario by ups and suggestions by kib
35 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
39 sed '1,/^EOF/d' < $here/$0 > dl.c
40 cc -o dl -Wall dl.c -lpthread
44 old=`sysctl vm.old_msync | awk '{print $NF}'`
47 mkdir -p /tmp/dl.dir.$i
58 sysctl vm.old_msync=$old
72 #include <sys/types.h>
81 int prepareFile(char *, int *);
82 void * mapBuffer(void *);
83 int startIO(int, char *);
87 #define FILESIZE (32*1024)
88 char wbuffer [FILESIZE];
90 /* Create a FILESIZE sized file - then remove file data from the cache */
92 prepareFile(char *filename, int *fdp)
99 fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
101 perror("Creating file");
104 len = write(fd, wbuffer, FILESIZE);
106 perror("Write failed");
111 perror("fsync failed");
114 addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
115 if (addr == MAP_FAILED) {
116 perror("Mmap failed");
119 status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC);
121 perror("Msync failed");
124 munmap(addr, FILESIZE);
131 /* mmap a 2 page buffer - first page is from fd1, second page from fd2 */
140 addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, a[i].fd1, 0);
141 if (addr == MAP_FAILED) {
142 err(1, "Mmap failed");
145 addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED |
146 MAP_SHARED, a[i].fd2, 0);
148 if (addr == MAP_FAILED) {
149 err(1, "Mmap2 failed");
158 startIO(int fd, char *buffer)
162 len = write(fd, buffer, 2 * pagesize);
164 warn("startIO(%d, %p): write failed", fd, buffer);
173 main(int argc, char *argv[], char *envp[])
176 int fdA, fdB, fdDelayA, fdDelayB;
178 char *bufferA, *bufferB;
180 pthread_t threads[2];
182 pagesize = getpagesize();
184 if ((prepareFile("A", &fdA))
185 || (prepareFile("B", &fdB))
186 || (prepareFile("DelayA", &fdDelayA))
187 || (prepareFile("DelayB", &fdDelayB)))
196 if ((r = pthread_create(&threads[0], NULL, mapBuffer, (void *)0)) != 0)
197 err(1, "pthread_create(): %s\n", strerror(r));
198 if ((r = pthread_create(&threads[1], NULL, mapBuffer, (void *)1)) != 0)
199 err(1, "pthread_create(): %s\n", strerror(r));
201 while (a[0].bp == NULL || a[1].bp == NULL)
210 status = startIO(fdA, bufferA);
216 status = startIO(fdB, bufferB);