//------------------------------------------------ // Runs in thr_add_readreqs, adds readreq objects // to all read queues in an even, random spread. // static void* run_add_readreqs(void* pv_unused) { uint64_t count = 0; while (g_running) { if (cf_atomic_int_incr(&g_read_reqs_queued) > MAX_READ_REQS_QUEUED) { fprintf(stdout, "ERROR: too many read reqs queued\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; break; } uint32_t random_queue_index = rand_32() % g_num_queues; uint32_t random_device_index = g_queue_per_device ? random_queue_index : rand_32() % g_num_devices; device* p_random_device = &g_devices[random_device_index]; readreq* p_readreq = malloc(sizeof(readreq)); p_readreq->p_device = p_random_device; p_readreq->offset = random_read_offset(p_random_device); p_readreq->size = g_read_req_num_512_blocks * MIN_BLOCK_BYTES; p_readreq->start_time = cf_getus(); cf_queue_push(g_readqs[random_queue_index].p_req_queue, &p_readreq); count++; int sleep_us = (int) (((count * 1000000) / g_read_reqs_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); }
static void* generate_async_reads(void* aio_context) { uint64_t count = 0; while(g_running) { /* Create the struct of info needed at the process_read end */ uintptr_t info_ptr; if (cf_queue_pop(async_info_queue, (void*)&info_ptr, CF_QUEUE_NOWAIT) != CF_QUEUE_OK) { fprintf(stdout, "Error: Could not pop info struct \n"); return (void*)(-1); } as_async_info_t *info = (as_async_info_t*)info_ptr; memset(info, 0, sizeof(as_async_info_t)); /* Generate the actual read request */ uint32_t random_device_index = rand_32() % g_num_devices; device* p_random_device = &g_devices[random_device_index]; readreq* p_readreq = &(info->p_readreq); if(p_readreq == NULL) { fprintf(stdout, "Error: preadreq null \n"); goto fail; } p_readreq->p_device = p_random_device; p_readreq->offset = random_read_offset(p_random_device); p_readreq->size = g_read_req_num_512_blocks * MIN_BLOCK_BYTES; p_readreq->start_time = cf_getms(); /* Async read */ if (g_use_valloc) { uint8_t* p_buffer = cf_valloc(p_readreq->size); info->p_buffer = p_buffer; if (p_buffer) { uint64_t raw_start_time = cf_getms(); info->raw_start_time = raw_start_time; if(read_async_from_device(info, *(aio_context_t *)aio_context) < 0) { fprintf(stdout, "Error: Async read failed \n"); free(p_buffer); goto fail; } } else { fprintf(stdout, "ERROR: read buffer cf_valloc()\n"); } } else { uint8_t stack_buffer[p_readreq->size + 4096]; uint8_t* p_buffer = align_4096(stack_buffer); info->p_buffer = p_buffer; uint64_t raw_start_time = cf_getms(); info->raw_start_time = raw_start_time; if(read_async_from_device(info, *(aio_context_t*)aio_context) < 0) { fprintf(stdout, "Error: Async read failed \n"); goto fail; } } if (cf_atomic_int_incr(&g_read_reqs_queued) > MAX_READ_REQS_QUEUED) { fprintf(stdout, "ERROR: too many read reqs queued\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; return (void*)-1;; } count++; int sleep_ms = (int) (((count * 1000) / g_read_reqs_per_sec) - (cf_getms() - g_run_start_ms)); if (sleep_ms > 0) { usleep((uint32_t)sleep_ms * 1000); } continue; /* Rollback for failure */ fail: if(info) { uintptr_t temp = (uintptr_t)info; cf_queue_push(async_info_queue, (void*)&temp); } } return (0); }