unsigned long long utime_since_now(struct timeval *s) { struct timeval t; fio_gettime(&t, NULL); return utime_since(s, &t); }
static void account_io_completion(struct thread_data *td, struct io_u *io_u, struct io_completion_data *icd, const enum fio_ddir idx, unsigned int bytes) { unsigned long lusec = 0; if (!gtod_reduce(td)) lusec = utime_since(&io_u->issue_time, &icd->time); if (!td->o.disable_lat) { unsigned long tusec; tusec = utime_since(&io_u->start_time, &icd->time); add_lat_sample(td, idx, tusec, bytes); if (td->flags & TD_F_PROFILE_OPS) { struct prof_io_ops *ops = &td->prof_io_ops; if (ops->io_u_lat) icd->error = ops->io_u_lat(td, tusec); } if (td->o.max_latency && tusec > td->o.max_latency) lat_fatal(td, icd, tusec, td->o.max_latency); if (td->o.latency_target && tusec > td->o.latency_target) { if (lat_target_failed(td)) lat_fatal(td, icd, tusec, td->o.latency_target); } } if (!td->o.disable_clat) { add_clat_sample(td, idx, lusec, bytes); io_u_mark_latency(td, lusec); } if (!td->o.disable_bw) add_bw_sample(td, idx, bytes, &icd->time); if (!gtod_reduce(td)) add_iops_sample(td, idx, bytes, &icd->time); if (td->o.number_ios && !--td->o.number_ios) td->done = 1; }
void fio_idle_prof_stop(void) { int i; uint64_t runt; struct timeval tp; struct timespec ts; struct idle_prof_thread *ipt; if (ipc.opt == IDLE_PROF_OPT_NONE) return; if (ipc.opt == IDLE_PROF_OPT_CALI) return; ipc.status = IDLE_PROF_STATUS_PROF_STOP; /* wait for all threads to exit from profiling */ for (i = 0; i < ipc.nr_cpus; i++) { ipt = &ipc.ipts[i]; pthread_mutex_lock(&ipt->start_lock); while ((ipt->state != TD_EXITED) && (ipt->state!=TD_NOT_CREATED)) { fio_gettime(&tp, NULL); ts.tv_sec = tp.tv_sec + 1; ts.tv_nsec = tp.tv_usec * 1000; /* timed wait in case a signal is not received */ pthread_cond_timedwait(&ipt->cond, &ipt->start_lock, &ts); } pthread_mutex_unlock(&ipt->start_lock); /* calculate idleness */ if (ipc.cali_mean != 0.0) { runt = utime_since(&ipt->tps, &ipt->tpe); if (runt) ipt->idleness = ipt->loops * ipc.cali_mean / runt; else ipt->idleness = 0.0; } else ipt->idleness = 0.0; } /* * memory allocations are freed via explicit fio_idle_prof_cleanup * after profiling stats are collected by apps. */ }
int ramp_time_over(struct thread_data *td) { struct timeval tv; if (!td->o.ramp_time || td->ramp_time_over) return 1; fio_gettime(&tv, NULL); if (utime_since(&td->epoch, &tv) >= td->o.ramp_time) { td->ramp_time_over = 1; reset_all_stats(td); td_set_runstate(td, TD_RAMP); return 1; } return 0; }
/* * Called to complete min_events number of io for the async engines. */ int io_u_queued_complete(struct thread_data *td, int min_evts, uint64_t *bytes) { struct io_completion_data icd; struct timespec *tvp = NULL; int ret; struct timespec ts = { .tv_sec = 0, .tv_nsec = 0, }; dprint(FD_IO, "io_u_queued_completed: min=%d\n", min_evts); if (!min_evts) tvp = &ts; ret = td_io_getevents(td, min_evts, td->o.iodepth_batch_complete, tvp); if (ret < 0) { td_verror(td, -ret, "td_io_getevents"); return ret; } else if (!ret) return ret; init_icd(td, &icd, ret); ios_completed(td, &icd); if (icd.error) { td_verror(td, icd.error, "io_u_queued_complete"); return -1; } if (bytes) { int ddir; for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++) bytes[ddir] += icd.bytes_done[ddir]; } return 0; } /* * Call when io_u is really queued, to update the submission latency. */ void io_u_queued(struct thread_data *td, struct io_u *io_u) { if (!td->o.disable_slat) { unsigned long slat_time; slat_time = utime_since(&io_u->start_time, &io_u->issue_time); add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen); } } void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write, unsigned int max_bs) { if (td->o.buffer_pattern_bytes) fill_buffer_pattern(td, buf, max_bs); else if (!td->o.zero_buffers) { unsigned int perc = td->o.compress_percentage; if (perc) { unsigned int seg = min_write; seg = min(min_write, td->o.compress_chunk); if (!seg) seg = min_write; fill_random_buf_percentage(&td->buf_state, buf, perc, seg, max_bs); } else fill_random_buf(&td->buf_state, buf, max_bs); } else memset(buf, 0, max_bs); } /* * "randomly" fill the buffer contents */ void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u, unsigned int min_write, unsigned int max_bs) { io_u->buf_filled_len = 0; fill_io_buffer(td, io_u->buf, min_write, max_bs); }
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; /* 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 KBs\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; }
static void io_completed(struct thread_data *td, struct io_u *io_u, struct io_completion_data *icd) { struct fio_file *f; dprint_io_u(io_u, "io complete"); td_io_u_lock(td); assert(io_u->flags & IO_U_F_FLIGHT); io_u->flags &= ~(IO_U_F_FLIGHT | IO_U_F_BUSY_OK); td_io_u_unlock(td); if (ddir_sync(io_u->ddir)) { td->last_was_sync = 1; f = io_u->file; if (f) { f->first_write = -1ULL; f->last_write = -1ULL; } return; } td->last_was_sync = 0; td->last_ddir = io_u->ddir; if (!io_u->error && ddir_rw(io_u->ddir)) { unsigned int bytes = io_u->buflen - io_u->resid; const enum fio_ddir idx = io_u->ddir; const enum fio_ddir odx = io_u->ddir ^ 1; int ret; td->io_blocks[idx]++; td->this_io_blocks[idx]++; td->io_bytes[idx] += bytes; if (!(io_u->flags & IO_U_F_VER_LIST)) td->this_io_bytes[idx] += bytes; if (idx == DDIR_WRITE) { f = io_u->file; if (f) { if (f->first_write == -1ULL || io_u->offset < f->first_write) f->first_write = io_u->offset; if (f->last_write == -1ULL || ((io_u->offset + bytes) > f->last_write)) f->last_write = io_u->offset + bytes; } } if (ramp_time_over(td) && (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING)) { account_io_completion(td, io_u, icd, idx, bytes); if (__should_check_rate(td, idx)) { td->rate_pending_usleep[idx] = (usec_for_io(td, idx) - utime_since_now(&td->start)); } if (__should_check_latency(td, idx)) { unsigned long lusec = utime_since( &io_u->issue_time, &icd->time); /* Linear increase and logarithmic decrease */ if (lusec > td->o.shed_latency[idx]) { if (td->shed_count[idx] < MAX_SHED_COUNT ) { td->shed_count[idx] += (1<<SHED_FRAC_BITS); } } else if (td->shed_count[idx]) { td->shed_count[idx] -= get_used_bits(td->shed_count[idx]); } if (td->shed_count[idx]) { lusec = (lusec * td->shed_count[idx]) >> SHED_FRAC_BITS; if (lusec > td->rate_pending_usleep[idx]) { td->rate_pending_usleep[idx] = lusec; } } }