summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/arch.c5
-rw-r--r--t/axmap.c142
-rw-r--r--t/btrace2fio.c1144
-rw-r--r--t/debug.c14
-rw-r--r--t/debug.h6
-rw-r--r--t/dedupe.c600
-rw-r--r--t/gen-rand.c68
-rw-r--r--t/genzipf.c350
-rw-r--r--t/ieee754.c21
-rw-r--r--t/jobs/t0001-52c58027.fio6
-rw-r--r--t/jobs/t0002-13af05ae-post24
-rw-r--r--t/jobs/t0002-13af05ae-pre23
-rw-r--r--t/jobs/t0003-0ae2c6e1-post.fio26
-rw-r--r--t/jobs/t0003-0ae2c6e1-pre.fio22
-rw-r--r--t/jobs/t0004-8a99fdf6.fio27
-rw-r--r--t/jobs/t0005-f7078f7b.fio13
-rw-r--r--t/jobs/t0006-82af2a7c.fio16
-rw-r--r--t/jobs/t0007-37cf9e3c.fio10
-rw-r--r--t/jobs/t0008-ae2fafc8.fio12
-rw-r--r--t/jobs/t0009-f8b0bd10.fio40
-rw-r--r--t/lfsr-test.c133
-rw-r--r--t/log.c31
-rw-r--r--t/memlock.c58
-rw-r--r--t/read-to-pipe-async.c670
-rw-r--r--t/stest.c72
-rw-r--r--t/verify-state.c154
26 files changed, 0 insertions, 3687 deletions
diff --git a/t/arch.c b/t/arch.c
deleted file mode 100644
index befb7c7f..00000000
--- a/t/arch.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "../arch/arch.h"
-
-unsigned long arch_flags = 0;
-int tsc_reliable;
-int arch_random;
diff --git a/t/axmap.c b/t/axmap.c
deleted file mode 100644
index e32ff98d..00000000
--- a/t/axmap.c
+++ /dev/null
@@ -1,142 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "../lib/lfsr.h"
-#include "../lib/axmap.h"
-
-void *smalloc(size_t size)
-{
- return malloc(size);
-}
-
-void sfree(void *ptr)
-{
- free(ptr);
-}
-
-static int test_regular(size_t size, int seed)
-{
- struct fio_lfsr lfsr;
- struct axmap *map;
- size_t osize;
- uint64_t ff;
- int err;
-
- printf("Using %llu entries...", (unsigned long long) size);
- fflush(stdout);
-
- lfsr_init(&lfsr, size, seed, seed & 0xF);
- map = axmap_new(size);
- osize = size;
- err = 0;
-
- while (size--) {
- uint64_t val;
-
- if (lfsr_next(&lfsr, &val)) {
- printf("lfsr: short loop\n");
- err = 1;
- break;
- }
- if (axmap_isset(map, val)) {
- printf("bit already set\n");
- err = 1;
- break;
- }
- axmap_set(map, val);
- if (!axmap_isset(map, val)) {
- printf("bit not set\n");
- err = 1;
- break;
- }
- }
-
- if (err)
- return err;
-
- ff = axmap_next_free(map, osize);
- if (ff != (uint64_t) -1ULL) {
- printf("axmap_next_free broken: got %llu\n", (unsigned long long) ff);
- return 1;
- }
-
- printf("pass!\n");
- axmap_free(map);
- return 0;
-}
-
-static int test_multi(size_t size, unsigned int bit_off)
-{
- unsigned int map_size = size;
- struct axmap *map;
- uint64_t val = bit_off;
- int i, err;
-
- printf("Test multi %llu entries %u offset...", (unsigned long long) size, bit_off);
- fflush(stdout);
-
- map = axmap_new(map_size);
- while (val + 128 <= map_size) {
- err = 0;
- for (i = val; i < val + 128; i++) {
- if (axmap_isset(map, val + i)) {
- printf("bit already set\n");
- err = 1;
- break;
- }
- }
-
- if (err)
- break;
-
- err = axmap_set_nr(map, val, 128);
- if (err != 128) {
- printf("only set %u bits\n", err);
- break;
- }
-
- err = 0;
- for (i = 0; i < 128; i++) {
- if (!axmap_isset(map, val + i)) {
- printf("bit not set: %llu\n", (unsigned long long) val + i);
- err = 1;
- break;
- }
- }
-
- val += 128;
- if (err)
- break;
- }
-
- if (!err)
- printf("pass!\n");
-
- axmap_free(map);
- return err;
-}
-
-int main(int argc, char *argv[])
-{
- size_t size = (1UL << 23) - 200;
- int seed = 1;
-
- if (argc > 1) {
- size = strtoul(argv[1], NULL, 10);
- if (argc > 2)
- seed = strtoul(argv[2], NULL, 10);
- }
-
- if (test_regular(size, seed))
- return 1;
- if (test_multi(size, 0))
- return 2;
- if (test_multi(size, 17))
- return 3;
-
- return 0;
-}
diff --git a/t/btrace2fio.c b/t/btrace2fio.c
deleted file mode 100644
index 4cdb38d1..00000000
--- a/t/btrace2fio.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-#include <stdio.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <math.h>
-#include <assert.h>
-
-#include "../io_ddir.h"
-#include "../flist.h"
-#include "../hash.h"
-#include "../fifo.h"
-#include "../blktrace_api.h"
-#include "../os/os.h"
-#include "../log.h"
-#include "../oslib/linux-dev-lookup.h"
-
-#define TRACE_FIFO_SIZE 8192
-
-static unsigned int rt_threshold = 1000000;
-static unsigned int ios_threshold = 10;
-static unsigned int rate_threshold;
-static unsigned int set_rate;
-static unsigned int max_depth = 256;
-static int output_ascii = 1;
-static char *filename;
-
-static char **add_opts;
-static int n_add_opts;
-
-/*
- * Collapse defaults
- */
-static unsigned int collapse_entries = 0;
-static unsigned int depth_diff = 1;
-static unsigned int random_diff = 5;
-
-struct bs {
- unsigned int bs;
- unsigned int nr;
- int merges;
-};
-
-struct trace_file {
- char *name;
- int major, minor;
-};
-
-struct btrace_out {
- unsigned long ios[DDIR_RWDIR_CNT];
- unsigned long merges[DDIR_RWDIR_CNT];
-
- uint64_t last_end[DDIR_RWDIR_CNT];
- uint64_t seq[DDIR_RWDIR_CNT];
-
- struct bs *bs[DDIR_RWDIR_CNT];
- unsigned int nr_bs[DDIR_RWDIR_CNT];
-
- int inflight;
- unsigned int depth;
- int depth_disabled;
- int complete_seen;
-
- uint64_t first_ttime[DDIR_RWDIR_CNT];
- uint64_t last_ttime[DDIR_RWDIR_CNT];
- uint64_t kib[DDIR_RWDIR_CNT];
-
- uint64_t start_delay;
-};
-
-struct btrace_pid {
- struct flist_head hash_list;
- struct flist_head pid_list;
- pid_t pid;
-
- pid_t *merge_pids;
- unsigned int nr_merge_pids;
-
- struct trace_file *files;
- int nr_files;
- unsigned int last_major, last_minor;
- int numjobs;
- int ignore;
-
- struct btrace_out o;
-};
-
-struct inflight {
- struct flist_head list;
- struct btrace_pid *p;
- uint64_t end_sector;
-};
-
-#define PID_HASH_BITS 10
-#define PID_HASH_SIZE (1U << PID_HASH_BITS)
-
-static struct flist_head pid_hash[PID_HASH_SIZE];
-static FLIST_HEAD(pid_list);
-
-#define INFLIGHT_HASH_BITS 8
-#define INFLIGHT_HASH_SIZE (1U << INFLIGHT_HASH_BITS)
-static struct flist_head inflight_hash[INFLIGHT_HASH_SIZE];
-
-static uint64_t first_ttime = -1ULL;
-
-static struct inflight *inflight_find(uint64_t sector)
-{
- struct flist_head *inflight_list;
- struct flist_head *e;
-
- inflight_list = &inflight_hash[hash_long(sector, INFLIGHT_HASH_BITS)];
-
- flist_for_each(e, inflight_list) {
- struct inflight *i = flist_entry(e, struct inflight, list);
-
- if (i->end_sector == sector)
- return i;
- }
-
- return NULL;
-}
-
-static void inflight_remove(struct inflight *i)
-{
- struct btrace_out *o = &i->p->o;
-
- o->inflight--;
- assert(o->inflight >= 0);
- flist_del(&i->list);
- free(i);
-}
-
-static void __inflight_add(struct inflight *i)
-{
- struct flist_head *list;
-
- list = &inflight_hash[hash_long(i->end_sector, INFLIGHT_HASH_BITS)];
- flist_add_tail(&i->list, list);
-}
-
-static void inflight_add(struct btrace_pid *p, uint64_t sector, uint32_t len)
-{
- struct btrace_out *o = &p->o;
- struct inflight *i;
-
- i = calloc(1, sizeof(*i));
- i->p = p;
- o->inflight++;
- if (!o->depth_disabled) {
- o->depth = max((int) o->depth, o->inflight);
- if (o->depth >= max_depth && !o->complete_seen) {
- o->depth_disabled = 1;
- o->depth = max_depth;
- }
- }
- i->end_sector = sector + (len >> 9);
- __inflight_add(i);
-}
-
-static void inflight_merge(struct inflight *i, int rw, unsigned int size)
-{
- i->p->o.merges[rw]++;
- if (size) {
- i->end_sector += (size >> 9);
- flist_del(&i->list);
- __inflight_add(i);
- }
-}
-
-/*
- * fifo refill frontend, to avoid reading data in trace sized bites
- */
-static int refill_fifo(struct fifo *fifo, int fd)
-{
- char buf[TRACE_FIFO_SIZE];
- unsigned int total;
- int ret;
-
- total = sizeof(buf);
- if (total > fifo_room(fifo))
- total = fifo_room(fifo);
-
- ret = read(fd, buf, total);
- if (ret < 0) {
- perror("read refill");
- return -1;
- }
-
- if (ret > 0)
- ret = fifo_put(fifo, buf, ret);
-
- return ret;
-}
-
-/*
- * Retrieve 'len' bytes from the fifo, refilling if necessary.
- */
-static int trace_fifo_get(struct fifo *fifo, int fd, void *buf,
- unsigned int len)
-{
- if (fifo_len(fifo) < len) {
- int ret = refill_fifo(fifo, fd);
-
- if (ret < 0)
- return ret;
- }
-
- return fifo_get(fifo, buf, len);
-}
-
-/*
- * Just discard the pdu by seeking past it.
- */
-static int discard_pdu(struct fifo *fifo, int fd, struct blk_io_trace *t)
-{
- if (t->pdu_len == 0)
- return 0;
-
- return trace_fifo_get(fifo, fd, NULL, t->pdu_len);
-}
-
-static int handle_trace_notify(struct blk_io_trace *t)
-{
- switch (t->action) {
- case BLK_TN_PROCESS:
- //printf("got process notify: %x, %d\n", t->action, t->pid);
- break;
- case BLK_TN_TIMESTAMP:
- //printf("got timestamp notify: %x, %d\n", t->action, t->pid);
- break;
- case BLK_TN_MESSAGE:
- break;
- default:
- log_err("unknown trace act %x\n", t->action);
- return 1;
- }
-
- return 0;
-}
-
-static void __add_bs(struct btrace_out *o, unsigned int len, int rw)
-{
- o->bs[rw] = realloc(o->bs[rw], (o->nr_bs[rw] + 1) * sizeof(struct bs));
- o->bs[rw][o->nr_bs[rw]].bs = len;
- o->bs[rw][o->nr_bs[rw]].nr = 1;
- o->nr_bs[rw]++;
-}
-
-static void add_bs(struct btrace_out *o, unsigned int len, int rw)
-{
- struct bs *bs = o->bs[rw];
- int i;
-
- if (!o->nr_bs[rw]) {
- __add_bs(o, len, rw);
- return;
- }
-
- for (i = 0; i < o->nr_bs[rw]; i++) {
- if (bs[i].bs == len) {
- bs[i].nr++;
- return;
- }
- }
-
- __add_bs(o, len, rw);
-}
-
-#define FMINORBITS 20
-#define FMINORMASK ((1U << FMINORBITS) - 1)
-#define FMAJOR(dev) ((unsigned int) ((dev) >> FMINORBITS))
-#define FMINOR(dev) ((unsigned int) ((dev) & FMINORMASK))
-
-static int btrace_add_file(struct btrace_pid *p, uint32_t devno)
-{
- unsigned int maj = FMAJOR(devno);
- unsigned int min = FMINOR(devno);
- struct trace_file *f;
- unsigned int i;
- char dev[256];
-
- if (filename)
- return 0;
- if (p->last_major == maj && p->last_minor == min)
- return 0;
-
- p->last_major = maj;
- p->last_minor = min;
-
- /*
- * check for this file in our list
- */
- for (i = 0; i < p->nr_files; i++) {
- f = &p->files[i];
-
- if (f->major == maj && f->minor == min)
- return 0;
- }
-
- strcpy(dev, "/dev");
- if (!blktrace_lookup_device(NULL, dev, maj, min)) {
- log_err("fio: failed to find device %u/%u\n", maj, min);
- if (!output_ascii) {
- log_err("fio: use -d to specify device\n");
- return 1;
- }
- return 0;
- }
-
- p->files = realloc(p->files, (p->nr_files + 1) * sizeof(*f));
- f = &p->files[p->nr_files];
- f->name = strdup(dev);
- f->major = maj;
- f->minor = min;
- p->nr_files++;
- return 0;
-}
-
-static int t_to_rwdir(struct blk_io_trace *t)
-{
- if (t->action & BLK_TC_ACT(BLK_TC_DISCARD))
- return DDIR_TRIM;
-
- return (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
-}
-
-static int handle_trace_discard(struct blk_io_trace *t, struct btrace_pid *p)
-{
- struct btrace_out *o = &p->o;
-
- if (btrace_add_file(p, t->device))
- return 1;
-
- if (o->first_ttime[2] == -1ULL)
- o->first_ttime[2] = t->time;
-
- o->ios[DDIR_TRIM]++;
- add_bs(o, t->bytes, DDIR_TRIM);
- return 0;
-}
-
-static int handle_trace_fs(struct blk_io_trace *t, struct btrace_pid *p)
-{
- struct btrace_out *o = &p->o;
- int rw;
-
- if (btrace_add_file(p, t->device))
- return 1;
-
- first_ttime = min(first_ttime, (uint64_t) t->time);
-
- rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
-
- if (o->first_ttime[rw] == -1ULL)
- o->first_ttime[rw] = t->time;
-
- add_bs(o, t->bytes, rw);
- o->ios[rw]++;
-
- if (t->sector == o->last_end[rw] || o->last_end[rw] == -1ULL)
- o->seq[rw]++;
-
- o->last_end[rw] = t->sector + (t->bytes >> 9);
- return 0;
-}
-
-static int handle_queue_trace(struct blk_io_trace *t, struct btrace_pid *p)
-{
- if (t->action & BLK_TC_ACT(BLK_TC_NOTIFY))
- return handle_trace_notify(t);
- else if (t->action & BLK_TC_ACT(BLK_TC_DISCARD))
- return handle_trace_discard(t, p);
- else
- return handle_trace_fs(t, p);
-}
-
-static int handle_trace(struct blk_io_trace *t, struct btrace_pid *p)
-{
- unsigned int act = t->action & 0xffff;
- int ret = 0;
-
- if (act == __BLK_TA_QUEUE) {
- inflight_add(p, t->sector, t->bytes);
- ret = handle_queue_trace(t, p);
- } else if (act == __BLK_TA_BACKMERGE) {
- struct inflight *i;
-
- i = inflight_find(t->sector + (t->bytes >> 9));
- if (i)
- inflight_remove(i);
-
- i = inflight_find(t->sector);
- if (i)
- inflight_merge(i, t_to_rwdir(t), t->bytes);
- } else if (act == __BLK_TA_FRONTMERGE) {
- struct inflight *i;
-
- i = inflight_find(t->sector + (t->bytes >> 9));
- if (i)
- inflight_remove(i);
-
- i = inflight_find(t->sector);
- if (i)
- inflight_merge(i, t_to_rwdir(t), 0);
- } else if (act == __BLK_TA_COMPLETE) {
- struct inflight *i;
-
- i = inflight_find(t->sector + (t->bytes >> 9));
- if (i) {
- i->p->o.kib[t_to_rwdir(t)] += (t->bytes >> 10);
- i->p->o.complete_seen = 1;
- inflight_remove(i);
- }
- }
-
- return ret;
-}
-
-static void byteswap_trace(struct blk_io_trace *t)
-{
- t->magic = fio_swap32(t->magic);
- t->sequence = fio_swap32(t->sequence);
- t->time = fio_swap64(t->time);
- t->sector = fio_swap64(t->sector);
- t->bytes = fio_swap32(t->bytes);
- t->action = fio_swap32(t->action);
- t->pid = fio_swap32(t->pid);
- t->device = fio_swap32(t->device);
- t->cpu = fio_swap32(t->cpu);
- t->error = fio_swap16(t->error);
- t->pdu_len = fio_swap16(t->pdu_len);
-}
-
-static struct btrace_pid *pid_hash_find(pid_t pid, struct flist_head *list)
-{
- struct flist_head *e;
- struct btrace_pid *p;
-
- flist_for_each(e, list) {
- p = flist_entry(e, struct btrace_pid, hash_list);
- if (p->pid == pid)
- return p;
- }
-
- return NULL;
-}
-
-static struct btrace_pid *pid_hash_get(pid_t pid)
-{
- struct flist_head *hash_list;
- struct btrace_pid *p;
-
- hash_list = &pid_hash[hash_long(pid, PID_HASH_BITS)];
-
- p = pid_hash_find(pid, hash_list);
- if (!p) {
- int i;
-
- p = calloc(1, sizeof(*p));
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- p->o.first_ttime[i] = -1ULL;
- p->o.last_ttime[i] = -1ULL;
- p->o.last_end[i] = -1ULL;
- }
-
- p->pid = pid;
- p->numjobs = 1;
- flist_add_tail(&p->hash_list, hash_list);
- flist_add_tail(&p->pid_list, &pid_list);
- }
-
- return p;
-}
-
-/*
- * Load a blktrace file by reading all the blk_io_trace entries, and storing
- * them as io_pieces like the fio text version would do.
- */
-static int load_blktrace(const char *fname, int need_swap)
-{
- struct btrace_pid *p;
- unsigned long traces;
- struct blk_io_trace t;
- struct fifo *fifo;
- int fd, ret = 0;
-
- fd = open(fname, O_RDONLY);
- if (fd < 0) {
- perror("open trace file\n");
- return 1;
- }
-
- fifo = fifo_alloc(TRACE_FIFO_SIZE);
-
- traces = 0;
- do {
- ret = trace_fifo_get(fifo, fd, &t, sizeof(t));
- if (ret < 0)
- goto err;
- else if (!ret)
- break;
- else if (ret < (int) sizeof(t)) {
- log_err("fio: short fifo get\n");
- break;
- }
-
- if (need_swap)
- byteswap_trace(&t);
-
- if ((t.magic & 0xffffff00) != BLK_IO_TRACE_MAGIC) {
- log_err("fio: bad magic in blktrace data: %x\n", t.magic);
- goto err;
- }
- if ((t.magic & 0xff) != BLK_IO_TRACE_VERSION) {
- log_err("fio: bad blktrace version %d\n", t.magic & 0xff);
- goto err;
- }
- ret = discard_pdu(fifo, fd, &t);
- if (ret < 0) {
- log_err("blktrace lseek\n");
- goto err;
- } else if (t.pdu_len != ret) {
- log_err("fio: discarded %d of %d\n", ret, t.pdu_len);
- goto err;
- }
-
- p = pid_hash_get(t.pid);
- ret = handle_trace(&t, p);
- if (ret)
- break;
- p->o.last_ttime[t_to_rwdir(&t)] = t.time;
- traces++;
- } while (1);
-
- fifo_free(fifo);
- close(fd);
-
- if (ret)
- return ret;
-
- if (output_ascii)
- printf("Traces loaded: %lu\n", traces);
-
- return 0;
-err:
- close(fd);
- fifo_free(fifo);
- return 1;
-}
-
-static int bs_cmp(const void *ba, const void *bb)
-{
- const struct bs *bsa = ba;
- const struct bs *bsb = bb;
-
- return bsb->nr - bsa->nr;
-}
-
-static unsigned long o_to_kib_rate(struct btrace_out *o, int rw)
-{
- uint64_t usec = (o->last_ttime[rw] - o->first_ttime[rw]) / 1000ULL;
- uint64_t val;
-
- if (!usec)
- return 0;
-
- usec /= 1000;
- if (!usec)
- return 0;
-
- val = o->kib[rw] * 1000ULL;
- return val / usec;
-}
-
-static uint64_t o_first_ttime(struct btrace_out *o)
-{
- uint64_t first;
-
- first = min(o->first_ttime[0], o->first_ttime[1]);
- return min(first, o->first_ttime[2]);
-}
-
-static uint64_t o_longest_ttime(struct btrace_out *o)
-{
- uint64_t ret = 0;
- int i;
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- uint64_t diff;
-
- diff = o->last_ttime[i] - o->first_ttime[i];
- ret = max(diff, ret);
- }
-
- return ret;
-}
-
-static void __output_p_ascii(struct btrace_pid *p, unsigned long *ios)
-{
- const char *msg[] = { "reads", "writes", "trims" };
- struct btrace_out *o = &p->o;
- unsigned long total, usec;
- int i, j;
-
- printf("[pid:\t%u", p->pid);
- if (p->nr_merge_pids)
- for (i = 0; i < p->nr_merge_pids; i++)
- printf(", %u", p->merge_pids[i]);
- printf("]\n");
-
- total = ddir_rw_sum(o->ios);
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- float perc;
-
- if (!o->ios[i])
- continue;
-
- ios[i] += o->ios[i] + o->merges[i];
- printf("%s\n", msg[i]);
- perc = ((float) o->ios[i] * 100.0) / (float) total;
- printf("\tios: %lu (perc=%3.2f%%)\n", o->ios[i], perc);
- perc = ((float) o->merges[i] * 100.0) / (float) total;
- printf("\tmerges: %lu (perc=%3.2f%%)\n", o->merges[i], perc);
- perc = ((float) o->seq[i] * 100.0) / (float) o->ios[i];
- printf("\tseq: %lu (perc=%3.2f%%)\n", (unsigned long) o->seq[i], perc);
- printf("\trate: %lu KiB/sec\n", o_to_kib_rate(o, i));
-
- for (j = 0; j < o->nr_bs[i]; j++) {
- struct bs *bs = &o->bs[i][j];
-
- perc = (((float) bs->nr * 100.0) / (float) o->ios[i]);
- printf("\tbs=%u, perc=%3.2f%%\n", bs->bs, perc);
- }
- }
-
- printf("depth:\t%u\n", o->depth);
- usec = o_longest_ttime(o) / 1000ULL;
- printf("usec:\t%lu (delay=%llu)\n", usec, (unsigned long long) o->start_delay);
-
- printf("files:\t");
- for (i = 0; i < p->nr_files; i++)
- printf("%s,", p->files[i].name);
- printf("\n");
-
- printf("\n");
-}
-
-static int __output_p_fio(struct btrace_pid *p, unsigned long *ios)
-{
- struct btrace_out *o = &p->o;
- unsigned long total;
- unsigned long long time;
- float perc;
- int i, j;
-
- if ((o->ios[0] + o->ios[1]) && o->ios[2]) {
- log_err("fio: trace has both read/write and trim\n");
- return 1;
- }
- if (!p->nr_files) {
- log_err("fio: no devices found\n");
- return 1;
- }
-
- printf("[pid%u", p->pid);
- if (p->nr_merge_pids)
- for (i = 0; i < p->nr_merge_pids; i++)
- printf(",pid%u", p->merge_pids[i]);
- printf("]\n");
-
- printf("numjobs=%u\n", p->numjobs);
- printf("direct=1\n");
- if (o->depth == 1)
- printf("ioengine=sync\n");
- else
- printf("ioengine=libaio\niodepth=%u\n", o->depth);
-
- if (o->ios[0] && !o->ios[1])
- printf("rw=randread\n");
- else if (!o->ios[0] && o->ios[1])
- printf("rw=randwrite\n");
- else if (o->ios[2])
- printf("rw=randtrim\n");
- else {
- printf("rw=randrw\n");
- total = ddir_rw_sum(o->ios);
- perc = ((float) o->ios[0] * 100.0) / (float) total;
- printf("rwmixread=%u\n", (int) floor(perc + 0.50));
- }
-
- printf("percentage_random=");
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- if (o->seq[i] && o->ios[i]) {
- perc = ((float) o->seq[i] * 100.0) / (float) o->ios[i];
- if (perc >= 99.0)
- perc = 100.0;
- } else
- perc = 100.0;
-
- if (i)
- printf(",");
- perc = 100.0 - perc;
- printf("%u", (int) floor(perc + 0.5));
- }
- printf("\n");
-
- printf("filename=");
- for (i = 0; i < p->nr_files; i++) {
- if (i)
- printf(":");
- printf("%s", p->files[i].name);
- }
- printf("\n");
-
- if (o->start_delay / 1000000ULL)
- printf("startdelay=%llus\n", o->start_delay / 1000000ULL);
-
- time = o_longest_ttime(o);
- time = (time + 1000000000ULL - 1) / 1000000000ULL;
- printf("runtime=%llus\n", time);
-
- printf("bssplit=");
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
-
- if (i && o->nr_bs[i - 1] && o->nr_bs[i])
- printf(",");
-
- for (j = 0; j < o->nr_bs[i]; j++) {
- struct bs *bs = &o->bs[i][j];
-
- perc = (((float) bs->nr * 100.0) / (float) o->ios[i]);
- if (perc < 1.00)
- continue;
- if (j)
- printf(":");
- if (j + 1 == o->nr_bs[i])
- printf("%u/", bs->bs);
- else
- printf("%u/%u", bs->bs, (int) floor(perc + 0.5));
- }
- }
- printf("\n");
-
- if (set_rate) {
- printf("rate=");
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- unsigned long rate;
-
- rate = o_to_kib_rate(o, i);
- if (i)
- printf(",");
- if (rate)
- printf("%luk", rate);
- }
- printf("\n");
- }
-
- if (n_add_opts)
- for (i = 0; i < n_add_opts; i++)
- printf("%s\n", add_opts[i]);
-
- printf("\n");
- return 0;
-}
-
-static int __output_p(struct btrace_pid *p, unsigned long *ios)
-{
- struct btrace_out *o = &p->o;
- int i, ret = 0;
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- if (o->nr_bs[i] <= 1)
- continue;
- qsort(o->bs[i], o->nr_bs[i], sizeof(struct bs), bs_cmp);
- }
-
- if (filename) {
- p->files = malloc(sizeof(struct trace_file));
- p->nr_files++;
- p->files[0].name = filename;
- }
-
- if (output_ascii)
- __output_p_ascii(p, ios);
- else
- ret = __output_p_fio(p, ios);
-
- return ret;
-}
-
-static void remove_ddir(struct btrace_out *o, int rw)
-{
- o->ios[rw] = 0;
-}
-
-static int prune_entry(struct btrace_out *o)
-{
- unsigned long rate;
- uint64_t time;
- int i;
-
- if (ddir_rw_sum(o->ios) < ios_threshold)
- return 1;
-
- time = o_longest_ttime(o) / 1000ULL;
- if (time < rt_threshold)
- return 1;
-
- rate = 0;
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- unsigned long this_rate;
-
- this_rate = o_to_kib_rate(o, i);
- if (this_rate < rate_threshold) {
- remove_ddir(o, i);
- this_rate = 0;
- }
- rate += this_rate;
- }
-
- if (rate < rate_threshold)
- return 1;
-
- return 0;
-}
-
-static int entry_cmp(void *priv, struct flist_head *a, struct flist_head *b)
-{
- struct btrace_pid *pa = flist_entry(a, struct btrace_pid, pid_list);
- struct btrace_pid *pb = flist_entry(b, struct btrace_pid, pid_list);
-
- return ddir_rw_sum(pb->o.ios) - ddir_rw_sum(pa->o.ios);
-}
-
-static void free_p(struct btrace_pid *p)
-{
- struct btrace_out *o = &p->o;
- int i;
-
- for (i = 0; i < p->nr_files; i++) {
- if (p->files[i].name && p->files[i].name != filename)
- free(p->files[i].name);
- }
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++)
- free(o->bs[i]);
-
- free(p->files);
- flist_del(&p->pid_list);
- flist_del(&p->hash_list);
- free(p);
-}
-
-static int entries_close(struct btrace_pid *pida, struct btrace_pid *pidb)
-{
- float perca, percb, fdiff;
- int i, idiff;
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- if ((pida->o.ios[i] && !pidb->o.ios[i]) ||
- (pidb->o.ios[i] && !pida->o.ios[i]))
- return 0;
- if (pida->o.ios[i] && pidb->o.ios[i]) {
- perca = ((float) pida->o.seq[i] * 100.0) / (float) pida->o.ios[i];
- percb = ((float) pidb->o.seq[i] * 100.0) / (float) pidb->o.ios[i];
- fdiff = perca - percb;
- if (fabs(fdiff) > random_diff)
- return 0;
- }
-
- idiff = pida->o.depth - pidb->o.depth;
- if (abs(idiff) > depth_diff)
- return 0;
- }
-
- return 1;
-}
-
-static void merge_bs(struct bs **bsap, unsigned int *nr_bsap,
- struct bs *bsb, unsigned int nr_bsb)
-{
- struct bs *bsa = *bsap;
- unsigned int nr_bsa = *nr_bsap;
- int a, b;
-
- for (b = 0; b < nr_bsb; b++) {
- int next, found = 0;
-
- for (a = 0; a < nr_bsa; a++) {
- if (bsb[b].bs != bsa[a].bs)
- continue;
-
- bsa[a].nr += bsb[b].nr;
- bsa[a].merges += bsb[b].merges;
- found = 1;
- break;
- }
-
- if (found)
- continue;
-
- next = *nr_bsap;
- bsa = realloc(bsa, (next + 1) * sizeof(struct bs));
- bsa[next].bs = bsb[b].bs;
- bsa[next].nr = bsb[b].nr;
- (*nr_bsap)++;
- *bsap = bsa;
- }
-}
-
-static int merge_entries(struct btrace_pid *pida, struct btrace_pid *pidb)
-{
- int i;
-
- if (!entries_close(pida, pidb))
- return 0;
-
- pida->nr_merge_pids++;
- pida->merge_pids = realloc(pida->merge_pids, pida->nr_merge_pids * sizeof(pid_t));
- pida->merge_pids[pida->nr_merge_pids - 1] = pidb->pid;
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++) {
- struct btrace_out *oa = &pida->o;
- struct btrace_out *ob = &pidb->o;
-
- oa->ios[i] += ob->ios[i];
- oa->merges[i] += ob->merges[i];
- oa->seq[i] += ob->seq[i];
- oa->kib[i] += ob->kib[i];
- oa->first_ttime[i] = min(oa->first_ttime[i], ob->first_ttime[i]);
- oa->last_ttime[i] = max(oa->last_ttime[i], ob->last_ttime[i]);
- merge_bs(&oa->bs[i], &oa->nr_bs[i], ob->bs[i], ob->nr_bs[i]);
- }
-
- pida->o.start_delay = min(pida->o.start_delay, pidb->o.start_delay);
- pida->o.depth = (pida->o.depth + pidb->o.depth) / 2;
- return 1;
-}
-
-static void check_merges(struct btrace_pid *p, struct flist_head *pidlist)
-{
- struct flist_head *e, *tmp;
-
- if (p->ignore)
- return;
-
- flist_for_each_safe(e, tmp, pidlist) {
- struct btrace_pid *pidb;
-
- pidb = flist_entry(e, struct btrace_pid, pid_list);
- if (pidb == p)
- continue;
-
- if (merge_entries(p, pidb)) {
- pidb->ignore = 1;
- p->numjobs++;
- }
- }
-}
-
-static int output_p(void)
-{
- unsigned long ios[DDIR_RWDIR_CNT];
- struct flist_head *e, *tmp;
- int depth_disabled = 0;
- int ret = 0;
-
- flist_for_each_safe(e, tmp, &pid_list) {
- struct btrace_pid *p;
-
- p = flist_entry(e, struct btrace_pid, pid_list);
- if (prune_entry(&p->o)) {
- free_p(p);
- continue;
- }
- p->o.start_delay = (o_first_ttime(&p->o) / 1000ULL) - first_ttime;
- depth_disabled += p->o.depth_disabled;
- }
-
- if (collapse_entries) {
- struct btrace_pid *p;
-
- flist_for_each_safe(e, tmp, &pid_list) {
- p = flist_entry(e, struct btrace_pid, pid_list);
- check_merges(p, &pid_list);
- }
-
- flist_for_each_safe(e, tmp, &pid_list) {
- p = flist_entry(e, struct btrace_pid, pid_list);
- if (p->ignore)
- free_p(p);
- }
- }
-
- if (depth_disabled)
- log_err("fio: missing completion traces, depths capped at %u\n", max_depth);
-
- memset(ios, 0, sizeof(ios));
-
- flist_sort(NULL, &pid_list, entry_cmp);
-
- flist_for_each(e, &pid_list) {
- struct btrace_pid *p;
-
- p = flist_entry(e, struct btrace_pid, pid_list);
- ret |= __output_p(p, ios);
- if (ret && !output_ascii)
- break;
- }
-
- if (output_ascii)
- printf("Total: reads=%lu, writes=%lu\n", ios[0], ios[1]);
-
- return ret;
-}
-
-static int usage(char *argv[])
-{
- log_err("%s: [options] <blktrace bin file>\n", argv[0]);
- log_err("\t-t\tUsec threshold to ignore task\n");
- log_err("\t-n\tNumber IOS threshold to ignore task\n");
- log_err("\t-f\tFio job file output\n");
- log_err("\t-d\tUse this file/device for replay\n");
- log_err("\t-r\tIgnore jobs with less than this KiB/sec rate\n");
- log_err("\t-R\tSet rate in fio job (def=%u)\n", set_rate);
- log_err("\t-D\tCap queue depth at this value (def=%u)\n", max_depth);
- log_err("\t-c\tCollapse \"identical\" jobs (def=%u)\n", collapse_entries);
- log_err("\t-u\tDepth difference for collapse (def=%u)\n", depth_diff);
- log_err("\t-x\tRandom difference for collapse (def=%u)\n", random_diff);
- log_err("\t-a\tAdditional fio option to add to job file\n");
- return 1;
-}
-
-static int trace_needs_swap(const char *trace_file, int *swap)
-{
- struct blk_io_trace t;
- int fd, ret;
-
- *swap = -1;
-
- fd = open(trace_file, O_RDONLY);
- if (fd < 0) {
- perror("open");
- return 1;
- }
-
- ret = read(fd, &t, sizeof(t));
- if (ret < 0) {
- close(fd);
- perror("read");
- return 1;
- } else if (ret != sizeof(t)) {
- close(fd);
- log_err("fio: short read on trace file\n");
- return 1;
- }
-
- close(fd);
-
- if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC)
- *swap = 0;
- else {
- /*
- * Maybe it needs to be endian swapped...
- */
- t.magic = fio_swap32(t.magic);
- if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC)
- *swap = 1;
- }
-
- if (*swap == -1) {
- log_err("fio: blktrace appears corrupt\n");
- return 1;
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int need_swap, i, c;
-
- if (argc < 2)
- return usage(argv);
-
- while ((c = getopt(argc, argv, "t:n:fd:r:RD:c:u:x:a:")) != -1) {
- switch (c) {
- case 'R':
- set_rate = 1;
- break;
- case 'r':
- rate_threshold = atoi(optarg);
- break;
- case 't':
- rt_threshold = atoi(optarg);
- break;
- case 'n':
- ios_threshold = atoi(optarg);
- break;
- case 'f':
- output_ascii = 0;
- break;
- case 'd':
- filename = strdup(optarg);
- break;
- case 'D':
- max_depth = atoi(optarg);
- break;
- case 'c':
- collapse_entries = atoi(optarg);
- break;
- case 'u':
- depth_diff = atoi(optarg);
- break;
- case 'x':
- random_diff = atoi(optarg);
- break;
- case 'a':
- add_opts = realloc(add_opts, (n_add_opts + 1) * sizeof(char *));
- add_opts[n_add_opts] = strdup(optarg);
- n_add_opts++;
- break;
- case '?':
- default:
- return usage(argv);
- }
- }
-
- if (argc == optind)
- return usage(argv);
-
- if (trace_needs_swap(argv[optind], &need_swap))
- return 1;
-
- for (i = 0; i < PID_HASH_SIZE; i++)
- INIT_FLIST_HEAD(&pid_hash[i]);
- for (i = 0; i < INFLIGHT_HASH_SIZE; i++)
- INIT_FLIST_HEAD(&inflight_hash[i]);
-
- load_blktrace(argv[optind], need_swap);
- first_ttime /= 1000ULL;
-
- return output_p();
-}
diff --git a/t/debug.c b/t/debug.c
deleted file mode 100644
index bf6f4605..00000000
--- a/t/debug.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdio.h>
-
-FILE *f_err;
-struct timeval *fio_tv = NULL;
-unsigned long fio_debug = 0;
-
-void __dprint(int type, const char *str, ...)
-{
-}
-
-void debug_init(void)
-{
- f_err = stderr;
-}
diff --git a/t/debug.h b/t/debug.h
deleted file mode 100644
index 9d1d4150..00000000
--- a/t/debug.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef FIO_DEBUG_INC_H
-#define FIO_DEBUG_INC_H
-
-extern void debug_init(void);
-
-#endif
diff --git a/t/dedupe.c b/t/dedupe.c
deleted file mode 100644
index 1f172a26..00000000
--- a/t/dedupe.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Small tool to check for dedupable blocks in a file or device. Basically
- * just scans the filename for extents of the given size, checksums them,
- * and orders them up.
- */
-#include <stdio.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "../flist.h"
-#include "../log.h"
-#include "../mutex.h"
-#include "../smalloc.h"
-#include "../minmax.h"
-#include "../crc/md5.h"
-#include "../lib/memalign.h"
-#include "../os/os.h"
-#include "../gettime.h"
-#include "../fio_time.h"
-#include "../lib/rbtree.h"
-
-#include "../lib/bloom.h"
-#include "debug.h"
-
-struct worker_thread {
- pthread_t thread;
-
- volatile int done;
-
- int fd;
- uint64_t cur_offset;
- uint64_t size;
-
- unsigned long items;
- unsigned long dupes;
- int err;
-};
-
-struct extent {
- struct flist_head list;
- uint64_t offset;
-};
-
-struct chunk {
- struct rb_node rb_node;
- uint64_t count;
- uint32_t hash[MD5_HASH_WORDS];
- struct flist_head extent_list[0];
-};
-
-struct item {
- uint64_t offset;
- uint32_t hash[MD5_HASH_WORDS];
-};
-
-static struct rb_root rb_root;
-static struct bloom *bloom;
-static struct fio_mutex *rb_lock;
-
-static unsigned int blocksize = 4096;
-static unsigned int num_threads;
-static unsigned int chunk_size = 1048576;
-static unsigned int dump_output;
-static unsigned int odirect;
-static unsigned int collision_check;
-static unsigned int print_progress = 1;
-static unsigned int use_bloom = 1;
-
-static uint64_t total_size;
-static uint64_t cur_offset;
-static struct fio_mutex *size_lock;
-
-static struct fio_file file;
-
-static uint64_t get_size(struct fio_file *f, struct stat *sb)
-{
- uint64_t ret;
-
- if (S_ISBLK(sb->st_mode)) {
- unsigned long long bytes = 0;
-
- if (blockdev_size(f, &bytes)) {
- log_err("dedupe: failed getting bdev size\n");
- return 0;
- }
- ret = bytes;
- } else
- ret = sb->st_size;
-
- return (ret & ~((uint64_t)blocksize - 1));
-}
-
-static int get_work(uint64_t *offset, uint64_t *size)
-{
- uint64_t this_chunk;
- int ret = 1;
-
- fio_mutex_down(size_lock);
-
- if (cur_offset < total_size) {
- *offset = cur_offset;
- this_chunk = min((uint64_t)chunk_size, total_size - cur_offset);
- *size = this_chunk;
- cur_offset += this_chunk;
- ret = 0;
- }
-
- fio_mutex_up(size_lock);
- return ret;
-}
-
-static int __read_block(int fd, void *buf, off_t offset, size_t count)
-{
- ssize_t ret;
-
- ret = pread(fd, buf, count, offset);
- if (ret < 0) {
- perror("pread");
- return 1;
- } else if (!ret)
- return 1;
- else if (ret != count) {
- log_err("dedupe: short read on block\n");
- return 1;
- }
-
- return 0;
-}
-
-static int read_block(int fd, void *buf, off_t offset)
-{
- return __read_block(fd, buf, offset, blocksize);
-}
-
-static void add_item(struct chunk *c, struct item *i)
-{
- /*
- * Save some memory and don't add extent items, if we don't
- * use them.
- */
- if (dump_output || collision_check) {
- struct extent *e;
-
- e = malloc(sizeof(*e));
- e->offset = i->offset;
- flist_add_tail(&e->list, &c->extent_list[0]);
- }
-
- c->count++;
-}
-
-static int col_check(struct chunk *c, struct item *i)
-{
- struct extent *e;
- char *cbuf, *ibuf;
- int ret = 1;
-
- cbuf = fio_memalign(blocksize, blocksize);
- ibuf = fio_memalign(blocksize, blocksize);
-
- e = flist_entry(c->extent_list[0].next, struct extent, list);
- if (read_block(file.fd, cbuf, e->offset))
- goto out;
-
- if (read_block(file.fd, ibuf, i->offset))
- goto out;
-
- ret = memcmp(ibuf, cbuf, blocksize);
-out:
- fio_memfree(cbuf, blocksize);
- fio_memfree(ibuf, blocksize);
- return ret;
-}
-
-static struct chunk *alloc_chunk(void)
-{
- struct chunk *c;
-
- if (collision_check || dump_output) {
- c = malloc(sizeof(struct chunk) + sizeof(struct flist_head));
- INIT_FLIST_HEAD(&c->extent_list[0]);
- } else
- c = malloc(sizeof(struct chunk));
-
- return c;
-}
-
-static void insert_chunk(struct item *i)
-{
- struct rb_node **p, *parent;
- struct chunk *c;
- int diff;
-
- p = &rb_root.rb_node;
- parent = NULL;
- while (*p) {
- parent = *p;
-
- c = rb_entry(parent, struct chunk, rb_node);
- diff = memcmp(i->hash, c->hash, sizeof(i->hash));
- if (diff < 0)
- p = &(*p)->rb_left;
- else if (diff > 0)
- p = &(*p)->rb_right;
- else {
- int ret;
-
- if (!collision_check)
- goto add;
-
- fio_mutex_up(rb_lock);
- ret = col_check(c, i);
- fio_mutex_down(rb_lock);
-
- if (!ret)
- goto add;
-
- p = &(*p)->rb_right;
- }
- }
-
- c = alloc_chunk();
- RB_CLEAR_NODE(&c->rb_node);
- c->count = 0;
- memcpy(c->hash, i->hash, sizeof(i->hash));
- rb_link_node(&c->rb_node, parent, p);
- rb_insert_color(&c->rb_node, &rb_root);
-add:
- add_item(c, i);
-}
-
-static void insert_chunks(struct item *items, unsigned int nitems,
- uint64_t *ndupes)
-{
- int i;
-
- fio_mutex_down(rb_lock);
-
- for (i = 0; i < nitems; i++) {
- if (bloom) {
- unsigned int s;
- int r;
-
- s = sizeof(items[i].hash) / sizeof(uint32_t);
- r = bloom_set(bloom, items[i].hash, s);
- *ndupes += r;
- } else
- insert_chunk(&items[i]);
- }
-
- fio_mutex_up(rb_lock);
-}
-
-static void crc_buf(void *buf, uint32_t *hash)
-{
- struct fio_md5_ctx ctx = { .hash = hash };
-
- fio_md5_init(&ctx);
- fio_md5_update(&ctx, buf, blocksize);
- fio_md5_final(&ctx);
-}
-
-static unsigned int read_blocks(int fd, void *buf, off_t offset, size_t size)
-{
- if (__read_block(fd, buf, offset, size))
- return 0;
-
- return size / blocksize;
-}
-
-static int do_work(struct worker_thread *thread, void *buf)
-{
- unsigned int nblocks, i;
- off_t offset;
- int nitems = 0;
- uint64_t ndupes = 0;
- struct item *items;
-
- offset = thread->cur_offset;
-
- nblocks = read_blocks(thread->fd, buf, offset, min(thread->size, (uint64_t)chunk_size));
- if (!nblocks)
- return 1;
-
- items = malloc(sizeof(*items) * nblocks);
-
- for (i = 0; i < nblocks; i++) {
- void *thisptr = buf + (i * blocksize);
-
- items[i].offset = offset;
- crc_buf(thisptr, items[i].hash);
- offset += blocksize;
- nitems++;
- }
-
- insert_chunks(items, nitems, &ndupes);
-
- free(items);
- thread->items += nitems;
- thread->dupes += ndupes;
- return 0;
-}
-
-static void *thread_fn(void *data)
-{
- struct worker_thread *thread = data;
- void *buf;
-
- buf = fio_memalign(blocksize, chunk_size);
-
- do {
- if (get_work(&thread->cur_offset, &thread->size)) {
- thread->err = 1;
- break;
- }
- if (do_work(thread, buf)) {
- thread->err = 1;
- break;
- }
- } while (1);
-
- thread->done = 1;
- fio_memfree(buf, chunk_size);
- return NULL;
-}
-
-static void show_progress(struct worker_thread *threads, unsigned long total)
-{
- unsigned long last_nitems = 0;
- struct timeval last_tv;
-
- fio_gettime(&last_tv, NULL);
-
- while (print_progress) {
- unsigned long this_items;
- unsigned long nitems = 0;
- uint64_t tdiff;
- float perc;
- int some_done = 0;
- int i;
-
- for (i = 0; i < num_threads; i++) {
- nitems += threads[i].items;
- some_done = threads[i].done;
- if (some_done)
- break;
- }
-
- if (some_done)
- break;
-
- perc = (float) nitems / (float) total;
- perc *= 100.0;
- this_items = nitems - last_nitems;
- this_items *= blocksize;
- tdiff = mtime_since_now(&last_tv);
- if (tdiff) {
- this_items = (this_items * 1000) / (tdiff * 1024);
- printf("%3.2f%% done (%luKiB/sec)\r", perc, this_items);
- last_nitems = nitems;
- fio_gettime(&last_tv, NULL);
- } else
- printf("%3.2f%% done\r", perc);
- fflush(stdout);
- usleep(250000);
- };
-}
-
-static int run_dedupe_threads(struct fio_file *f, uint64_t dev_size,
- uint64_t *nextents, uint64_t *nchunks)
-{
- struct worker_thread *threads;
- unsigned long nitems, total_items;
- int i, err = 0;
-
- total_size = dev_size;
- total_items = dev_size / blocksize;
- cur_offset = 0;
- size_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
-
- threads = malloc(num_threads * sizeof(struct worker_thread));
- for (i = 0; i < num_threads; i++) {
- memset(&threads[i], 0, sizeof(struct worker_thread));
- threads[i].fd = f->fd;
-
- err = pthread_create(&threads[i].thread, NULL, thread_fn, &threads[i]);
- if (err) {
- log_err("fio: thread startup failed\n");
- break;
- }
- }
-
- show_progress(threads, total_items);
-
- nitems = 0;
- *nextents = 0;
- *nchunks = 1;
- for (i = 0; i < num_threads; i++) {
- void *ret;
- pthread_join(threads[i].thread, &ret);
- nitems += threads[i].items;
- *nchunks += threads[i].dupes;
- }
-
- printf("Threads(%u): %lu items processed\n", num_threads, nitems);
-
- *nextents = nitems;
- *nchunks = nitems - *nchunks;
-
- fio_mutex_remove(size_lock);
- free(threads);
- return err;
-}
-
-static int dedupe_check(const char *filename, uint64_t *nextents,
- uint64_t *nchunks)
-{
- uint64_t dev_size;
- struct stat sb;
- int flags;
-
- flags = O_RDONLY;
- if (odirect)
- flags |= OS_O_DIRECT;
-
- memset(&file, 0, sizeof(file));
- file.file_name = strdup(filename);
-
- file.fd = open(filename, flags);
- if (file.fd == -1) {
- perror("open");
- goto err;
- }
-
- if (fstat(file.fd, &sb) < 0) {
- perror("fstat");
- goto err;
- }
-
- dev_size = get_size(&file, &sb);
- if (!dev_size)
- goto err;
-
- if (use_bloom) {
- uint64_t bloom_entries;
-
- bloom_entries = 8 * (dev_size / blocksize);
- bloom = bloom_new(bloom_entries);
- }
-
- printf("Will check <%s>, size <%llu>, using %u threads\n", filename, (unsigned long long) dev_size, num_threads);
-
- return run_dedupe_threads(&file, dev_size, nextents, nchunks);
-err:
- if (file.fd != -1)
- close(file.fd);
- free(file.file_name);
- return 1;
-}
-
-static void show_chunk(struct chunk *c)
-{
- struct flist_head *n;
- struct extent *e;
-
- printf("c hash %8x %8x %8x %8x, count %lu\n", c->hash[0], c->hash[1], c->hash[2], c->hash[3], (unsigned long) c->count);
- flist_for_each(n, &c->extent_list[0]) {
- e = flist_entry(n, struct extent, list);
- printf("\toffset %llu\n", (unsigned long long) e->offset);
- }
-}
-
-static void show_stat(uint64_t nextents, uint64_t nchunks)
-{
- double perc, ratio;
-
- printf("Extents=%lu, Unique extents=%lu\n", (unsigned long) nextents, (unsigned long) nchunks);
-
- if (nchunks) {
- ratio = (double) nextents / (double) nchunks;
- printf("De-dupe ratio: 1:%3.2f\n", ratio - 1.0);
- } else
- printf("De-dupe ratio: 1:infinite\n");
-
- perc = 1.00 - ((double) nchunks / (double) nextents);
- perc *= 100.0;
- printf("Fio setting: dedupe_percentage=%u\n", (int) (perc + 0.50));
-
-}
-
-static void iter_rb_tree(uint64_t *nextents, uint64_t *nchunks)
-{
- struct rb_node *n;
-
- *nchunks = *nextents = 0;
-
- n = rb_first(&rb_root);
- if (!n)
- return;
-
- do {
- struct chunk *c;
-
- c = rb_entry(n, struct chunk, rb_node);
- (*nchunks)++;
- *nextents += c->count;
-
- if (dump_output)
- show_chunk(c);
-
- } while ((n = rb_next(n)) != NULL);
-}
-
-static int usage(char *argv[])
-{
- log_err("Check for dedupable blocks on a device/file\n\n");
- log_err("%s: [options] <device or file>\n", argv[0]);
- log_err("\t-b\tChunk size to use\n");
- log_err("\t-t\tNumber of threads to use\n");
- log_err("\t-d\tFull extent/chunk debug output\n");
- log_err("\t-o\tUse O_DIRECT\n");
- log_err("\t-c\tFull collision check\n");
- log_err("\t-B\tUse probabilistic bloom filter\n");
- log_err("\t-p\tPrint progress indicator\n");
- return 1;
-}
-
-int main(int argc, char *argv[])
-{
- uint64_t nextents = 0, nchunks = 0;
- int c, ret;
-
- arch_init(argv);
- debug_init();
-
- while ((c = getopt(argc, argv, "b:t:d:o:c:p:B:")) != -1) {
- switch (c) {
- case 'b':
- blocksize = atoi(optarg);
- break;
- case 't':
- num_threads = atoi(optarg);
- break;
- case 'd':
- dump_output = atoi(optarg);
- break;
- case 'o':
- odirect = atoi(optarg);
- break;
- case 'c':
- collision_check = atoi(optarg);
- break;
- case 'p':
- print_progress = atoi(optarg);
- break;
- case 'B':
- use_bloom = atoi(optarg);
- break;
- case '?':
- default:
- return usage(argv);
- }
- }
-
- if (collision_check || dump_output)
- use_bloom = 0;
-
- if (!num_threads)
- num_threads = cpus_online();
-
- if (argc == optind)
- return usage(argv);
-
- sinit();
-
- rb_root = RB_ROOT;
- rb_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
-
- ret = dedupe_check(argv[optind], &nextents, &nchunks);
-
- if (!ret) {
- if (!bloom)
- iter_rb_tree(&nextents, &nchunks);
-
- show_stat(nextents, nchunks);
- }
-
- fio_mutex_remove(rb_lock);
- if (bloom)
- bloom_free(bloom);
- scleanup();
- return ret;
-}
diff --git a/t/gen-rand.c b/t/gen-rand.c
deleted file mode 100644
index 6c31f925..00000000
--- a/t/gen-rand.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <math.h>
-#include <string.h>
-
-#include "../lib/types.h"
-#include "../log.h"
-#include "../lib/lfsr.h"
-#include "../lib/axmap.h"
-#include "../smalloc.h"
-#include "../minmax.h"
-#include "../lib/rand.h"
-
-int main(int argc, char *argv[])
-{
- struct frand_state s;
- uint64_t i, start, end, nvalues;
- unsigned long *buckets, index, pass, fail;
- double p, dev, mean, vmin, vmax;
-
- if (argc < 4) {
- log_err("%s: start end nvalues\n", argv[0]);
- return 1;
- }
-
- start = strtoul(argv[1], NULL, 10);
- end = strtoul(argv[2], NULL, 10);
-
- if (start >= end) {
- log_err("%s: start must be smaller than end\n", argv[0]);
- return 1;
- }
- index = 1 + end - start;
- buckets = calloc(index, sizeof(unsigned long));
-
- nvalues = strtoul(argv[3], NULL, 10);
-
- init_rand(&s, false);
-
- for (i = 0; i < nvalues; i++) {
- int v = rand32_between(&s, start, end);
-
- buckets[v - start]++;
- }
-
- p = 1.0 / index;
- dev = sqrt(nvalues * p * (1.0 - p));
- mean = nvalues * p;
- vmin = mean - dev;
- vmax = mean + dev;
-
- pass = fail = 0;
- for (i = 0; i < index; i++) {
- if (buckets[i] < vmin || buckets[i] > vmax) {
- printf("FAIL bucket%4lu: val=%8lu (%.1f < %.1f > %.1f)\n", (unsigned long) i + 1, buckets[i], vmin, mean, vmax);
- fail++;
- } else {
- printf("PASS bucket%4lu: val=%8lu (%.1f < %.1f > %.1f)\n", (unsigned long) i + 1, buckets[i], vmin, mean, vmax);
- pass++;
- }
- }
-
- printf("Passes=%lu, Fail=%lu\n", pass, fail);
-
- return 0;
-}
diff --git a/t/genzipf.c b/t/genzipf.c
deleted file mode 100644
index 9faec389..00000000
--- a/t/genzipf.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Generate/analyze pareto/zipf distributions to better understand
- * what an access pattern would look like.
- *
- * For instance, the following would generate a zipf distribution
- * with theta 1.2, using 262144 (1 GiB / 4096) values and split the
- * reporting into 20 buckets:
- *
- * ./t/fio-genzipf -t zipf -i 1.2 -g 1 -b 4096 -o 20
- *
- * Only the distribution type (zipf or pareto) and spread input need
- * to be given, if not given defaults are used.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "../lib/zipf.h"
-#include "../lib/gauss.h"
-#include "../flist.h"
-#include "../hash.h"
-
-#define DEF_NR_OUTPUT 20
-
-struct node {
- struct flist_head list;
- unsigned long long val;
- unsigned long hits;
-};
-
-static struct flist_head *hash;
-static unsigned long hash_bits = 24;
-static unsigned long hash_size = 1 << 24;
-
-enum {
- TYPE_NONE = 0,
- TYPE_ZIPF,
- TYPE_PARETO,
- TYPE_NORMAL,
-};
-static const char *dist_types[] = { "None", "Zipf", "Pareto", "Normal" };
-
-enum {
- OUTPUT_NORMAL,
- OUTPUT_CSV,
-};
-
-static int dist_type = TYPE_ZIPF;
-static unsigned long gib_size = 500;
-static unsigned long block_size = 4096;
-static unsigned long output_nranges = DEF_NR_OUTPUT;
-static double percentage;
-static double dist_val;
-static int output_type = OUTPUT_NORMAL;
-
-#define DEF_ZIPF_VAL 1.2
-#define DEF_PARETO_VAL 0.3
-
-static unsigned int hashv(unsigned long long val)
-{
- return jhash(&val, sizeof(val), 0) & (hash_size - 1);
-}
-
-static struct node *hash_lookup(unsigned long long val)
-{
- struct flist_head *l = &hash[hashv(val)];
- struct flist_head *entry;
- struct node *n;
-
- flist_for_each(entry, l) {
- n = flist_entry(entry, struct node, list);
- if (n->val == val)
- return n;
- }
-
- return NULL;
-}
-
-static void hash_insert(struct node *n, unsigned long long val)
-{
- struct flist_head *l = &hash[hashv(val)];
-
- n->val = val;
- n->hits = 1;
- flist_add_tail(&n->list, l);
-}
-
-static void usage(void)
-{
- printf("genzipf: test zipf/pareto values for fio input\n");
- printf("\t-h\tThis help screen\n");
- printf("\t-p\tGenerate size of data set that are hit by this percentage\n");
- printf("\t-t\tDistribution type (zipf, pareto, or normal)\n");
- printf("\t-i\tDistribution algorithm input (zipf theta, pareto power,\n"
- "\t\tor normal %% deviation)\n");
- printf("\t-b\tBlock size of a given range (in bytes)\n");
- printf("\t-g\tSize of data set (in gigabytes)\n");
- printf("\t-o\tNumber of output rows\n");
- printf("\t-c\tOutput ranges in CSV format\n");
-}
-
-static int parse_options(int argc, char *argv[])
-{
- const char *optstring = "t:g:i:o:b:p:ch";
- int c, dist_val_set = 0;
-
- while ((c = getopt(argc, argv, optstring)) != -1) {
- switch (c) {
- case 'h':
- usage();
- return 1;
- case 'p':
- percentage = atof(optarg);
- break;
- case 'b':
- block_size = strtoul(optarg, NULL, 10);
- break;
- case 't':
- if (!strncmp(optarg, "zipf", 4))
- dist_type = TYPE_ZIPF;
- else if (!strncmp(optarg, "pareto", 6))
- dist_type = TYPE_PARETO;
- else if (!strncmp(optarg, "normal", 6))
- dist_type = TYPE_NORMAL;
- else {
- printf("wrong dist type: %s\n", optarg);
- return 1;
- }
- break;
- case 'g':
- gib_size = strtoul(optarg, NULL, 10);
- break;
- case 'i':
- dist_val = atof(optarg);
- dist_val_set = 1;
- break;
- case 'o':
- output_nranges = strtoul(optarg, NULL, 10);
- break;
- case 'c':
- output_type = OUTPUT_CSV;
- break;
- default:
- printf("bad option %c\n", c);
- return 1;
- }
- }
-
- if (dist_type == TYPE_PARETO) {
- if ((dist_val >= 1.00 || dist_val < 0.00)) {
- printf("pareto input must be > 0.00 and < 1.00\n");
- return 1;
- }
- if (!dist_val_set)
- dist_val = DEF_PARETO_VAL;
- } else if (dist_type == TYPE_ZIPF) {
- if (dist_val == 1.0) {
- printf("zipf input must be different than 1.0\n");
- return 1;
- }
- if (!dist_val_set)
- dist_val = DEF_ZIPF_VAL;
- }
-
- return 0;
-}
-
-struct output_sum {
- double output;
- unsigned int nranges;
-};
-
-static int node_cmp(const void *p1, const void *p2)
-{
- const struct node *n1 = p1;
- const struct node *n2 = p2;
-
- return n2->hits - n1->hits;
-}
-
-static void output_csv(struct node *nodes, unsigned long nnodes)
-{
- unsigned long i;
-
- printf("rank, count\n");
- for (i = 0; i < nnodes; i++)
- printf("%lu, %lu\n", i, nodes[i].hits);
-}
-
-static void output_normal(struct node *nodes, unsigned long nnodes,
- unsigned long nranges)
-{
- unsigned long i, j, cur_vals, interval_step, next_interval, total_vals;
- unsigned long blocks = percentage * nnodes / 100;
- double hit_percent_sum = 0;
- unsigned long long hit_sum = 0;
- double perc, perc_i;
- struct output_sum *output_sums;
-
- interval_step = (nnodes - 1) / output_nranges + 1;
- next_interval = interval_step;
- output_sums = malloc(output_nranges * sizeof(struct output_sum));
-
- for (i = 0; i < output_nranges; i++) {
- output_sums[i].output = 0.0;
- output_sums[i].nranges = 0;
- }
-
- j = total_vals = cur_vals = 0;
-
- for (i = 0; i < nnodes; i++) {
- struct output_sum *os = &output_sums[j];
- struct node *node = &nodes[i];
- cur_vals += node->hits;
- total_vals += node->hits;
- os->nranges += node->hits;
- if (i == (next_interval) -1 || i == nnodes - 1) {
- os->output = (double) cur_vals / (double) nranges;
- os->output *= 100.0;
- cur_vals = 0;
- next_interval += interval_step;
- j++;
- }
-
- if (percentage) {
- if (total_vals >= blocks) {
- double cs = (double) i * block_size / (1024.0 * 1024.0);
- char p = 'M';
-
- if (cs > 1024.0) {
- cs /= 1024.0;
- p = 'G';
- }
- if (cs > 1024.0) {
- cs /= 1024.0;
- p = 'T';
- }
-
- printf("%.2f%% of hits satisfied in %.3f%cB of cache\n", percentage, cs, p);
- percentage = 0.0;
- }
- }
- }
-
- perc_i = 100.0 / (double)output_nranges;
- perc = 0.0;
-
- printf("\n Rows Hits %% Sum %% # Hits Size\n");
- printf("-----------------------------------------------------------------------\n");
- for (i = 0; i < output_nranges; i++) {
- struct output_sum *os = &output_sums[i];
- double gb = (double)os->nranges * block_size / 1024.0;
- char p = 'K';
-
- if (gb > 1024.0) {
- p = 'M';
- gb /= 1024.0;
- }
- if (gb > 1024.0) {
- p = 'G';
- gb /= 1024.0;
- }
-
- perc += perc_i;
- hit_percent_sum += os->output;
- hit_sum += os->nranges;
- printf("%s %6.2f%%\t%6.2f%%\t\t%6.2f%%\t\t%8u\t%6.2f%c\n",
- i ? "|->" : "Top", perc, os->output, hit_percent_sum,
- os->nranges, gb, p);
- }
-
- printf("-----------------------------------------------------------------------\n");
- printf("Total\t\t\t\t\t\t%8llu\n", hit_sum);
- free(output_sums);
-}
-
-int main(int argc, char *argv[])
-{
- unsigned long offset;
- unsigned long long nranges;
- unsigned long nnodes;
- struct node *nodes;
- struct zipf_state zs;
- struct gauss_state gs;
- int i, j;
-
- if (parse_options(argc, argv))
- return 1;
-
- if (output_type != OUTPUT_CSV)
- printf("Generating %s distribution with %f input and %lu GiB size and %lu block_size.\n",
- dist_types[dist_type], dist_val, gib_size, block_size);
-
- nranges = gib_size * 1024 * 1024 * 1024ULL;
- nranges /= block_size;
-
- if (dist_type == TYPE_ZIPF)
- zipf_init(&zs, nranges, dist_val, 1);
- else if (dist_type == TYPE_PARETO)
- pareto_init(&zs, nranges, dist_val, 1);
- else
- gauss_init(&gs, nranges, dist_val, 1);
-
- hash_bits = 0;
- hash_size = nranges;
- while ((hash_size >>= 1) != 0)
- hash_bits++;
-
- hash_size = 1 << hash_bits;
-
- hash = calloc(hash_size, sizeof(struct flist_head));
- for (i = 0; i < hash_size; i++)
- INIT_FLIST_HEAD(&hash[i]);
-
- nodes = malloc(nranges * sizeof(struct node));
-
- for (i = j = 0; i < nranges; i++) {
- struct node *n;
-
- if (dist_type == TYPE_ZIPF)
- offset = zipf_next(&zs);
- else if (dist_type == TYPE_PARETO)
- offset = pareto_next(&zs);
- else
- offset = gauss_next(&gs);
-
- n = hash_lookup(offset);
- if (n)
- n->hits++;
- else {
- hash_insert(&nodes[j], offset);
- j++;
- }
- }
-
- qsort(nodes, j, sizeof(struct node), node_cmp);
- nnodes = j;
-
- if (output_type == OUTPUT_CSV)
- output_csv(nodes, nnodes);
- else
- output_normal(nodes, nnodes, nranges);
-
- free(hash);
- free(nodes);
- return 0;
-}
diff --git a/t/ieee754.c b/t/ieee754.c
deleted file mode 100644
index 3898ab74..00000000
--- a/t/ieee754.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <stdio.h>
-#include "../lib/ieee754.h"
-
-static double values[] = { -17.23, 17.23, 123.4567, 98765.4321, 0.0 };
-
-int main(int argc, char *argv[])
-{
- uint64_t i;
- double f;
- int j;
-
- j = 0;
- do {
- i = fio_double_to_uint64(values[j]);
- f = fio_uint64_to_double(i);
- printf("%f -> %f\n", values[j], f);
- j++;
- } while (values[j] != 0.0);
-
- return 0;
-}
diff --git a/t/jobs/t0001-52c58027.fio b/t/jobs/t0001-52c58027.fio
deleted file mode 100644
index 49b7d118..00000000
--- a/t/jobs/t0001-52c58027.fio
+++ /dev/null
@@ -1,6 +0,0 @@
-#Commit 52c580272d87d2b9b8a65d317bf7c2d432a30fec
-[foo]
-size=20000
-bsrange=1k-4k
-rw=randread
-ioengine=null
diff --git a/t/jobs/t0002-13af05ae-post b/t/jobs/t0002-13af05ae-post
deleted file mode 100644
index b7d5bab9..00000000
--- a/t/jobs/t0002-13af05ae-post
+++ /dev/null
@@ -1,24 +0,0 @@
-[global]
-ioengine=libaio
-direct=1
-filename=/dev/fioa
-iodepth=128
-size=1G
-loops=1
-group_reporting=1
-readwrite=read
-do_verify=1
-verify=md5
-verify_fatal=1
-numjobs=1
-thread
-bssplit=512/50:1M/50
-
-[thread0]
-offset=0G
-
-[thread-mix0]
-offset=4G
-size=1G
-readwrite=rw
-bsrange=512:1M
diff --git a/t/jobs/t0002-13af05ae-pre b/t/jobs/t0002-13af05ae-pre
deleted file mode 100644
index 77dd48fd..00000000
--- a/t/jobs/t0002-13af05ae-pre
+++ /dev/null
@@ -1,23 +0,0 @@
-[global]
-ioengine=libaio
-direct=1
-filename=/dev/fioa
-iodepth=128
-size=1G
-loops=1
-group_reporting=1
-readwrite=write
-do_verify=0
-verify=md5
-numjobs=1
-thread
-bssplit=512/50:1M/50
-
-[thread0]
-offset=0G
-
-[thread-mix0]
-offset=4G
-readwrite=rw
-size=1G
-bsrange=512:1M
diff --git a/t/jobs/t0003-0ae2c6e1-post.fio b/t/jobs/t0003-0ae2c6e1-post.fio
deleted file mode 100644
index 8bc4f05a..00000000
--- a/t/jobs/t0003-0ae2c6e1-post.fio
+++ /dev/null
@@ -1,26 +0,0 @@
-# Expected result: verify fails.
-# Buggy result: fio segfaults
-[global]
-ioengine=libaio
-direct=1
-filename=/tmp/foo
-iodepth=128
-size=1M
-loops=1
-group_reporting=1
-readwrite=read
-do_verify=1
-verify=md5
-verify_fatal=1
-numjobs=1
-thread
-verify_dump=1
-bs=4k
-
-[large_reads]
-offset=0G
-blocksize=1M
-
-[small_reads]
-offset=1G
-blocksize=512
diff --git a/t/jobs/t0003-0ae2c6e1-pre.fio b/t/jobs/t0003-0ae2c6e1-pre.fio
deleted file mode 100644
index 46f452cb..00000000
--- a/t/jobs/t0003-0ae2c6e1-pre.fio
+++ /dev/null
@@ -1,22 +0,0 @@
-[global]
-ioengine=libaio
-direct=1
-filename=/tmp/foo
-iodepth=128
-size=10M
-loops=1
-group_reporting=1
-readwrite=write
-do_verify=0
-verify=md5
-numjobs=1
-thread
-verify_dump=1
-
-[small_writes]
-offset=0G
-blocksize=512
-
-[large_writes]
-offset=1G
-blocksize=1M
diff --git a/t/jobs/t0004-8a99fdf6.fio b/t/jobs/t0004-8a99fdf6.fio
deleted file mode 100644
index 09ae9b26..00000000
--- a/t/jobs/t0004-8a99fdf6.fio
+++ /dev/null
@@ -1,27 +0,0 @@
-# Expected result: fio runs to completion
-# Buggy result: fio segfaults
-[global]
-ioengine=libaio
-direct=1
-filename=/tmp/foo
-iodepth=128
-size=10M
-loops=1
-group_reporting=1
-readwrite=write
-do_verify=0
-verify=md5
-numjobs=1
-thread
-verify_dump=1
-
-[small_writes]
-offset=0G
-blocksize=512
-verify_interval=1M
-
-[large_writes]
-stonewall
-offset=1G
-blocksize=1M
-verify_interval=512
diff --git a/t/jobs/t0005-f7078f7b.fio b/t/jobs/t0005-f7078f7b.fio
deleted file mode 100644
index 3481d630..00000000
--- a/t/jobs/t0005-f7078f7b.fio
+++ /dev/null
@@ -1,13 +0,0 @@
-# Expected result: fio reads and writes 100m
-# Buggy result: fio reads and writes ~100m/2
-[global]
-bs=4k
-ioengine=sync
-size=100m
-direct=1
-filename=xxx
-
-[write]
-verify=md5
-verify_backlog=32
-rw=write
diff --git a/t/jobs/t0006-82af2a7c.fio b/t/jobs/t0006-82af2a7c.fio
deleted file mode 100644
index 7117067e..00000000
--- a/t/jobs/t0006-82af2a7c.fio
+++ /dev/null
@@ -1,16 +0,0 @@
-# Expected results: workload runs and switches between 'm' and 'V' state
-# Buggy result: workload stays in 'm' mode, never doing actual verifies
-[global]
-rw=randrw
-bs=4k
-direct=1
-ioengine=libaio
-iodepth=32
-verify=meta
-verify_backlog=1024
-verify_fatal=1
-
-[ver-test]
-filename=foo
-size=4g
-verify_pattern=0xaaa
diff --git a/t/jobs/t0007-37cf9e3c.fio b/t/jobs/t0007-37cf9e3c.fio
deleted file mode 100644
index fd70c21c..00000000
--- a/t/jobs/t0007-37cf9e3c.fio
+++ /dev/null
@@ -1,10 +0,0 @@
-# Expected result: fio reads 87040KB of data
-# Buggy result: fio reads the full 128MB of data
-[foo]
-size=128mb
-rw=read:512k
-bs=1m
-time_based
-norandommap
-write_iolog=log
-direct=1
diff --git a/t/jobs/t0008-ae2fafc8.fio b/t/jobs/t0008-ae2fafc8.fio
deleted file mode 100644
index 4b364850..00000000
--- a/t/jobs/t0008-ae2fafc8.fio
+++ /dev/null
@@ -1,12 +0,0 @@
-# Expected result: fio writes 16MB, reads 16+16MB
-# Buggy result: fio writes 16MB, reads ~21MB
-[global]
-bs=4k
-verify=crc32c
-rw=readwrite
-direct=1
-
-[foo]
-size=32m
-do_verify=1
-verify_backlog=1
diff --git a/t/jobs/t0009-f8b0bd10.fio b/t/jobs/t0009-f8b0bd10.fio
deleted file mode 100644
index 90e07ad8..00000000
--- a/t/jobs/t0009-f8b0bd10.fio
+++ /dev/null
@@ -1,40 +0,0 @@
-# Expected result: fio verifies and runs for 1m
-# Buggy result: fio crashes with:
-# __get_io_u: Assertion `io_u->flags & IO_U_F_FREE' failed
-
-[global]
-direct=1
-ioengine=null
-size=20g
-norandommap
-randrepeat=0
-bs=4096
-iodepth=170
-#iodepth=96
-#numjobs=1
-numjobs=1
-#numjobs=24
-# number_ios=1
-# runtime=216000
-runtime=3600
-time_based=1
-group_reporting=1
-thread
-gtod_reduce=1
-iodepth_batch=4
-iodepth_batch_complete=4
-cpus_allowed=0-5
-cpus_allowed_policy=split
-rw=randwrite
-verify=crc32c-intel
-verify_backlog=1m
-do_verify=1
-verify_async=6
-verify_async_cpus=0-5
-runtime=1m
-
-[4_KiB_RR_drive_r]
-
-[4_KiB_RR_drive_s]
-
-
diff --git a/t/lfsr-test.c b/t/lfsr-test.c
deleted file mode 100644
index 7016f268..00000000
--- a/t/lfsr-test.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "../lib/lfsr.h"
-#include "../gettime.h"
-#include "../fio_time.h"
-
-void usage()
-{
- printf("Usage: lfsr-test 0x<numbers> [seed] [spin] [verify]\n");
- printf("-------------------------------------------------------------\n");
- printf("*numbers: how many random numbers to produce (in hex)\n"
- "seed: initial value\n"
- "spin: how many iterations before we produce a number\n"
- "verify: check if LFSR has iterated correctly\n\n"
- "Only <numbers> is required. The rest are evaluated to 0 or false\n"
- "Elapsed/mean time and verification results are printed at the"
- "end of the test\n");
-}
-
-int main(int argc, char *argv[])
-{
- int r;
- struct timeval start, end;
- struct fio_lfsr *fl;
- int verify = 0;
- unsigned int spin = 0;
- uint64_t seed = 0;
- uint64_t numbers;
- uint64_t v_size;
- uint64_t i;
- void *v = NULL, *v_start;
- double total, mean;
-
- arch_init(argv);
-
- /* Read arguments */
- switch (argc) {
- case 5: if (strncmp(argv[4], "verify", 7) == 0)
- verify = 1;
- case 4: spin = atoi(argv[3]);
- case 3: seed = atol(argv[2]);
- case 2: numbers = strtol(argv[1], NULL, 16);
- break;
- default: usage();
- return 1;
- }
-
- /* Initialize LFSR */
- fl = malloc(sizeof(struct fio_lfsr));
- if (!fl) {
- perror("malloc");
- return 1;
- }
-
- r = lfsr_init(fl, numbers, seed, spin);
- if (r) {
- printf("Initialization failed.\n");
- return r;
- }
-
- /* Print specs */
- printf("LFSR specs\n");
- printf("==========================\n");
- printf("Size is %u\n", 64 - __builtin_clzl(fl->cached_bit));
- printf("Max val is %lu\n", (unsigned long) fl->max_val);
- printf("XOR-mask is 0x%lX\n", (unsigned long) fl->xormask);
- printf("Seed is %lu\n", (unsigned long) fl->last_val);
- printf("Spin is %u\n", fl->spin);
- printf("Cycle length is %lu\n", (unsigned long) fl->cycle_length);
-
- /* Create verification table */
- if (verify) {
- v_size = numbers * sizeof(uint8_t);
- v = malloc(v_size);
- memset(v, 0, v_size);
- printf("\nVerification table is %lf KiB\n", (double)(v_size) / 1024);
- }
- v_start = v;
-
- /*
- * Iterate over a tight loop until we have produced all the requested
- * numbers. Verifying the results should introduce some small yet not
- * negligible overhead.
- */
- fprintf(stderr, "\nTest initiated... ");
- fio_gettime(&start, NULL);
- while (!lfsr_next(fl, &i)) {
- if (verify)
- *(uint8_t *)(v + i) += 1;
- }
- fio_gettime(&end, NULL);
- fprintf(stderr, "finished.\n");
-
-
- /* Check if all expected numbers within range have been calculated */
- r = 0;
- if (verify) {
- fprintf(stderr, "Verifying results... ");
- for (i = 0; i < numbers; i++) {
- if (*(uint8_t *)(v + i) != 1) {
- fprintf(stderr, "failed (%lu = %d).\n",
- (unsigned long) i,
- *(uint8_t *)(v + i));
- r = 1;
- break;
- }
- }
- if (!r)
- fprintf(stderr, "OK!\n");
- }
-
- /* Calculate elapsed time and mean time per number */
- total = utime_since(&start, &end);
- mean = total / fl->num_vals;
-
- printf("\nTime results ");
- if (verify)
- printf("(slower due to verification)");
- printf("\n==============================\n");
- printf("Elapsed: %lf s\n", total / pow(10,6));
- printf("Mean: %lf us\n", mean);
-
- free(v_start);
- free(fl);
- return r;
-}
diff --git a/t/log.c b/t/log.c
deleted file mode 100644
index 929aac6c..00000000
--- a/t/log.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include "../minmax.h"
-
-size_t log_err(const char *format, ...)
-{
- char buffer[1024];
- va_list args;
- size_t len;
-
- va_start(args, format);
- len = vsnprintf(buffer, sizeof(buffer), format, args);
- va_end(args);
- len = min(len, sizeof(buffer) - 1);
-
- return fwrite(buffer, len, 1, stderr);
-}
-
-size_t log_info(const char *format, ...)
-{
- char buffer[1024];
- va_list args;
- size_t len;
-
- va_start(args, format);
- len = vsnprintf(buffer, sizeof(buffer), format, args);
- va_end(args);
- len = min(len, sizeof(buffer) - 1);
-
- return fwrite(buffer, len, 1, stdout);
-}
diff --git a/t/memlock.c b/t/memlock.c
deleted file mode 100644
index 3d3579ad..00000000
--- a/t/memlock.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-
-static struct thread_data {
- unsigned long mib;
-} td;
-
-static void *worker(void *data)
-{
- struct thread_data *td = data;
- unsigned long index;
- size_t size;
- char *buf;
- int i, first = 1;
-
- size = td->mib * 1024UL * 1024UL;
- buf = malloc(size);
-
- for (i = 0; i < 100000; i++) {
- for (index = 0; index + 4096 < size; index += 4096)
- memset(&buf[index+512], 0x89, 512);
- if (first) {
- printf("loop%d: did %lu MiB\n", i+1, size/(1024UL*1024UL));
- first = 0;
- }
- }
- return NULL;
-}
-
-int main(int argc, char *argv[])
-{
- unsigned long mib, threads;
- pthread_t *pthreads;
- int i;
-
- if (argc < 3) {
- printf("%s: <MiB per thread> <threads>\n", argv[0]);
- return 1;
- }
-
- mib = strtoul(argv[1], NULL, 10);
- threads = strtoul(argv[2], NULL, 10);
-
- pthreads = calloc(threads, sizeof(pthread_t));
- td.mib = mib;
-
- for (i = 0; i < threads; i++)
- pthread_create(&pthreads[i], NULL, worker, &td);
-
- for (i = 0; i < threads; i++) {
- void *ret;
-
- pthread_join(pthreads[i], &ret);
- }
- return 0;
-}
diff --git a/t/read-to-pipe-async.c b/t/read-to-pipe-async.c
deleted file mode 100644
index ebdd8f10..00000000
--- a/t/read-to-pipe-async.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Read a file and write the contents to stdout. If a given read takes
- * longer than 'max_us' time, then we schedule a new thread to handle
- * the next read. This avoids the coordinated omission problem, where
- * one request appears to take a long time, but in reality a lot of
- * requests would have been slow, but we don't notice since new submissions
- * are not being issued if just 1 is held up.
- *
- * One test case:
- *
- * $ time (./read-to-pipe-async -f randfile.gz | gzip -dc > outfile; sync)
- *
- * This will read randfile.gz and log the latencies of doing so, while
- * piping the output to gzip to decompress it. Any latencies over max_us
- * are logged when they happen, and latency buckets are displayed at the
- * end of the run
- *
- * gcc -Wall -g -O2 -o read-to-pipe-async read-to-pipe-async.c -lpthread
- *
- * Copyright (C) 2016 Jens Axboe
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <inttypes.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "../flist.h"
-
-static int bs = 4096;
-static int max_us = 10000;
-static char *file;
-static int separate_writer = 1;
-
-#define PLAT_BITS 8
-#define PLAT_VAL (1 << PLAT_BITS)
-#define PLAT_GROUP_NR 19
-#define PLAT_NR (PLAT_GROUP_NR * PLAT_VAL)
-#define PLAT_LIST_MAX 20
-
-struct stats {
- unsigned int plat[PLAT_NR];
- unsigned int nr_samples;
- unsigned int max;
- unsigned int min;
- unsigned int over;
-};
-
-static double plist[PLAT_LIST_MAX] = { 50.0, 75.0, 90.0, 95.0, 99.0, 99.5, 99.9, 99.99, 99.999, 99.9999, };
-
-struct thread_data {
- int exit;
- int done;
- pthread_mutex_t lock;
- pthread_cond_t cond;
- pthread_mutex_t done_lock;
- pthread_cond_t done_cond;
- pthread_t thread;
-};
-
-struct writer_thread {
- struct flist_head list;
- struct flist_head done_list;
- struct stats s;
- struct thread_data thread;
-};
-
-struct reader_thread {
- struct flist_head list;
- struct flist_head done_list;
- int started;
- int busy;
- int write_seq;
- struct stats s;
- struct thread_data thread;
-};
-
-struct work_item {
- struct flist_head list;
- void *buf;
- size_t buf_size;
- off_t off;
- int fd;
- int seq;
- struct writer_thread *writer;
- struct reader_thread *reader;
- pthread_mutex_t lock;
- pthread_cond_t cond;
- pthread_t thread;
-};
-
-static struct reader_thread reader_thread;
-static struct writer_thread writer_thread;
-
-uint64_t utime_since(const struct timeval *s, const struct timeval *e)
-{
- long sec, usec;
- uint64_t ret;
-
- sec = e->tv_sec - s->tv_sec;
- usec = e->tv_usec - s->tv_usec;
- if (sec > 0 && usec < 0) {
- sec--;
- usec += 1000000;
- }
-
- if (sec < 0 || (sec == 0 && usec < 0))
- return 0;
-
- ret = sec * 1000000ULL + usec;
-
- return ret;
-}
-
-static struct work_item *find_seq(struct writer_thread *w, unsigned int seq)
-{
- struct work_item *work;
- struct flist_head *entry;
-
- if (flist_empty(&w->list))
- return NULL;
-
- flist_for_each(entry, &w->list) {
- work = flist_entry(entry, struct work_item, list);
- if (work->seq == seq)
- return work;
- }
-
- return NULL;
-}
-
-static unsigned int plat_val_to_idx(unsigned int val)
-{
- unsigned int msb, error_bits, base, offset;
-
- /* Find MSB starting from bit 0 */
- if (val == 0)
- msb = 0;
- else
- msb = sizeof(val)*8 - __builtin_clz(val) - 1;
-
- /*
- * MSB <= (PLAT_BITS-1), cannot be rounded off. Use
- * all bits of the sample as index
- */
- if (msb <= PLAT_BITS)
- return val;
-
- /* Compute the number of error bits to discard*/
- error_bits = msb - PLAT_BITS;
-
- /* Compute the number of buckets before the group */
- base = (error_bits + 1) << PLAT_BITS;
-
- /*
- * Discard the error bits and apply the mask to find the
- * index for the buckets in the group
- */
- offset = (PLAT_VAL - 1) & (val >> error_bits);
-
- /* Make sure the index does not exceed (array size - 1) */
- return (base + offset) < (PLAT_NR - 1) ?
- (base + offset) : (PLAT_NR - 1);
-}
-
-/*
- * Convert the given index of the bucket array to the value
- * represented by the bucket
- */
-static unsigned int plat_idx_to_val(unsigned int idx)
-{
- unsigned int error_bits, k, base;
-
- assert(idx < PLAT_NR);
-
- /* MSB <= (PLAT_BITS-1), cannot be rounded off. Use
- * all bits of the sample as index */
- if (idx < (PLAT_VAL << 1))
- return idx;
-
- /* Find the group and compute the minimum value of that group */
- error_bits = (idx >> PLAT_BITS) - 1;
- base = 1 << (error_bits + PLAT_BITS);
-
- /* Find its bucket number of the group */
- k = idx % PLAT_VAL;
-
- /* Return the mean of the range of the bucket */
- return base + ((k + 0.5) * (1 << error_bits));
-}
-
-static void add_lat(struct stats *s, unsigned int us, const char *name)
-{
- int lat_index = 0;
-
- if (us > s->max)
- s->max = us;
- if (us < s->min)
- s->min = us;
-
- if (us > max_us) {
- fprintf(stderr, "%s latency=%u usec\n", name, us);
- s->over++;
- }
-
- lat_index = plat_val_to_idx(us);
- __sync_fetch_and_add(&s->plat[lat_index], 1);
- __sync_fetch_and_add(&s->nr_samples, 1);
-}
-
-static int write_work(struct work_item *work)
-{
- struct timeval s, e;
- ssize_t ret;
-
- gettimeofday(&s, NULL);
- ret = write(STDOUT_FILENO, work->buf, work->buf_size);
- gettimeofday(&e, NULL);
- assert(ret == work->buf_size);
-
- add_lat(&work->writer->s, utime_since(&s, &e), "write");
- return work->seq + 1;
-}
-
-static void thread_exiting(struct thread_data *thread)
-{
- __sync_fetch_and_add(&thread->done, 1);
- pthread_cond_signal(&thread->done_cond);
-}
-
-static void *writer_fn(void *data)
-{
- struct writer_thread *wt = data;
- struct work_item *work;
- unsigned int seq = 1;
-
- work = NULL;
- while (!wt->thread.exit || !flist_empty(&wt->list)) {
- pthread_mutex_lock(&wt->thread.lock);
-
- if (work) {
- flist_add_tail(&work->list, &wt->done_list);
- work = NULL;
- }
-
- work = find_seq(wt, seq);
- if (work)
- flist_del_init(&work->list);
- else
- pthread_cond_wait(&wt->thread.cond, &wt->thread.lock);
-
- pthread_mutex_unlock(&wt->thread.lock);
-
- if (work)
- seq = write_work(work);
- }
-
- thread_exiting(&wt->thread);
- return NULL;
-}
-
-static void reader_work(struct work_item *work)
-{
- struct timeval s, e;
- ssize_t ret;
- size_t left;
- void *buf;
- off_t off;
-
- gettimeofday(&s, NULL);
-
- left = work->buf_size;
- buf = work->buf;
- off = work->off;
- while (left) {
- ret = pread(work->fd, buf, left, off);
- if (!ret) {
- fprintf(stderr, "zero read\n");
- break;
- } else if (ret < 0) {
- fprintf(stderr, "errno=%d\n", errno);
- break;
- }
- left -= ret;
- off += ret;
- buf += ret;
- }
-
- gettimeofday(&e, NULL);
-
- add_lat(&work->reader->s, utime_since(&s, &e), "read");
-
- pthread_cond_signal(&work->cond);
-
- if (separate_writer) {
- pthread_mutex_lock(&work->writer->thread.lock);
- flist_add_tail(&work->list, &work->writer->list);
- pthread_mutex_unlock(&work->writer->thread.lock);
- pthread_cond_signal(&work->writer->thread.cond);
- } else {
- struct reader_thread *rt = work->reader;
- struct work_item *next = NULL;
- struct flist_head *entry;
-
- /*
- * Write current work if it matches in sequence.
- */
- if (work->seq == rt->write_seq)
- goto write_it;
-
- pthread_mutex_lock(&rt->thread.lock);
-
- flist_add_tail(&work->list, &rt->done_list);
-
- /*
- * See if the next work item is here, if so, write it
- */
- work = NULL;
- flist_for_each(entry, &rt->done_list) {
- next = flist_entry(entry, struct work_item, list);
- if (next->seq == rt->write_seq) {
- work = next;
- flist_del(&work->list);
- break;
- }
- }
-
- pthread_mutex_unlock(&rt->thread.lock);
-
- if (work) {
-write_it:
- write_work(work);
- __sync_fetch_and_add(&rt->write_seq, 1);
- }
- }
-}
-
-static void *reader_one_off(void *data)
-{
- reader_work(data);
- return NULL;
-}
-
-static void *reader_fn(void *data)
-{
- struct reader_thread *rt = data;
- struct work_item *work;
-
- while (!rt->thread.exit || !flist_empty(&rt->list)) {
- work = NULL;
- pthread_mutex_lock(&rt->thread.lock);
- if (!flist_empty(&rt->list)) {
- work = flist_first_entry(&rt->list, struct work_item, list);
- flist_del_init(&work->list);
- } else
- pthread_cond_wait(&rt->thread.cond, &rt->thread.lock);
- pthread_mutex_unlock(&rt->thread.lock);
-
- if (work) {
- __sync_fetch_and_add(&rt->busy, 1);
- reader_work(work);
- __sync_fetch_and_sub(&rt->busy, 1);
- }
- }
-
- thread_exiting(&rt->thread);
- return NULL;
-}
-
-static void queue_work(struct reader_thread *rt, struct work_item *work)
-{
- if (!rt->started) {
- pthread_mutex_lock(&rt->thread.lock);
- flist_add_tail(&work->list, &rt->list);
- pthread_mutex_unlock(&rt->thread.lock);
-
- rt->started = 1;
- pthread_create(&rt->thread.thread, NULL, reader_fn, rt);
- } else if (!rt->busy && !pthread_mutex_trylock(&rt->thread.lock)) {
- flist_add_tail(&work->list, &rt->list);
- pthread_mutex_unlock(&rt->thread.lock);
-
- pthread_cond_signal(&rt->thread.cond);
- } else {
- int ret = pthread_create(&work->thread, NULL, reader_one_off, work);
- if (ret)
- fprintf(stderr, "pthread_create=%d\n", ret);
- else
- pthread_detach(work->thread);
- }
-}
-
-static unsigned int calc_percentiles(unsigned int *io_u_plat, unsigned long nr,
- unsigned int **output)
-{
- unsigned long sum = 0;
- unsigned int len, i, j = 0;
- unsigned int oval_len = 0;
- unsigned int *ovals = NULL;
- int is_last;
-
- len = 0;
- while (len < PLAT_LIST_MAX && plist[len] != 0.0)
- len++;
-
- if (!len)
- return 0;
-
- /*
- * Calculate bucket values, note down max and min values
- */
- is_last = 0;
- for (i = 0; i < PLAT_NR && !is_last; i++) {
- sum += io_u_plat[i];
- while (sum >= (plist[j] / 100.0 * nr)) {
- assert(plist[j] <= 100.0);
-
- if (j == oval_len) {
- oval_len += 100;
- ovals = realloc(ovals, oval_len * sizeof(unsigned int));
- }
-
- ovals[j] = plat_idx_to_val(i);
- is_last = (j == len - 1);
- if (is_last)
- break;
-
- j++;
- }
- }
-
- *output = ovals;
- return len;
-}
-
-static void show_latencies(struct stats *s, const char *msg)
-{
- unsigned int *ovals = NULL;
- unsigned int len, i;
-
- len = calc_percentiles(s->plat, s->nr_samples, &ovals);
- if (len) {
- fprintf(stderr, "Latency percentiles (usec) (%s)\n", msg);
- for (i = 0; i < len; i++)
- fprintf(stderr, "\t%2.4fth: %u\n", plist[i], ovals[i]);
- }
-
- if (ovals)
- free(ovals);
-
- fprintf(stderr, "\tOver=%u, min=%u, max=%u\n", s->over, s->min, s->max);
-}
-
-static void init_thread(struct thread_data *thread)
-{
- pthread_cond_init(&thread->cond, NULL);
- pthread_cond_init(&thread->done_cond, NULL);
- pthread_mutex_init(&thread->lock, NULL);
- pthread_mutex_init(&thread->done_lock, NULL);
- thread->exit = 0;
-}
-
-static void exit_thread(struct thread_data *thread,
- void fn(struct writer_thread *),
- struct writer_thread *wt)
-{
- __sync_fetch_and_add(&thread->exit, 1);
- pthread_cond_signal(&thread->cond);
-
- while (!thread->done) {
- pthread_mutex_lock(&thread->done_lock);
-
- if (fn) {
- struct timeval tv;
- struct timespec ts;
-
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + 1;
- ts.tv_nsec = tv.tv_usec * 1000ULL;
-
- pthread_cond_timedwait(&thread->done_cond, &thread->done_lock, &ts);
- fn(wt);
- } else
- pthread_cond_wait(&thread->done_cond, &thread->done_lock);
-
- pthread_mutex_unlock(&thread->done_lock);
- }
-}
-
-static int usage(char *argv[])
-{
- fprintf(stderr, "%s: [-b blocksize] [-t max usec] [-w separate writer] -f file\n", argv[0]);
- return 1;
-}
-
-static int parse_options(int argc, char *argv[])
-{
- int c;
-
- while ((c = getopt(argc, argv, "f:b:t:w:")) != -1) {
- switch (c) {
- case 'f':
- file = strdup(optarg);
- break;
- case 'b':
- bs = atoi(optarg);
- break;
- case 't':
- max_us = atoi(optarg);
- break;
- case 'w':
- separate_writer = atoi(optarg);
- if (!separate_writer)
- fprintf(stderr, "inline writing is broken\n");
- break;
- case '?':
- default:
- return usage(argv);
- }
- }
-
- if (!file)
- return usage(argv);
-
- return 0;
-}
-
-static void prune_done_entries(struct writer_thread *wt)
-{
- FLIST_HEAD(list);
-
- if (flist_empty(&wt->done_list))
- return;
-
- if (pthread_mutex_trylock(&wt->thread.lock))
- return;
-
- if (!flist_empty(&wt->done_list))
- flist_splice_init(&wt->done_list, &list);
- pthread_mutex_unlock(&wt->thread.lock);
-
- while (!flist_empty(&list)) {
- struct work_item *work;
-
- work = flist_first_entry(&list, struct work_item, list);
- flist_del(&work->list);
-
- pthread_cond_destroy(&work->cond);
- pthread_mutex_destroy(&work->lock);
- free(work->buf);
- free(work);
- }
-}
-
-int main(int argc, char *argv[])
-{
- struct timeval s, re, we;
- struct reader_thread *rt;
- struct writer_thread *wt;
- unsigned long rate;
- struct stat sb;
- size_t bytes;
- off_t off;
- int fd, seq;
-
- if (parse_options(argc, argv))
- return 1;
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- perror("open");
- return 2;
- }
-
- if (fstat(fd, &sb) < 0) {
- perror("stat");
- return 3;
- }
-
- wt = &writer_thread;
- init_thread(&wt->thread);
- INIT_FLIST_HEAD(&wt->list);
- INIT_FLIST_HEAD(&wt->done_list);
- wt->s.max = 0;
- wt->s.min = -1U;
- pthread_create(&wt->thread.thread, NULL, writer_fn, wt);
-
- rt = &reader_thread;
- init_thread(&rt->thread);
- INIT_FLIST_HEAD(&rt->list);
- INIT_FLIST_HEAD(&rt->done_list);
- rt->s.max = 0;
- rt->s.min = -1U;
- rt->write_seq = 1;
-
- off = 0;
- seq = 0;
- bytes = 0;
-
- gettimeofday(&s, NULL);
-
- while (sb.st_size) {
- struct work_item *work;
- size_t this_len;
- struct timespec ts;
- struct timeval tv;
-
- prune_done_entries(wt);
-
- this_len = sb.st_size;
- if (this_len > bs)
- this_len = bs;
-
- work = calloc(1, sizeof(*work));
- work->buf = malloc(this_len);
- work->buf_size = this_len;
- work->off = off;
- work->fd = fd;
- work->seq = ++seq;
- work->writer = wt;
- work->reader = rt;
- pthread_cond_init(&work->cond, NULL);
- pthread_mutex_init(&work->lock, NULL);
-
- queue_work(rt, work);
-
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000ULL;
- ts.tv_nsec += max_us * 1000ULL;
- if (ts.tv_nsec >= 1000000000ULL) {
- ts.tv_nsec -= 1000000000ULL;
- ts.tv_sec++;
- }
-
- pthread_mutex_lock(&work->lock);
- pthread_cond_timedwait(&work->cond, &work->lock, &ts);
- pthread_mutex_unlock(&work->lock);
-
- off += this_len;
- sb.st_size -= this_len;
- bytes += this_len;
- }
-
- exit_thread(&rt->thread, NULL, NULL);
- gettimeofday(&re, NULL);
-
- exit_thread(&wt->thread, prune_done_entries, wt);
- gettimeofday(&we, NULL);
-
- show_latencies(&rt->s, "READERS");
- show_latencies(&wt->s, "WRITERS");
-
- bytes /= 1024;
- rate = (bytes * 1000UL * 1000UL) / utime_since(&s, &re);
- fprintf(stderr, "Read rate (KiB/sec) : %lu\n", rate);
- rate = (bytes * 1000UL * 1000UL) / utime_since(&s, &we);
- fprintf(stderr, "Write rate (KiB/sec): %lu\n", rate);
-
- close(fd);
- return 0;
-}
diff --git a/t/stest.c b/t/stest.c
deleted file mode 100644
index 04df60dc..00000000
--- a/t/stest.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "../smalloc.h"
-#include "../flist.h"
-#include "../arch/arch.h"
-#include "debug.h"
-
-#define MAGIC1 0xa9b1c8d2
-#define MAGIC2 0xf0a1e9b3
-
-#define LOOPS 32
-
-struct elem {
- unsigned int magic1;
- struct flist_head list;
- unsigned int magic2;
-};
-
-FLIST_HEAD(list);
-
-static int do_rand_allocs(void)
-{
- unsigned int size, nr, rounds = 0;
- unsigned long total;
- struct elem *e;
-
- while (rounds++ < LOOPS) {
-#ifdef STEST_SEED
- srand(MAGIC1);
-#endif
- nr = total = 0;
- while (total < 120*1024*1024UL) {
- size = 8 * sizeof(struct elem) + (int) (999.0 * (rand() / (RAND_MAX + 1.0)));
- e = smalloc(size);
- if (!e) {
- printf("fail at %lu, size %u\n", total, size);
- break;
- }
- e->magic1 = MAGIC1;
- e->magic2 = MAGIC2;
- total += size;
- flist_add_tail(&e->list, &list);
- nr++;
- }
-
- printf("Got items: %u\n", nr);
-
- while (!flist_empty(&list)) {
- e = flist_entry(list.next, struct elem, list);
- assert(e->magic1 == MAGIC1);
- assert(e->magic2 == MAGIC2);
- flist_del(&e->list);
- sfree(e);
- }
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- arch_init(argv);
- sinit();
- debug_init();
-
- do_rand_allocs();
-
- scleanup();
- return 0;
-}
diff --git a/t/verify-state.c b/t/verify-state.c
deleted file mode 100644
index 9a2c3df6..00000000
--- a/t/verify-state.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Dump the contents of a verify state file in plain text
- */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include "../log.h"
-#include "../os/os.h"
-#include "../verify-state.h"
-#include "../crc/crc32c.h"
-#include "debug.h"
-
-static void show_s(struct thread_io_list *s, unsigned int no_s)
-{
- int i;
-
- printf("Thread:\t\t%u\n", no_s);
- printf("Name:\t\t%s\n", s->name);
- printf("Completions:\t%llu\n", (unsigned long long) s->no_comps);
- printf("Depth:\t\t%llu\n", (unsigned long long) s->depth);
- printf("Number IOs:\t%llu\n", (unsigned long long) s->numberio);
- printf("Index:\t\t%llu\n", (unsigned long long) s->index);
-
- printf("Completions:\n");
- if (!s->no_comps)
- return;
- for (i = s->no_comps - 1; i >= 0; i--) {
- printf("\t(file=%2llu) %llu\n",
- (unsigned long long) s->comps[i].fileno,
- (unsigned long long) s->comps[i].offset);
- }
-}
-
-static void show(struct thread_io_list *s, size_t size)
-{
- int no_s;
-
- no_s = 0;
- do {
- int i;
-
- s->no_comps = le64_to_cpu(s->no_comps);
- s->depth = le32_to_cpu(s->depth);
- s->nofiles = le32_to_cpu(s->nofiles);
- s->numberio = le64_to_cpu(s->numberio);
- s->index = le64_to_cpu(s->index);
-
- for (i = 0; i < s->no_comps; i++) {
- s->comps[i].fileno = le64_to_cpu(s->comps[i].fileno);
- s->comps[i].offset = le64_to_cpu(s->comps[i].offset);
- }
-
- show_s(s, no_s);
- no_s++;
- size -= __thread_io_list_sz(s->depth, s->nofiles);
- s = (void *) s + __thread_io_list_sz(s->depth, s->nofiles);
- } while (size != 0);
-}
-
-static void show_verify_state(void *buf, size_t size)
-{
- struct verify_state_hdr *hdr = buf;
- struct thread_io_list *s;
- uint32_t crc;
-
- hdr->version = le64_to_cpu(hdr->version);
- hdr->size = le64_to_cpu(hdr->size);
- hdr->crc = le64_to_cpu(hdr->crc);
-
- printf("Version:\t0x%x\n", (unsigned int) hdr->version);
- printf("Size:\t\t%u\n", (unsigned int) hdr->size);
- printf("CRC:\t\t0x%x\n", (unsigned int) hdr->crc);
-
- size -= sizeof(*hdr);
- if (hdr->size != size) {
- log_err("Size mismatch\n");
- return;
- }
-
- s = buf + sizeof(*hdr);
- crc = fio_crc32c((unsigned char *) s, hdr->size);
- if (crc != hdr->crc) {
- log_err("crc mismatch %x != %x\n", crc, (unsigned int) hdr->crc);
- return;
- }
-
- if (hdr->version == 0x03)
- show(s, size);
- else
- log_err("Unsupported version %d\n", (int) hdr->version);
-}
-
-static int show_file(const char *file)
-{
- struct stat sb;
- void *buf;
- int ret, fd;
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- log_err("open %s: %s\n", file, strerror(errno));
- return 1;
- }
-
- if (fstat(fd, &sb) < 0) {
- log_err("stat: %s\n", strerror(errno));
- close(fd);
- return 1;
- }
-
- buf = malloc(sb.st_size);
- ret = read(fd, buf, sb.st_size);
- if (ret < 0) {
- log_err("read: %s\n", strerror(errno));
- close(fd);
- return 1;
- } else if (ret != sb.st_size) {
- log_err("Short read\n");
- close(fd);
- return 1;
- }
-
- close(fd);
- show_verify_state(buf, sb.st_size);
-
- free(buf);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int i, ret;
-
- debug_init();
-
- if (argc < 2) {
- log_err("Usage: %s <state file>\n", argv[0]);
- return 1;
- }
-
- ret = 0;
- for (i = 1; i < argc; i++) {
- ret = show_file(argv[i]);
- if (ret)
- break;
- }
-
- return ret;
-}