⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm_basic.cxx

📁 ecos为实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 4 页
字号:
//==========================================================================////        tm_basic.cxx////        Basic timing test / scaffolding////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     gthomas// Contributors:  gthomas// Date:          1998-10-19// Description:   Very simple kernel timing test//####DESCRIPTIONEND#####include <pkgconf/kernel.h>#include <cyg/kernel/sched.hxx>#include <cyg/kernel/thread.hxx>#include <cyg/kernel/thread.inl>#include <cyg/kernel/mutex.hxx>#include <cyg/kernel/sema.hxx>#include <cyg/kernel/sched.inl>#include <cyg/kernel/clock.hxx>#include <cyg/kernel/clock.inl>#include <cyg/kernel/kapi.h>#include <cyg/infra/testcase.h>// Define this to see the statistics with the first sample datum removed.// This can expose the effects of caches on the speed of operations.#undef STATS_WITHOUT_FIRST_SAMPLE#if defined(CYGFUN_KERNEL_API_C) &&             \    defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \    defined(CYGVAR_KERNEL_COUNTERS_CLOCK) &&    \    !defined(CYGPKG_HAL_I386_LINUX) &&          \    (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)#define NTHREADS 1#include "testaux.hxx"// Structure used to keep track of timestypedef struct fun_times {    cyg_uint32 start;    cyg_uint32 end;} fun_times;#define NSAMPLES         32#define NTEST_THREADS    24#define NTHREAD_SWITCHES 128#define NMUTEXES         32#define NMBOXES          32#define NSEMAPHORES      32#define NSCHEDS          128#define NCOUNTERS        32#define NALARMS          32#define NSAMPLES_SIM         2#define NTEST_THREADS_SIM    2#define NTHREAD_SWITCHES_SIM 4#define NMUTEXES_SIM         2#define NMBOXES_SIM          2#define NSEMAPHORES_SIM      2#define NSCHEDS_SIM          4#define NCOUNTERS_SIM        2#define NALARMS_SIM          2static int nsamples;static int ntest_threads;static int nthread_switches;static int nmutexes;static int nmboxes;static int nsemaphores;static int nscheds;static int ncounters;static int nalarms;#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUMstatic char stacks[NTEST_THREADS][STACK_SIZE];static cyg_thread test_threads[NTEST_THREADS];static cyg_handle_t threads[NTEST_THREADS];static int overhead;static cyg_sem_t synchro;static fun_times thread_ft[NTEST_THREADS];static fun_times test2_ft[NTHREAD_SWITCHES];static cyg_mutex_t test_mutexes[NMUTEXES];static fun_times mutex_ft[NMUTEXES];static cyg_thread mutex_test_thread;static cyg_handle_t mutex_test_thread_handle;static cyg_mbox test_mboxes[NMBOXES];static cyg_handle_t test_mbox_handles[NMBOXES];static fun_times mbox_ft[NMBOXES];static cyg_thread mbox_test_thread;static cyg_handle_t mbox_test_thread_handle;static cyg_sem_t test_semaphores[NSEMAPHORES];static fun_times semaphore_ft[NSEMAPHORES];static cyg_thread semaphore_test_thread;static cyg_handle_t semaphore_test_thread_handle;static fun_times sched_ft[NSCHEDS];static cyg_counter test_counters[NCOUNTERS];static cyg_handle_t counters[NCOUNTERS];static fun_times counter_ft[NCOUNTERS];static cyg_alarm test_alarms[NALARMS];static cyg_handle_t alarms[NALARMS];static fun_times alarm_ft[NALARMS];static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;static long ns_per_system_clock;#ifdef HAL_CLOCK_LATENCY// Data kept by kernel real time clock measuring clock interrupt latencyextern cyg_tick_count total_clock_latency, total_clock_interrupts;extern cyg_int32 min_clock_latency, max_clock_latency;extern bool measure_clock_latency;#endifexternC void diag_printf(const char *, ...);void run_sched_tests(void);void run_thread_tests(void);void run_thread_switch_test(void);void run_mutex_tests(void);void run_mutex_circuit_test(void);void run_mbox_tests(void);void run_mbox_circuit_test(void);void run_semaphore_tests(void);void run_semaphore_circuit_test(void);void run_counter_tests(void);void run_alarm_tests(void);// Wait until a clock tick [real time clock] has passed.  This should keep it// from happening again during a measurement, thus minimizing any fluctuationsvoidwait_for_tick(void){    cyg_tick_count_t tv0, tv1;    tv0 = cyg_current_time();    while (true) {        tv1 = cyg_current_time();        if (tv1 != tv0) break;    }}// Display a number of ticks as microseconds// Note: for improved calculation significance, values are kept in ticks*1000voidshow_ticks_in_us(cyg_uint32 ticks){    long long ns;    ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;    ns += 5;  // for rounding to .01us    diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10));}//// If the kernel is instrumented to measure clock interrupt latency, these// measurements can be drastically perturbed by printing via "diag_printf()"// since that code may run with interrupts disabled for long periods.//// In order to get accurate/reasonable latency figures _for the kernel // primitive functions beint tested_, the kernel's latency measurements// are suspended while the printing actually takes place.//// The measurements are reenabled after the printing, thus allowing for// fair measurements of the kernel primitives, which are not distorted// by the printing mechanisms.#ifdef HAL_CLOCK_LATENCYvoiddisable_clock_latency_measurement(void){    wait_for_tick();    measure_clock_latency = false;}voidenable_clock_latency_measurement(void){    wait_for_tick();    measure_clock_latency = true;}// Ensure that the measurements are reasonable (no startup anomalies)voidreset_clock_latency_measurement(void){  disable_clock_latency_measurement();  total_clock_latency = 0;  total_clock_interrupts = 0;  min_clock_latency = 0x7FFFFFFF;  max_clock_latency = 0;  enable_clock_latency_measurement();}#else#define disable_clock_latency_measurement()#define enable_clock_latency_measurement()#define reset_clock_latency_measurement()#endifvoidshow_times_hdr(void){    disable_clock_latency_measurement();    diag_printf("\n");    diag_printf("                                 Confidence\n");    diag_printf("     Ave     Min     Max     Var  Ave  Min  Function\n");    diag_printf("  ======  ======  ======  ====== ========== ========\n");    enable_clock_latency_measurement();}voidshow_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first){    int i, delta, min, max, con_ave, con_min, ave_dev;    int start_sample, total_samples;       cyg_int32 total, ave;    if (ignore_first) {        start_sample = 1;        total_samples = nsamples-1;    } else {        start_sample = 0;        total_samples = nsamples;    }    total = 0;    min = 0x7FFFFFFF;    max = 0;    for (i = start_sample;  i < nsamples;  i++) {        if (ft[i].end < ft[i].start) {            // Clock wrapped around (timer tick)            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;        } else {            delta = ft[i].end - ft[i].start;        }        delta -= overhead;        if (delta < 0) delta = 0;        delta *= 1000;        total += delta;        if (delta < min) min = delta;        if (delta > max) max = delta;    }    ave = total / total_samples;    total = 0;    ave_dev = 0;    for (i = start_sample;  i < nsamples;  i++) {        if (ft[i].end < ft[i].start) {            // Clock wrapped around (timer tick)            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;        } else {            delta = ft[i].end - ft[i].start;        }        delta -= overhead;        if (delta < 0) delta = 0;        delta *= 1000;        delta = delta - ave;        if (delta < 0) delta = -delta;        ave_dev += delta;    }    ave_dev /= total_samples;    con_ave = 0;    con_min = 0;    for (i = start_sample;  i < nsamples;  i++) {        if (ft[i].end < ft[i].start) {            // Clock wrapped around (timer tick)            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;        } else {            delta = ft[i].end - ft[i].start;        }        delta -= overhead;        if (delta < 0) delta = 0;        delta *= 1000;        if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++;        if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++;    }    con_ave = (con_ave * 100) / total_samples;    con_min = (con_min * 100) / total_samples;    show_ticks_in_us(ave);    show_ticks_in_us(min);    show_ticks_in_us(max);    show_ticks_in_us(ave_dev);    disable_clock_latency_measurement();    diag_printf("  %3d%% %3d%%", con_ave, con_min);    diag_printf(" %s\n", title);    enable_clock_latency_measurement();}voidshow_times(fun_times ft[], int nsamples, char *title){    show_times_detail(ft, nsamples, title, false);#ifdef STATS_WITHOUT_FIRST_SAMPLE    show_times_detail(ft, nsamples, "", true);#endif}voidshow_test_parameters(void){    disable_clock_latency_measurement();    diag_printf("\nTesting parameters:\n");    diag_printf("   Clock samples:         %3d\n", nsamples);    diag_printf("   Threads:               %3d\n", ntest_threads);    diag_printf("   Thread switches:       %3d\n", nthread_switches);    diag_printf("   Mutexes:               %3d\n", nmutexes);    diag_printf("   Mailboxes:             %3d\n", nmboxes);    diag_printf("   Semaphores:            %3d\n", nsemaphores);    diag_printf("   Scheduler operations:  %3d\n", nscheds);    diag_printf("   Counters:              %3d\n", ncounters);    diag_printf("   Alarms:                %3d\n", nalarms);    diag_printf("\n");     enable_clock_latency_measurement();}voidend_of_test_group(void){    disable_clock_latency_measurement();    diag_printf("\n");     enable_clock_latency_measurement();}// Compute a name for a threadchar *thread_name(char *basename, int indx) {    return "<<NULL>>";  // Not currently used}// test0 - null test, never executedvoidtest0(cyg_uint32 indx){    diag_printf("test0.%d executed?\n", indx);    cyg_thread_exit();}// test1 - empty test, simply exit.  Last thread signals parent.voidtest1(cyg_uint32 indx){    if (indx == (cyg_uint32)(ntest_threads-1)) {        cyg_semaphore_post(&synchro);  // Signal that last thread is dying    }    cyg_thread_exit();}// test2 - measure thread switch timesvoidtest2(cyg_uint32 indx){    int i;    for (i = 0;  i < nthread_switches;  i++) {        if (indx == 0) {            HAL_CLOCK_READ(&test2_ft[i].start);        } else {            HAL_CLOCK_READ(&test2_ft[i].end);        }        cyg_thread_yield();    }    if (indx == 1) {        cyg_semaphore_post(&synchro);    }    cyg_thread_exit();}// Full-circuit mutex unlock/lock testvoidmutex_test(cyg_uint32 indx){    int i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -