bool raycast(game* g, vec2 from, vec2 to) { ivec2 cur(fast_floor(from.x), fast_floor(from.y)); ivec2 end(fast_floor(to.x), fast_floor(to.y)); ivec2 sign(sign(to.x - from.x), sign(to.y - from.y)); vec2 abs_delta(abs(to.x - from.x), abs(to.y - from.y)); vec2 delta_t(vec2(1.0f) / abs_delta); vec2 lb(to_vec2(cur)); vec2 ub(lb + vec2(1.0f)); vec2 t(vec2((from.x > to.x) ? (from.x - lb.x) : (ub.x - from.x), (from.y > to.y) ? (from.y - lb.y) : (ub.y - from.y)) / abs_delta); for(;;) { if (g->is_raycast_solid(cur.x, cur.y)) return true; if (t.x <= t.y) { if (cur.x == end.x) break; t.x += delta_t.x; cur.x += sign.x; } else { if (cur.y == end.y) break; t.y += delta_t.y; cur.y += sign.y; } } return false; }
static void test(void) { test_context *ctx = &ctx_instance; rtems_status_code sc; rtems_task_argument runner_index; rtems_id stopper_id; uint32_t expected_tokens; uint32_t total_delta; uint64_t total_cycles; uint32_t average_cycles; sc = rtems_task_create( rtems_build_name('S', 'T', 'O', 'P'), PRIO_STOP, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &stopper_id ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { sc = rtems_task_create( rtems_build_name('R', 'U', 'N', (char) ('0' + runner_index)), PRIO_HIGH + runner_index, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &ctx->runner_ids[runner_index] ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); } for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { sc = rtems_task_start(ctx->runner_ids[runner_index], runner, runner_index); rtems_test_assert(sc == RTEMS_SUCCESSFUL); } sc = rtems_task_wake_after(10 * rtems_clock_get_ticks_per_second()); rtems_test_assert(sc == RTEMS_SUCCESSFUL); sc = rtems_task_start(stopper_id, stopper, 0); rtems_test_assert(sc == RTEMS_SUCCESSFUL); for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { sc = rtems_task_delete(ctx->runner_ids[runner_index]); rtems_test_assert(sc == RTEMS_SUCCESSFUL); } total_cycles = 0; for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { const test_counters *counters = &ctx->counters[runner_index]; size_t cpu; for (cpu = 0; cpu < CPU_COUNT; ++cpu) { total_cycles += counters->cycles_per_cpu[cpu].counter; } } average_cycles = (uint32_t) (total_cycles / (RUNNER_COUNT * CPU_COUNT)); printf( "total cycles %" PRIu64 "\n" "average cycles %" PRIu32 "\n", total_cycles, average_cycles ); for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { const test_counters *counters = &ctx->counters[runner_index]; size_t cpu; printf("runner %" PRIuPTR "\n", runner_index); for (cpu = 0; cpu < CPU_COUNT; ++cpu) { uint32_t tokens = counters->tokens_per_cpu[cpu].counter; uint32_t cycles = counters->cycles_per_cpu[cpu].counter; double cycle_deviation = ((double) cycles - average_cycles) / average_cycles; printf( "\tcpu %zu tokens %" PRIu32 "\n" "\tcpu %zu cycles %" PRIu32 "\n" "\tcpu %zu cycle deviation %f\n", cpu, tokens, cpu, cycles, cpu, cycle_deviation ); } } expected_tokens = ctx->counters[0].tokens_per_cpu[0].counter; total_delta = 0; for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) { test_counters *counters = &ctx->counters[runner_index]; size_t cpu; for (cpu = 0; cpu < CPU_COUNT; ++cpu) { uint32_t tokens = counters->tokens_per_cpu[cpu].counter; uint32_t delta = abs_delta(tokens, expected_tokens); rtems_test_assert(delta <= 1); total_delta += delta; } } rtems_test_assert(total_delta <= (RUNNER_COUNT * CPU_COUNT - 1)); }