static int do_child(int i) { long long elapsed_ms; if (tst_process_state_wait2(getppid(), 'S') != 0) { tst_brkm(TBROK | TERRNO, NULL, "failed to wait for parent process's state"); } tst_timer_start(CLOCK_MONOTONIC); switch (test_cases[i].op_type) { case OP_OPEN_RDONLY: SAFE_OPEN(NULL, "file", O_RDONLY); break; case OP_OPEN_WRONLY: SAFE_OPEN(NULL, "file", O_WRONLY); break; case OP_OPEN_RDWR: SAFE_OPEN(NULL, "file", O_RDWR); break; case OP_TRUNCATE: SAFE_TRUNCATE(NULL, "file", 0); break; default: break; } tst_timer_stop(); elapsed_ms = tst_timer_elapsed_ms(); if (elapsed_ms < MIN_TIME_LIMIT * 1000) { tst_resm(TPASS, "%s, unblocked within %ds", test_cases[i].desc, MIN_TIME_LIMIT); } else { tst_resm(TFAIL, "%s, blocked too long %llims, " "expected within %ds", test_cases[i].desc, elapsed_ms, MIN_TIME_LIMIT); } tst_exit(); }
/* read_testfile - mmap testfile and read every page. * This functions measures how many I/O and time it takes to fully * read contents of test file. * * @do_readahead: call readahead prior to reading file content? * @fname: name of file to test * @fsize: how many bytes to read/mmap * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io * @usec: returns how many microsecond it took to go over fsize bytes * @cached: returns cached kB from /proc/meminfo */ static int read_testfile(struct tcase *tc, int do_readahead, const char *fname, size_t fsize, unsigned long *read_bytes, long long *usec, unsigned long *cached) { int fd; size_t i = 0; long read_bytes_start; unsigned char *p, tmp; off_t offset = 0; fd = SAFE_OPEN(fname, O_RDONLY); if (do_readahead) { do { TEST(tc->readahead(fd, offset, fsize - offset)); if (TST_RET != 0) { SAFE_CLOSE(fd); return TST_ERR; } i++; offset += readahead_length; } while ((size_t)offset < fsize); tst_res(TINFO, "readahead calls made: %zu", i); *cached = get_cached_size(); /* offset of file shouldn't change after readahead */ offset = SAFE_LSEEK(fd, 0, SEEK_CUR); if (offset == 0) tst_res(TPASS, "offset is still at 0 as expected"); else tst_res(TFAIL, "offset has changed to: %lu", offset); } tst_timer_start(CLOCK_MONOTONIC); read_bytes_start = get_bytes_read(); p = SAFE_MMAP(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ tmp = 0; for (i = 0; i < fsize; i += pagesize) tmp = tmp ^ p[i]; /* prevent gcc from optimizing out loop above */ if (tmp != 0) tst_brk(TBROK, "This line should not be reached"); if (!do_readahead) *cached = get_cached_size(); SAFE_MUNMAP(p, fsize); *read_bytes = get_bytes_read() - read_bytes_start; tst_timer_stop(); *usec = tst_timer_elapsed_us(); SAFE_CLOSE(fd); return 0; }