| 120 | }; |
| 121 | |
| 122 | void * worker(void *voidargs) |
| 123 | { |
| 124 | uint8_t *buf = (uint8_t *)malloc(4096); |
| 125 | struct worker_args *args = (struct worker_args*)voidargs; |
| 126 | struct timeval ts_begin, ts_cur, ts_gap; |
| 127 | |
| 128 | ssize_t ret; |
| 129 | bid_t bid; |
| 130 | uint32_t crc, crc_file; |
| 131 | uint64_t i, c, run_count=0; |
| 132 | TEST_INIT(); |
| 133 | |
| 134 | memset(buf, 0, 4096); |
| 135 | gettimeofday(&ts_begin, NULL); |
| 136 | |
| 137 | while(1) { |
| 138 | bid = rand() % args->nblocks; |
| 139 | ret = bcache_read(args->file, bid, buf); |
| 140 | if (ret <= 0) { |
| 141 | ret = args->file->ops->pread(args->file->fd, buf, |
| 142 | args->file->blocksize, bid * args->file->blocksize); |
| 143 | TEST_CHK(ret == args->file->blocksize); |
| 144 | ret = bcache_write(args->file, bid, buf, BCACHE_REQ_CLEAN, false); |
| 145 | TEST_CHK(ret == args->file->blocksize); |
| 146 | } |
| 147 | crc_file = crc32_8(buf, sizeof(uint64_t)*2, 0); |
| 148 | (void)crc_file; |
| 149 | memcpy(&i, buf, sizeof(i)); |
| 150 | memcpy(&crc, buf + sizeof(uint64_t)*2, sizeof(crc)); |
| 151 | // Disable checking the CRC value at this time as pread and pwrite are |
| 152 | // not thread-safe. |
| 153 | // TEST_CHK(crc == crc_file && i==bid); |
| 154 | //DBG("%d %d %d %x %x\n", (int)args->n, (int)i, (int)bid, (int)crc, (int)crc_file); |
| 155 | |
| 156 | if (args->writer) { |
| 157 | memcpy(&c, buf+sizeof(i), sizeof(c)); |
| 158 | c++; |
| 159 | memcpy(buf+sizeof(i), &c, sizeof(c)); |
| 160 | crc = crc32_8(buf, sizeof(uint64_t)*2, 0); |
| 161 | memcpy(buf + sizeof(uint64_t)*2, &crc, sizeof(crc)); |
| 162 | |
| 163 | ret = bcache_write(args->file, bid, buf, BCACHE_REQ_DIRTY, true); |
| 164 | TEST_CHK(ret == args->file->blocksize); |
| 165 | } else { // have some of the reader threads flush dirty immutable blocks |
| 166 | if (bid <= args->nblocks / 4) { // 25% probability |
| 167 | filemgr_flush_immutable(args->file, NULL); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | gettimeofday(&ts_cur, NULL); |
| 172 | ts_gap = _utime_gap(ts_begin, ts_cur); |
| 173 | if ((size_t)ts_gap.tv_sec >= args->time_sec) break; |
| 174 | |
| 175 | run_count++; |
| 176 | } |
| 177 | |
| 178 | free(buf); |
| 179 | thread_exit(0); |
nothing calls this directly
no test coverage detected