void * rw4k_thread(void *p) { struct RR *rr = (typeof(rr))p; uint8_t * const buf = alloc_buf(rr); uint64_t cap = 0; ioctl(rr->fd, BLKGETSIZE64, &cap); if (cap == 0) { cap = lseek(rr->fd, 0, SEEK_END); } assert(cap); cap = (rr->perc * (double)cap); setup_affinity(rr); const uint64_t start = debug_time_usec(); const uint64_t dur = rr->duration_sec * 1000000; uint64_t count = 0; const uint64_t round = 10; for (;;) { for (uint64_t i = 0; i < round; i++) { do_random_rw(rr->fd, rr->mask, buf, rr->write, cap); } count += round; if (debug_time_usec() - start > dur) break; } // record rr->nr_io = count; free(buf); pthread_exit(NULL); }
static inline ssize_t do_random_rw(const int fd, const size_t mask, uint8_t * const buf, const bool is_write, const uint64_t cap) { const size_t size = (mask + 1u); const off_t off = (random_uint64() % (cap - size)) & (~mask); const uint64_t t0 = debug_time_usec(); const ssize_t r = is_write?pwrite(fd, buf, size, off):pread(fd, buf, size, off); assert((typeof(size))r == size); const uint64_t dt = debug_diff_usec(t0); latency_record(dt, latency); return r; }
uint64_t debug_diff_usec(const uint64_t last) { return debug_time_usec() - last; }
double debug_time_sec(void) { const uint64_t usec = debug_time_usec(); return ((double)usec) / 1000000.0; }