/* * Copyright (c) 2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 * 82178 Puchheim * Germany * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _KERNEL #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tmacros.h" const char rtems_test_name[] = "SPTIMECOUNTER 2"; #define CPU_COUNT 32 #define DURATION_IN_SECONDS 1 typedef struct { rtems_test_parallel_context base; struct timecounter tc_null; uint32_t binuptime_per_job[CPU_COUNT]; sbintime_t duration_per_job[CPU_COUNT]; uint32_t rtemsuptime_per_job[CPU_COUNT]; } timecounter_context; static timecounter_context test_instance; static rtems_interval test_duration(void) { return DURATION_IN_SECONDS * rtems_clock_get_ticks_per_second(); } static uint32_t test_get_timecount_null(struct timecounter *tc) { return 0; } static void install_tc_null(timecounter_context *ctx) { struct timecounter *tc_cpu = &ctx->tc_null; tc_cpu->tc_get_timecount = test_get_timecount_null; tc_cpu->tc_counter_mask = 0xffffffff; tc_cpu->tc_frequency = rtems_counter_nanoseconds_to_ticks(1000000000); tc_cpu->tc_quality = 2000; rtems_timecounter_install(tc_cpu); } static rtems_interval test_bintime_init( rtems_test_parallel_context *base, void *arg, size_t active_workers ) { rtems_test_spin_until_next_tick(); return test_duration(); } static void test_bintime_body( rtems_test_parallel_context *base, void *arg, size_t active_workers, size_t worker_index ) { timecounter_context *ctx = (timecounter_context *) base; uint32_t counter = 1; struct bintime start; struct bintime end; rtems_bsd_binuptime(&start); do { ++counter; rtems_bsd_binuptime(&end); } while (!rtems_test_parallel_stop_job(&ctx->base)); ctx->binuptime_per_job[worker_index] = counter; ctx->duration_per_job[worker_index] = bttosbt(end) - bttosbt(start); } static void test_bintime_fini( rtems_test_parallel_context *base, void *arg, size_t active_workers ) { timecounter_context *ctx = (timecounter_context *) base; size_t i; printf(" \n", active_workers); for (i = 0; i < active_workers; ++i) { sbintime_t error; printf( " %" PRIu32 "\n" " %" PRId64 "\n", i + 1, ctx->binuptime_per_job[i], i + 1, ctx->duration_per_job[i] ); error = DURATION_IN_SECONDS * SBT_1S - ctx->duration_per_job[i]; rtems_test_assert(error * error < SBT_1MS * SBT_1MS); } printf(" \n"); } static rtems_interval test_bintime_null_init( rtems_test_parallel_context *base, void *arg, size_t active_workers ) { timecounter_context *ctx = &test_instance; install_tc_null(ctx); return test_duration(); } static void test_bintime_null_body( rtems_test_parallel_context *base, void *arg, size_t active_workers, size_t worker_index ) { timecounter_context *ctx = (timecounter_context *) base; struct bintime bt; uint32_t counter = 0; while (!rtems_test_parallel_stop_job(&ctx->base)) { ++counter; rtems_bsd_binuptime(&bt); } ctx->binuptime_per_job[worker_index] = counter; } static void test_bintime_null_fini( rtems_test_parallel_context *base, void *arg, size_t active_workers ) { timecounter_context *ctx = (timecounter_context *) base; size_t i; printf(" \n", active_workers); for (i = 0; i < active_workers; ++i) { printf( " %" PRIu32 "\n", i + 1, ctx->binuptime_per_job[i] ); } printf(" \n"); } static const rtems_test_parallel_job timecounter_jobs[] = { { .init = test_bintime_init, .body = test_bintime_body, .fini = test_bintime_fini, .cascade = true },{ .init = test_bintime_null_init, .body = test_bintime_null_body, .fini = test_bintime_null_fini, .cascade = true } }; static void Init(rtems_task_argument arg) { timecounter_context *ctx = &test_instance; struct bintime bt; struct timespec ts; struct timeval tv; TEST_BEGIN(); printf("\n"); rtems_test_parallel( &ctx->base, NULL, &timecounter_jobs[0], RTEMS_ARRAY_SIZE(timecounter_jobs) ); /* Check for all functions available in the bsd.h user space */ rtems_bsd_bintime(&bt); rtems_bsd_microtime(&tv); rtems_bsd_nanotime(&ts); rtems_bsd_binuptime(&bt); rtems_bsd_microuptime(&tv); rtems_bsd_nanouptime(&ts); rtems_bsd_getbintime(&bt); rtems_bsd_getmicrotime(&tv); rtems_bsd_getnanotime(&ts); rtems_bsd_getbinuptime(&bt); rtems_bsd_getmicrouptime(&tv); rtems_bsd_getnanouptime(&ts); printf("\n"); TEST_END(); rtems_test_exit(0); } #define CONFIGURE_MICROSECONDS_PER_TICK 1000 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_MAXIMUM_TASKS (2 + CPU_COUNT - 1) #define CONFIGURE_MAXIMUM_TIMERS 2 #define CONFIGURE_MAXIMUM_PERIODS 1 #define CONFIGURE_SMP_APPLICATION #define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT #define CONFIGURE_RTEMS_INIT_TASKS_TABLE #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_INIT #include