diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-01-04 18:54:17 +0100 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-01-04 18:54:17 +0100 |
commit | 0f6ead3914b5436785469e770a14fff753723f06 (patch) | |
tree | 42b2daea7753c15652f54523bd553d0356fdbb13 | |
parent | b0ec131ac68b16e35c7112c9ea686b608fb8983f (diff) | |
download | flashbench-0f6ead3914b5436785469e770a14fff753723f06.tar.gz |
flashbench: implement write opcodes in vm
This makes it possible to use three kinds of
write operations, writing zero-, one- or
somwhat random contents. Many media have different
characteristics depending on the kind of content.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | dev.c | 43 | ||||
-rw-r--r-- | vm.c | 28 |
2 files changed, 55 insertions, 16 deletions
@@ -19,6 +19,8 @@ #include "dev.h" +#define MAX_BUFSIZE (64 * 1024 * 1024) + static inline long long time_to_ns(struct timespec *ts) { return ts->tv_sec * 1000 * 1000 * 1000 + ts->tv_nsec; @@ -33,46 +35,49 @@ static long long get_ns(void) long long time_read(struct device *dev, off_t pos, size_t size) { - static char readbuf[64 * 1024 * 1024] __attribute__((aligned(4096))); long long now = get_ns(); ssize_t ret; - if (size > sizeof(readbuf)) + if (size > MAX_BUFSIZE) return -ENOMEM; do { - ret = pread(dev->fd, readbuf, size, pos % dev->size); + ret = pread(dev->fd, dev->readbuf, size, pos % dev->size); if (ret > 0) { size -= ret; pos += ret; } } while (ret > 0 || errno == -EAGAIN); - if (ret) - return -errno; + if (ret) { + fprintf(stderr, "fd %d buf %p size %ld pos %ld\n", dev->fd, dev->readbuf, size, pos % dev->size); + perror("time_read"); + return 0; + } return get_ns() - now; } long long time_write(struct device *dev, off_t pos, size_t size, enum writebuf which) { - static char writebuf[64 * 1024 * 1024] __attribute__((aligned(4096))); long long now = get_ns(); ssize_t ret; - if (size > sizeof(writebuf)) + if (size > MAX_BUFSIZE) return -ENOMEM; do { - ret = pwrite(dev->fd, writebuf, size, pos % dev->size); + ret = pwrite(dev->fd, dev->writebuf[which], size, pos % dev->size); if (ret > 0) { size -= ret; pos += ret; } } while (ret > 0 || errno == -EAGAIN); - if (ret) - return -errno; + if (ret) { + perror("time_write"); + return 0; + } return get_ns() - now; } @@ -91,6 +96,7 @@ static void set_rtprio(void) int setup_dev(struct device *dev, const char *filename) { + int i, err; set_rtprio(); dev->fd = open(filename, O_RDWR | O_DIRECT | O_SYNC | O_NOATIME); @@ -105,8 +111,19 @@ int setup_dev(struct device *dev, const char *filename) return -errno; } - return 0; -} - + err = posix_memalign(&dev->readbuf, 4096, MAX_BUFSIZE); + if (err) return -err; + err = posix_memalign(&dev->writebuf[WBUF_ZERO], 4096, MAX_BUFSIZE); + if (err) return -err; + err = posix_memalign(&dev->writebuf[WBUF_ONE], 4096, MAX_BUFSIZE); + if (err) return -err; + err = posix_memalign(&dev->writebuf[WBUF_RAND], 4096, MAX_BUFSIZE); + if (err) return -err; + memset(dev->writebuf[WBUF_ZERO], 0, MAX_BUFSIZE); + memset(dev->writebuf[WBUF_ONE], 0xff, MAX_BUFSIZE); + for (i = 0; i < MAX_BUFSIZE; i+=256) + memset(dev->writebuf[WBUF_RAND] + i, (i & 0xff), 256); + return 0; +} @@ -168,6 +168,28 @@ static struct operation *do_read(struct operation *op, struct device *dev, return op+1; } +static struct operation *do_write(struct operation *op, struct device *dev, + off_t off, off_t max, size_t len) +{ + enum writebuf writebuf; + switch (op->code) { + case O_WRITE_ZERO: + writebuf = WBUF_ZERO; + break; + case O_WRITE_ONE: + writebuf = WBUF_ONE; + break; + case O_WRITE_RAND: + writebuf = WBUF_RAND; + break; + default: + return NULL; + } + op->result.l = time_write(dev, off, len, writebuf); + op->r_type = R_NS; + return op+1; +} + static struct operation *length_or_offs(struct operation *op, struct device *dev, off_t off, off_t max, size_t len) { @@ -482,9 +504,9 @@ static struct operation *drop(struct operation *op, struct device *dev, static struct syntax syntax[] = { { O_END, "END", nop, }, { O_READ, "READ", do_read, }, - { O_WRITE_ZERO, "WRITE_ZERO", nop, }, - { O_WRITE_ONE, "WRITE_ONE", nop, }, - { O_WRITE_RAND, "WRITE_RAND", nop, }, + { O_WRITE_ZERO, "WRITE_ZERO", do_write, }, + { O_WRITE_ONE, "WRITE_ONE", do_write, }, + { O_WRITE_RAND, "WRITE_RAND", do_write, }, { O_ERASE, "ERASE", nop, }, { O_LENGTH, "LENGTH", length_or_offs }, { O_OFFSET, "OFFSET", length_or_offs, }, |