//------------------------------------------------ // Runs in every device large-block read thread, // executes large-block reads at a constant rate. // static void* run_large_block_reads(void* pv_device) { device* p_device = (device*)pv_device; uint64_t count = 0; while (g_running) { read_and_report_large_block(p_device); count++; int sleep_ms = (int) (((count * 1000 * g_num_devices) / g_large_block_ops_per_sec) - (cf_getms() - g_run_start_ms)); if (sleep_ms > 0) { usleep((uint32_t)sleep_ms * 1000); } } return (0); }
//------------------------------------------------ // Runs in every device large-block read thread, // executes large-block reads at a constant rate. // static void* run_large_block_reads(void* pv_device) { device* p_device = (device*)pv_device; uint64_t count = 0; while (g_running) { read_and_report_large_block(p_device); count++; int sleep_us = (int) (((count * 1000000 * g_num_devices) / g_large_block_ops_per_sec) - (cf_getus() - g_run_start_us)); if (sleep_us > 0) { usleep((uint32_t)sleep_us); } if (sleep_us != 0) { fprintf(stdout, "%" PRIu64 ", sleep_us = %d\n", count, sleep_us); } } return (0); }
//------------------------------------------------ // Runs in service threads, adds read trans_req // objects to transaction queues in round-robin // fashion. // static void* run_generate_read_reqs(void* pv_unused) { rand_seed_thread(); uint64_t count = 0; uint64_t internal_read_reqs_per_sec = g_scfg.internal_read_reqs_per_sec / g_scfg.read_req_threads; while (g_running) { if (atomic32_incr(&g_reqs_queued) > g_scfg.max_reqs_queued) { fprintf(stdout, "ERROR: too many requests queued\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; break; } uint32_t q_index = count % g_scfg.num_queues; uint32_t random_dev_index = rand_32() % g_scfg.num_devices; device* random_dev = &g_devices[random_dev_index]; trans_req read_req = { .dev = random_dev, .offset = random_read_offset(random_dev), .size = random_read_size(random_dev), .is_write = false, .start_time = get_ns() }; queue_push(g_trans_qs[q_index], &read_req); count++; int64_t sleep_us = (int64_t) (((count * 1000000) / internal_read_reqs_per_sec) - (get_us() - g_run_start_us)); if (sleep_us > 0) { usleep((uint32_t)sleep_us); } else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) { fprintf(stdout, "ERROR: read request generator can't keep up\n"); fprintf(stdout, "ACT can't do requested load - test stopped\n"); g_running = false; } } return NULL; } //------------------------------------------------ // Runs in service threads, adds write trans_req // objects to transaction queues in round-robin // fashion. // static void* run_generate_write_reqs(void* pv_unused) { rand_seed_thread(); uint64_t count = 0; uint64_t internal_write_reqs_per_sec = g_scfg.internal_write_reqs_per_sec / g_scfg.write_req_threads; while (g_running) { if (atomic32_incr(&g_reqs_queued) > g_scfg.max_reqs_queued) { fprintf(stdout, "ERROR: too many requests queued\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; break; } uint32_t q_index = count % g_scfg.num_queues; uint32_t random_dev_index = rand_32() % g_scfg.num_devices; device* random_dev = &g_devices[random_dev_index]; trans_req write_req = { .dev = random_dev, .offset = random_write_offset(random_dev), .size = random_write_size(random_dev), .is_write = true, .start_time = get_ns() }; queue_push(g_trans_qs[q_index], &write_req); count++; int64_t sleep_us = (int64_t) (((count * 1000000) / internal_write_reqs_per_sec) - (get_us() - g_run_start_us)); if (sleep_us > 0) { usleep((uint32_t)sleep_us); } else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) { fprintf(stdout, "ERROR: write request generator can't keep up\n"); fprintf(stdout, "ACT can't do requested load - test stopped\n"); g_running = false; } } return NULL; } //------------------------------------------------ // Runs in every device large-block read thread, // executes large-block reads at a constant rate. // static void* run_large_block_reads(void* pv_dev) { rand_seed_thread(); device* dev = (device*)pv_dev; uint8_t* buf = act_valloc(g_scfg.large_block_ops_bytes); if (! buf) { fprintf(stdout, "ERROR: large block read buffer act_valloc()\n"); g_running = false; return NULL; } uint64_t count = 0; while (g_running) { read_and_report_large_block(dev, buf); count++; uint64_t target_us = (uint64_t) ((double)(count * 1000000 * g_scfg.num_devices) / g_scfg.large_block_reads_per_sec); int64_t sleep_us = (int64_t)(target_us - (get_us() - g_run_start_us)); if (sleep_us > 0) { usleep((uint32_t)sleep_us); } else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) { fprintf(stdout, "ERROR: large block reads can't keep up\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; } } free(buf); return NULL; }