uint32_t test_ecc_proj_coords_add(bn_uint_t *ax, bn_uint_t *ay, bn_uint_t *bx, bn_uint_t *by, bn_uint_t *expx, bn_uint_t *expy, ecc_curve_t *curve) { BN_CREATE_VARIABLE(px, ax->length); BN_CREATE_VARIABLE(py, ay->length); BN_CREATE_VARIABLE(pz, ay->length); BN_CREATE_VARIABLE(qx, ax->length); BN_CREATE_VARIABLE(qy, ay->length); BN_CREATE_VARIABLE(qz, ay->length); BN_CREATE_VARIABLE(ox, ax->length); BN_CREATE_VARIABLE(oy, ay->length); BN_CREATE_VARIABLE(oz, ay->length); BN_CREATE_VARIABLE(counted_ay, ay->length); BN_CREATE_VARIABLE(counted_ax, ax->length); start_count_time(); eccutils_affine_to_projective(ax, ay, &px, &py, &pz, curve); eccutils_affine_to_projective(bx, by, &qx, &qy, &qz, curve); ecc_proj_ec_add(&px, &py, &pz, &qx, &qy, &qz, &ox, &oy, &oz, curve); eccutils_projective_to_affine(&ox, &oy, &oz, &counted_ax, &counted_ay, curve); stop_count_time(); info("ecc_proj_add_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if ((bn_compare(&counted_ax, expx) == 0) && (bn_compare(&counted_ay, expy) == 0)) return 0; return 1; }
uint32_t test_tinydtls_ecdh(bn_uint_t *d_alice, bn_uint_t *pubx_alice, bn_uint_t *puby_alice, bn_uint_t *d_bob, bn_uint_t *pubx_bob, bn_uint_t *puby_bob, ecc_curve_t *curve) { (void)(curve); uint32_t tempAx2[8]; uint32_t tempAy2[8]; uint32_t tempBx2[8]; uint32_t tempBy2[8]; start_count_time(); tecc_ec_mult(pubx_bob->number, puby_bob->number, d_alice->number, tempAx2, tempAy2); tecc_ec_mult(pubx_alice->number, puby_alice->number, d_bob->number, tempBx2, tempBy2); stop_count_time(); info("ecc_tinydtls_ECDH_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); uint32_t i, result = 1; for(i = 0; i < 8; ++i){ result &= (tempAx2[i] == tempBx2[i]); result &= (tempAy2[i] == tempBy2[i]); } if (result == 1) return 0; return 1; }
uint32_t test_ecdsa_proj_sig_val_sig(ecc_curve_t *curve) { uint32_t res; BN_CREATE_VARIABLE(d, curve->p->length); BN_CREATE_VARIABLE(k, curve->p->length); BN_CREATE_VARIABLE(r, curve->p->length); BN_CREATE_VARIABLE(s, curve->p->length); BN_CREATE_VARIABLE(hash, curve->p->length); BN_CREATE_VARIABLE(pubx, curve->p->length); BN_CREATE_VARIABLE(puby, curve->p->length); start_count_time(); default_prgn(&k); default_prgn(&hash); ecc_generate_key(&default_prgn, &d, &pubx, &puby, curve); res = ecc_proj_ECDSA_signature_gen(&k, &hash, &d, &r, &s, curve); res = ecc_proj_ECDSA_signature_val(&r, &s, &hash, &pubx, &puby, curve); stop_count_time(); info("ecc_proj_ECDSA_gen_val_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if (res == 0) return 0; return 1; }
uint32_t test_ecdsa_tinydtls_val_sig(bn_uint_t *r, bn_uint_t *s, bn_uint_t *hash, bn_uint_t *pub_k_x, bn_uint_t *pub_k_y, ecc_curve_t *curve) { (void)(curve); uint32_t res; start_count_time(); res = tecc_ecdsa_validate(pub_k_x->number, pub_k_y->number, hash->number, r->number, s->number); stop_count_time(); info("ecc_tinydtls_ECDSA_val_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); return res; }
uint32_t test_ecdsa_proj_val_sig(bn_uint_t *r, bn_uint_t *s, bn_uint_t *hash, bn_uint_t *pub_k_x, bn_uint_t *pub_k_y, ecc_curve_t *curve) { uint32_t res; start_count_time(); res = ecc_proj_ECDSA_signature_val(r, s, hash, pub_k_x, pub_k_y, curve); stop_count_time(); info("ecc_proj_ECDSA_val_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if (res == 0) return 0; return 1; }
uint32_t test_ecdsa_proj_gen_sig(bn_uint_t *k, bn_uint_t *hash, bn_uint_t *d, bn_uint_t *expr, bn_uint_t *exps, ecc_curve_t *curve) { BN_CREATE_VARIABLE(r, expr->length); BN_CREATE_VARIABLE(s, exps->length); uint32_t res; start_count_time(); res = ecc_proj_ECDSA_signature_gen(k, hash, d, &r, &s, curve); stop_count_time(); info("ecc_proj_ECDSA_gen_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if ((bn_compare(&r, expr) == 0) && (bn_compare(&s, exps) == 0) && (res == 0)) return 0; return 1; }
uint32_t test_gen_proj_tinydtls_key(bn_uint_t *d, bn_uint_t *exp_pub_k_x, bn_uint_t *exp_pub_k_y, ecc_curve_t *curve) { (void)(curve); BN_CREATE_VARIABLE(pubx, exp_pub_k_x->length); BN_CREATE_VARIABLE(puby, exp_pub_k_y->length); start_count_time(); tecc_gen_pub_key(d->number, pubx.number, puby.number); stop_count_time(); info("ecc_tinydtls_keygen_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if ((bn_compare(&pubx, exp_pub_k_x) == 0) && (bn_compare(&puby, exp_pub_k_y) == 0)) return 0; return 1; }
uint32_t test_ecdsa_tinydtls_gen_sig(bn_uint_t *k, bn_uint_t *hash, bn_uint_t *d, bn_uint_t *expr, bn_uint_t *exps, ecc_curve_t *curve) { (void)(curve); BN_CREATE_VARIABLE(r, expr->length); BN_CREATE_VARIABLE(s, exps->length); uint32_t res; start_count_time(); res = tecc_ecdsa_sign(d->number, hash->number, k->number, r.number, s.number); stop_count_time(); info("ecc_tinydtls_ECDSA_gen_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if ((bn_compare(&r, expr) == 0) && (bn_compare(&s, exps) == 0) && (res == 0)) return 0; return 1; }
//------------------------------------------------ // Runs in every device large-block write thread, // executes large-block writes at a constant rate. // static void* run_large_block_writes(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 write buffer act_valloc()\n"); g_running = false; return NULL; } uint64_t count = 0; while (g_running) { write_and_report_large_block(dev, buf, count); count++; uint64_t target_us = (uint64_t) ((double)(count * 1000000 * g_scfg.num_devices) / g_scfg.large_block_writes_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 writes can't keep up\n"); fprintf(stdout, "drive(s) can't keep up - test stopped\n"); g_running = false; } } free(buf); return NULL; }
uint32_t test_ecdsa_tinydtls_sig_val_sig(ecc_curve_t *curve) { (void)(curve); uint32_t res = 0; BN_CREATE_VARIABLE(priv_key, 8); BN_CREATE_VARIABLE(k, 8); uint32_t pubx[8]; uint32_t puby[8]; uint32_t hash[8]; uint32_t r[9]; uint32_t s[9]; start_count_time(); default_prgn(&priv_key); default_prgn(&k); tecc_gen_pub_key(priv_key.number, pubx, puby); res |= tecc_ecdsa_sign(priv_key.number, hash, k.number, r, s); res |= tecc_ecdsa_validate(pubx, puby, hash, r, s); stop_count_time(); info("ecc_tinydtls_ECDSA_gen_val_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); return res; }
{ BN_CREATE_VARIABLE(dtmp, d->length); void prgn(bn_uint_t *output) { bn_copy(d, output, output->length); } BN_CREATE_VARIABLE(pubx, exp_pub_k_x->length); BN_CREATE_VARIABLE(puby, exp_pub_k_y->length); start_count_time(); ecc_proj_generate_key(&prgn, &dtmp, &pubx, &puby, curve); stop_count_time(); info("ecc_proj_keygen_time_%dB: %u us %u ticks", curve->p->length, get_us(), get_ticks()); if ((bn_compare(&pubx, exp_pub_k_x) == 0) && (bn_compare(&puby, exp_pub_k_y) == 0)) return 0; return 1; } uint32_t test_proj_ecdh(bn_uint_t *d_alice, bn_uint_t *pubx_alice, bn_uint_t *puby_alice, bn_uint_t *d_bob, bn_uint_t *pubx_bob, bn_uint_t *puby_bob, ecc_curve_t *curve) { BN_CREATE_VARIABLE(secret_alice, d_alice->length); BN_CREATE_VARIABLE(secret_bob, d_bob->length); start_count_time(); //now magic starts! alice and bob exchange their Qx and Qx ecc_proj_ECDH_secret_gen(&ecc_default_hash_no_hash, d_alice, pubx_bob, puby_bob, &secret_alice, curve);
/** * @brief Init function executed in first lines of tests. Started properly Chibios and ARM */ void init(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* Timer configuration.*/ rccEnableTIM3(FALSE); rccResetTIM3(); rccEnableTIM4(FALSE); rccResetTIM4(); TIM3->CR1 = 0; /* Initially stopped. */ TIM4->CR1 = 0; /* Initially stopped. */ TIM3->CR2 = TIM_CR2_MMS_1; TIM3->PSC = ((STM32_TIMCLK2 / 1000000) - 1); /* Prescaler value. */ TIM3->SR = 0; /* Clear pending IRQs. */ TIM3->DIER = 0; TIM3->SMCR = TIM_SMCR_MSM; TIM4->CR2 = 0; TIM4->PSC = 0; /* Prescaler value. */ TIM4->SR = 0; /* Clear pending IRQs. */ TIM4->DIER = 0; TIM4->SMCR = TIM_SMCR_TS_1 | TIM_SMCR_MSM | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; TIM4->CR1 = TIM_CR1_CEN; TIM3->CNT = 0; /* Initially stopped. */ TIM4->CNT = 0; /* Initially stopped. */ start_count_time(); chThdSleepMilliseconds(1000); stop_count_time(); /* * Initializes a serial-over-USB CDC driver. */ sduObjectInit(&SDU1); sduStart(&SDU1, &serusbcfg); /* * Activates the USB driver and then the USB bus pull-up on D+. * Note, a delay is inserted in order to not have to disconnect the cable * after a reset. */ usbDisconnectBus(serusbcfg.usbp); chThdSleepMilliseconds(250); usbStart(serusbcfg.usbp, &usbcfg); usbConnectBus(serusbcfg.usbp); /* * Stopping and restarting the USB in order to test the stop procedure. The * following lines are not usually required. */ chThdSleepMilliseconds(3000); info("---------------ECDSA ECDH Test Suite---------------"); info("CPU frequency %f MHz", STM32_SYSCLK/1000000.0); info("---------------------------------------------------"); info("-----------------Timer second test-----------------"); info("Start timer and wait 1 sec"); start_count_time(); chThdSleepMilliseconds(1000); stop_count_time(); info("Timer result 1sec = %u us", get_us()); info("---------------------------------------------------"); }
void decode_audio_packet(void) { double FDCT_time = 0, residue_time = 0; double initial_clock = get_us(); int mode_number = read_unsigned_value_PF(ilog(mode_num - 1)); vorbis_mode_t *mode = &mode_list[mode_number]; int V_N_bits = B_N_bits[mode->blockflag] - 1; int V_N = 1 << V_N_bits; int previous_window_flag = 1, next_window_flag = 1; if(mode->blockflag) { previous_window_flag = read_bit_PF(); next_window_flag = read_bit_PF(); } mapping_header_t *mapping = &mapping_list[mode->mapping]; channel_t *channel_list = setup_ref(mapping->channel_list); submap_t *submap_list = setup_ref(mapping->submap_list); uint16_t setup_origin = setup_get_head(); for(int i = 0; i < audio_channels; i++) { int submap_number = 0; if(mapping->submaps > 1) submap_number = channel_list[i].mux; int floor_number = submap_list[submap_number].floor; decode_floor1(floor_number, i); vector_list[i].no_residue = !vector_list[i].nonzero; } coupling_step_t *step_list = setup_ref(mapping->coupling_step_list); for(int i = 0; i < mapping->coupling_steps; i++) { if(vector_list[step_list[i].magnitude].nonzero || !vector_list[step_list[i].angle].nonzero) { vector_list[step_list[i].magnitude].no_residue = 0; vector_list[step_list[i].angle].no_residue = 0; } } if(mapping->submaps == 1) { submap_t *submap = setup_ref(mapping->submap_list); int residue_number = submap->residue; for(int i = 0; i < audio_channels; i++) { vector_list[i].do_not_decode_flag = vector_list[i].no_residue; } double residue_entry = get_us(); decode_residue(V_N_bits, residue_number, 0, audio_channels); residue_time += get_us() - residue_entry; } else { ERROR(ERROR_VORBIS, "Multiple submaps are not supported yet.\n"); } for(int i = 0; i < mapping->coupling_steps; i++) { decouple_square_polar(V_N, step_list[i].magnitude, step_list[i].angle); } for(int i = 0; i < audio_channels; i++) { DATA_TYPE *v = setup_ref(vector_list[i].body); if(vector_list[i].nonzero) { synthesize_floor1(V_N, i); } /*for(int i = 0; i < V_N; i++) { printf("%.0f ", 100000.0f * v[i]); } printf("\n");*/ double FDCT_entry = get_us(); FDCT_IV(v, V_N_bits); FDCT_time += get_us() - FDCT_entry; for(int j = 0; j < V_N; j++) { #ifndef FIXED_POINT v[j] *= 32768.0f; #endif //printf("%.0f ", v[j]); } //printf("\n"); overlap_add(V_N_bits, i, previous_window_flag); } /*if(previous_window_flag && vector_list[0].next_window_flag) { for(int i = 0; i < V_N / 2; i++) { audio[i + V_N / 2] = (int16_t)rh[i]; audio[i] = (int16_t)v_out[i + V_N / 2]; } } else { if(!previous_window_flag) { for(int i = 0; i < B_N[0] / 4; i++) { audio[i] = (int16_t)v_out[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 + i]; } for(int i = 0; i < B_N[0] / 4; i++) { audio[B_N[0] / 4 + i] = (int16_t)rh[i]; } for(int i = 0; i < (B_N[1] - B_N[0]) / 4; i++) { audio[B_N[0] / 2 + i] = (int16_t)(-v_out[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 - 1 - i]); } } else if(!vector_list[0].next_window_flag) { for(int i = 0; i < (B_N[1] - B_N[0]) / 4; i++) { audio[i] = (int16_t)(-rh[B_N[1] / 4 - 1 - i]); } for(int i = 0; i < B_N[0] / 4; i++) { audio[(B_N[1] - B_N[0]) / 4 + i] = (int16_t)v_out[i + B_N[0] / 4]; } for(int i = 0; i < B_N[0] / 4; i++) { audio[B_N[1] / 4 + i] = (int16_t)rh[i]; } } }*/ DATA_TYPE *v_left = setup_ref(vector_list[0].body); DATA_TYPE *v_right = setup_ref(vector_list[1].body); DATA_TYPE *rh_left = setup_ref(vector_list[0].right_hand); DATA_TYPE *rh_right = setup_ref(vector_list[1].right_hand); if(previous_window_flag && vector_list[0].next_window_flag) { for(int i = 0; i < V_N / 2; i++) { feed_SRC(v_left[i + V_N / 2], v_right[i + V_N / 2]); } for(int i = 0; i < V_N / 2; i++) { feed_SRC(rh_left[i], rh_right[i]); } } else { if(!previous_window_flag) { for(int i = 0; i < B_N[0] / 4; i++) { feed_SRC(v_left[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 + i], v_right[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 + i]); } for(int i = 0; i < B_N[0] / 4; i++) { feed_SRC(rh_left[i], rh_right[i]); } for(int i = 0; i < (B_N[1] - B_N[0]) / 4; i++) { feed_SRC(-v_left[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 - 1 - i], -v_right[B_N[1] / 4 + (B_N[1] - B_N[0]) / 4 - 1 - i]); } } else if(!vector_list[0].next_window_flag) { for(int i = 0; i < (B_N[1] - B_N[0]) / 4; i++) { feed_SRC(-rh_left[B_N[1] / 4 - 1 - i], -rh_right[B_N[1] / 4 - 1 - i]); } for(int i = 0; i < B_N[0] / 4; i++) { feed_SRC(v_left[i + B_N[0] / 4], v_right[i + B_N[0] / 4]); } for(int i = 0; i < B_N[0] / 4; i++) { feed_SRC(rh_left[i], rh_right[i]); } } } //int this_window_flag = vector_list[0].next_window_flag; for(int i = 0; i < audio_channels; i++) { cache_righthand(V_N, i, next_window_flag); } setup_set_head(setup_origin); double packet_time = get_us() - initial_clock; printf("%lf %lf %lf\n", packet_time, FDCT_time, residue_time); /*if(previous_window_flag && this_window_flag) { fwrite(audio, sizeof(int16_t) * V_N, 1, sox); } else { fwrite(audio, sizeof(int16_t) * (B_N[0] + B_N[1]) / 4, 1, sox); }*/ }
//------------------------------------------------ // 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; }
int main(int argc, char* argv[]) { signal_setup(); fprintf(stdout, "\nACT version %s\n", VERSION); fprintf(stdout, "Storage device IO test\n"); fprintf(stdout, "Copyright 2018 by Aerospike. All rights reserved.\n\n"); if (! storage_configure(argc, argv)) { exit(-1); } device devices[g_scfg.num_devices]; queue* trans_qs[g_scfg.num_queues]; g_devices = devices; g_trans_qs = trans_qs; histogram_scale scale = g_scfg.us_histograms ? HIST_MICROSECONDS : HIST_MILLISECONDS; if (! (g_large_block_read_hist = histogram_create(scale)) || ! (g_large_block_write_hist = histogram_create(scale)) || ! (g_raw_read_hist = histogram_create(scale)) || ! (g_read_hist = histogram_create(scale)) || ! (g_raw_write_hist = histogram_create(scale)) || ! (g_write_hist = histogram_create(scale))) { exit(-1); } for (uint32_t n = 0; n < g_scfg.num_devices; n++) { device* dev = &g_devices[n]; dev->name = (const char*)g_scfg.device_names[n]; if (g_scfg.file_size == 0) { // normally 0 set_scheduler(dev->name, g_scfg.scheduler_mode); } if (! (dev->fd_q = queue_create(sizeof(int), true)) || ! discover_device(dev) || ! (dev->raw_read_hist = histogram_create(scale)) || ! (dev->raw_write_hist = histogram_create(scale))) { exit(-1); } sprintf(dev->read_hist_tag, "%s-reads", dev->name); sprintf(dev->write_hist_tag, "%s-writes", dev->name); } rand_seed(); g_run_start_us = get_us(); uint64_t run_stop_us = g_run_start_us + g_scfg.run_us; g_running = true; if (g_scfg.write_reqs_per_sec != 0) { for (uint32_t n = 0; n < g_scfg.num_devices; n++) { device* dev = &g_devices[n]; if (pthread_create(&dev->large_block_read_thread, NULL, run_large_block_reads, (void*)dev) != 0) { fprintf(stdout, "ERROR: create large op read thread\n"); exit(-1); } if (pthread_create(&dev->large_block_write_thread, NULL, run_large_block_writes, (void*)dev) != 0) { fprintf(stdout, "ERROR: create large op write thread\n"); exit(-1); } } } if (g_scfg.tomb_raider) { for (uint32_t n = 0; n < g_scfg.num_devices; n++) { device* dev = &g_devices[n]; if (pthread_create(&dev->tomb_raider_thread, NULL, run_tomb_raider, (void*)dev) != 0) { fprintf(stdout, "ERROR: create tomb raider thread\n"); exit(-1); } } } uint32_t n_trans_tids = g_scfg.num_queues * g_scfg.threads_per_queue; pthread_t trans_tids[n_trans_tids]; for (uint32_t i = 0; i < g_scfg.num_queues; i++) { if (! (g_trans_qs[i] = queue_create(sizeof(trans_req), true))) { exit(-1); } for (uint32_t j = 0; j < g_scfg.threads_per_queue; j++) { if (pthread_create(&trans_tids[(i * g_scfg.threads_per_queue) + j], NULL, run_transactions, (void*)g_trans_qs[i]) != 0) { fprintf(stdout, "ERROR: create transaction thread\n"); exit(-1); } } } // Equivalent: g_scfg.internal_read_reqs_per_sec != 0. bool do_reads = g_scfg.read_reqs_per_sec != 0; pthread_t read_req_tids[g_scfg.read_req_threads]; if (do_reads) { for (uint32_t k = 0; k < g_scfg.read_req_threads; k++) { if (pthread_create(&read_req_tids[k], NULL, run_generate_read_reqs, NULL) != 0) { fprintf(stdout, "ERROR: create read request thread\n"); exit(-1); } } } // Equivalent: g_scfg.internal_write_reqs_per_sec != 0. bool do_commits = g_scfg.commit_to_device && g_scfg.write_reqs_per_sec != 0; pthread_t write_req_tids[g_scfg.write_req_threads]; if (do_commits) { for (uint32_t k = 0; k < g_scfg.write_req_threads; k++) { if (pthread_create(&write_req_tids[k], NULL, run_generate_write_reqs, NULL) != 0) { fprintf(stdout, "ERROR: create write request thread\n"); exit(-1); } } } fprintf(stdout, "\nHISTOGRAM NAMES\n"); if (do_reads) { fprintf(stdout, "reads\n"); fprintf(stdout, "device-reads\n"); for (uint32_t d = 0; d < g_scfg.num_devices; d++) { fprintf(stdout, "%s\n", g_devices[d].read_hist_tag); } } if (g_scfg.write_reqs_per_sec != 0) { fprintf(stdout, "large-block-reads\n"); fprintf(stdout, "large-block-writes\n"); } if (do_commits) { fprintf(stdout, "writes\n"); fprintf(stdout, "device-writes\n"); for (uint32_t d = 0; d < g_scfg.num_devices; d++) { fprintf(stdout, "%s\n", g_devices[d].write_hist_tag); } } fprintf(stdout, "\n"); uint64_t now_us = 0; uint64_t count = 0; while (g_running && (now_us = get_us()) < run_stop_us) { count++; int64_t sleep_us = (int64_t) ((count * g_scfg.report_interval_us) - (now_us - g_run_start_us)); if (sleep_us > 0) { usleep((uint32_t)sleep_us); } fprintf(stdout, "after %" PRIu64 " sec:\n", (count * g_scfg.report_interval_us) / 1000000); fprintf(stdout, "requests-queued: %" PRIu32 "\n", atomic32_get(g_reqs_queued)); if (do_reads) { histogram_dump(g_read_hist, "reads"); histogram_dump(g_raw_read_hist, "device-reads"); for (uint32_t d = 0; d < g_scfg.num_devices; d++) { histogram_dump(g_devices[d].raw_read_hist, g_devices[d].read_hist_tag); } } if (g_scfg.write_reqs_per_sec != 0) { histogram_dump(g_large_block_read_hist, "large-block-reads"); histogram_dump(g_large_block_write_hist, "large-block-writes"); } if (do_commits) { histogram_dump(g_write_hist, "writes"); histogram_dump(g_raw_write_hist, "device-writes"); for (uint32_t d = 0; d < g_scfg.num_devices; d++) { histogram_dump(g_devices[d].raw_write_hist, g_devices[d].write_hist_tag); } } fprintf(stdout, "\n"); fflush(stdout); } g_running = false; if (do_reads) { for (uint32_t k = 0; k < g_scfg.read_req_threads; k++) { pthread_join(read_req_tids[k], NULL); } } if (do_commits) { for (uint32_t k = 0; k < g_scfg.write_req_threads; k++) { pthread_join(write_req_tids[k], NULL); } } for (uint32_t j = 0; j < n_trans_tids; j++) { pthread_join(trans_tids[j], NULL); } for (uint32_t i = 0; i < g_scfg.num_queues; i++) { queue_destroy(g_trans_qs[i]); } for (uint32_t d = 0; d < g_scfg.num_devices; d++) { device* dev = &g_devices[d]; if (g_scfg.tomb_raider) { pthread_join(dev->tomb_raider_thread, NULL); } if (g_scfg.write_reqs_per_sec != 0) { pthread_join(dev->large_block_read_thread, NULL); pthread_join(dev->large_block_write_thread, NULL); } fd_close_all(dev); queue_destroy(dev->fd_q); free(dev->raw_read_hist); free(dev->raw_write_hist); } free(g_large_block_read_hist); free(g_large_block_write_hist); free(g_raw_read_hist); free(g_read_hist); free(g_raw_write_hist); free(g_write_hist); return 0; }
int main(int32_t argc, char * argv) { srand(time(NULL)); void * game_memory = malloc(MEM); void * game_memory_pos = game_memory; assert(game_memory != NULL); HexShape hexes; hexes.radius_in_pixels = 20; // NOTE: This is 'radius' dimensions hexes.dimensions_in_pixels = mulVf2ByScalar((vf2){1, sqrt(3) * .5f}, hexes.radius_in_pixels); v2 window_dimensions_in_pixels = floorVf2(mulV2ByVf2((v2){24, 18}, hexes.dimensions_in_pixels)); vHex camera_position_in_hexes = {2,3}; SDL_Init(SDL_INIT_VIDEO); SDL_Window * window = SDL_CreateWindow("A Hex Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_dimensions_in_pixels.x, window_dimensions_in_pixels.y, 0); SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0); SDL_Texture * texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, window_dimensions_in_pixels.x, window_dimensions_in_pixels.y); // The pixel buffer uint32_t * pixels = (uint32_t *)game_memory_pos; game_memory_pos += window_dimensions_in_pixels.x * window_dimensions_in_pixels.y * sizeof(uint32_t); assert(game_memory_pos < game_memory + MEM); printf("Starting\n"); // For average FPS measurement uint64_t last_measure = get_us(); uint32_t frame_count = 0; // For FPS timing uint64_t last_frame = get_us(); uint32_t delta_frame; bool32 quit = false; SDL_Event event; while (!quit) { uint64_t now = get_us(); // Measure FPS if (now >= (last_measure + 1000000)) { // If last measurement was more than 1 sec ago last_measure = now; printf("%f us/frame\n", 1000000.0f / (double)frame_count); frame_count = 0; } // Render if (now >= last_frame + (1000000/FPS)) { delta_frame = now - last_frame; last_frame = now; frame_count++; // Clear screen to white v2 pixelPointer; for (pixelPointer.y = 0; pixelPointer.y < window_dimensions_in_pixels.y; pixelPointer.y++) { for (pixelPointer.x = 0; pixelPointer.x < window_dimensions_in_pixels.x; pixelPointer.x++) { pixels[v2ToV1(pixelPointer, window_dimensions_in_pixels.x)] = 0x00FFFFFF; } } // Draw Hexagons int32_t radius = 2; vHex hex_pos; for (hex_pos.q = 1-radius; hex_pos.q < radius; hex_pos.q += 1) { for (hex_pos.r = 1-radius; hex_pos.r < radius; hex_pos.r += 1) { if (absInt32(hex_pos.q + hex_pos.r) < radius) { uint32_t color; if (hex_pos.q == 0 && hex_pos.r == 0) { color = 0x00FF0000; } else { color = 0; } v2 hex_pixel_pos = floorVf2(mulVf2ByVf2( hexes.dimensions_in_pixels, hexToCart(addHexes(hex_pos, camera_position_in_hexes), hexes.radius_in_pixels) )); render_hex(hex_pixel_pos, pixels, hexes, window_dimensions_in_pixels, color); } } } // Flip pixels v2 pos; for (pos.y = 0; pos.y < window_dimensions_in_pixels.y / 2; pos.y++) { for (pos.x = 0; pos.x < window_dimensions_in_pixels.x; pos.x++) { uint32_t top_pixel = pixels[pos.y * window_dimensions_in_pixels.x + pos.x]; pixels[v2ToV1(pos, window_dimensions_in_pixels.x)] = pixels[(window_dimensions_in_pixels.y - pos.y - 1) * window_dimensions_in_pixels.x + pos.x]; pixels[(window_dimensions_in_pixels.y - pos.y - 1) * window_dimensions_in_pixels.x + pos.x] = top_pixel; } } SDL_UpdateTexture(texture, NULL, pixels, window_dimensions_in_pixels.x * sizeof(uint32_t)); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } // Get inputs SDL_PollEvent(&event); if (event.type == SDL_QUIT) { quit = true; } else if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == 'w' && event.key.keysym.mod == KMOD_LCTRL) { quit = true; } } } error("Quitting"); SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); free(game_memory); printf("Finished\n"); return 0; }