📄 timerbench.c
字号:
/* * Copyright (C) 2005 Jan Kiszka <jan.kiszka@web.de>. * * Xenomai is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Xenomai is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Xenomai; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <linux/module.h>#include <asm/semaphore.h>#ifdef CONFIG_IPIPE_TRACE#include <linux/ipipe_trace.h>#endif /* CONFIG_IPIPE_TRACE */#include <rtdm/rtbenchmark.h>#include <rtdm/rtdm_driver.h>struct rt_tmbench_context { int mode; unsigned long period; int freeze_max; int warmup_loops; int samples_per_sec; long *histogram_min; long *histogram_max; long *histogram_avg; int histogram_size; int bucketsize; rtdm_task_t timer_task; xntimer_t timer; int warmup; uint64_t start_time; uint64_t date; struct rtbnch_result curr; rtdm_event_t result_event; struct rtbnch_interm_result result; struct semaphore nrt_mutex;};static unsigned int start_index;module_param(start_index, uint, 0400);MODULE_PARM_DESC(start_index, "First device instance number to be used");MODULE_LICENSE("GPL");MODULE_AUTHOR("jan.kiszka@web.de");static inline void add_histogram(struct rt_tmbench_context *ctx, long *histogram, long addval){ /* bucketsize steps */ long inabs = (addval >= 0 ? addval : -addval) / ctx->bucketsize; histogram[inabs < ctx->histogram_size ? inabs : ctx->histogram_size-1]++;}void eval_inner_loop(struct rt_tmbench_context *ctx, long dt){ if (ctx->date <= ctx->start_time) ctx->curr.overruns++; if (dt > ctx->curr.max) ctx->curr.max = dt; if (dt < ctx->curr.min) ctx->curr.min = dt; ctx->curr.avg += dt;#ifdef CONFIG_IPIPE_TRACE if (ctx->freeze_max && (dt > ctx->result.overall.max) && !ctx->warmup) { ipipe_trace_frozen_reset(); ipipe_trace_freeze(dt); ctx->result.overall.max = dt; }#endif /* CONFIG_IPIPE_TRACE */ ctx->date += ctx->period; if (!ctx->warmup && ctx->histogram_size) add_histogram(ctx, ctx->histogram_avg, dt);}void eval_outer_loop(struct rt_tmbench_context *ctx){ if (!ctx->warmup) { if (ctx->histogram_size) { add_histogram(ctx, ctx->histogram_max, ctx->curr.max); add_histogram(ctx, ctx->histogram_min, ctx->curr.min); } ctx->result.last.min = ctx->curr.min; if (ctx->curr.min < ctx->result.overall.min) ctx->result.overall.min = ctx->curr.min; ctx->result.last.max = ctx->curr.max; if (ctx->curr.max > ctx->result.overall.max) ctx->result.overall.max = ctx->curr.max; ctx->result.last.avg = ctx->curr.avg / ctx->samples_per_sec; ctx->result.overall.avg += ctx->result.last.avg; ctx->result.overall.overruns += ctx->curr.overruns; rtdm_event_pulse(&ctx->result_event); } if (ctx->warmup && (ctx->result.overall.test_loops == ctx->warmup_loops)) { ctx->result.overall.test_loops = 0; ctx->warmup = 0; } ctx->curr.min = 10000000; ctx->curr.max = -10000000; ctx->curr.avg = 0; ctx->curr.overruns = 0; ctx->result.overall.test_loops++;}void timer_task_proc(void *arg){ struct rt_tmbench_context *ctx = (struct rt_tmbench_context *)arg; int count; /* start time: one millisecond from now. */ ctx->date = rtdm_clock_read() + 1000000; while (1) { int err; for (count = 0; count < ctx->samples_per_sec; count++) { RTDM_EXECUTE_ATOMICALLY( ctx->start_time = rtdm_clock_read(); err = rtdm_task_sleep_until(ctx->date); ); if (err) return; eval_inner_loop(ctx, (long)(rtdm_clock_read() - ctx->date)); } eval_outer_loop(ctx); }}void timer_proc(void *arg){ struct rt_tmbench_context *ctx = (struct rt_tmbench_context *)arg; eval_inner_loop(ctx, (long)(rtdm_clock_read() - ctx->date)); ctx->start_time = rtdm_clock_read(); /* FIXME: convert to RTDM timers */ xntimer_start(&ctx->timer, xnpod_ns2ticks(ctx->date-ctx->start_time), XN_INFINITE); if (++ctx->curr.test_loops < ctx->samples_per_sec) return; ctx->curr.test_loops = 0; eval_outer_loop(ctx);}int rt_tmbench_open(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, int oflags){ struct rt_tmbench_context *ctx; ctx = (struct rt_tmbench_context *)context->dev_private; ctx->mode = -1; init_MUTEX(&ctx->nrt_mutex); return 0;}int rt_tmbench_close(struct rtdm_dev_context *context, rtdm_user_info_t *user_info){ struct rt_tmbench_context *ctx; ctx = (struct rt_tmbench_context *)context->dev_private; down(&ctx->nrt_mutex); if (ctx->mode >= 0) { if (ctx->mode == RTBNCH_TIMER_TASK) rtdm_task_destroy(&ctx->timer_task); else /* FIXME: convert to RTDM timers */ xntimer_destroy(&ctx->timer); rtdm_event_destroy(&ctx->result_event); if (ctx->histogram_size) kfree(ctx->histogram_min); ctx->mode = -1; ctx->histogram_size = 0; } up(&ctx->nrt_mutex); return 0;}#ifdef CONFIG_IPIPE_TRACEint tracer_ioctl(int request, rtdm_user_info_t *user_info, void *arg){ switch (request) { case RTBNCH_RTIOC_BEGIN_TRACE: ipipe_trace_begin((long)arg); break; case RTBNCH_RTIOC_END_TRACE: ipipe_trace_end((long)arg); break; case RTBNCH_RTIOC_REFREEZE_TRACE: ipipe_trace_frozen_reset(); /* fall through */ case RTBNCH_RTIOC_FREEZE_TRACE: ipipe_trace_freeze((long)arg); break; case RTBNCH_RTIOC_SPECIAL_TRACE: ipipe_trace_special((long)arg, 0); break; case RTBNCH_RTIOC_SPECIAL_TRACE_EX: { struct rtbnch_trace_special special; if (user_info) { if (!rtdm_read_user_ok(user_info, arg, sizeof(struct rtbnch_trace_special)) || rtdm_copy_from_user(user_info, &special, arg, sizeof(struct rtbnch_trace_special))) return 0; } else special = *(struct rtbnch_trace_special *)arg; ipipe_trace_special(special.id, special.v); break; } default: return 0; } return 1;}#else /* !CONFIG_IPIPE_TRACE */#define tracer_ioctl(request, user_info, arg) (0)#endif /* CONFIG_IPIPE_TRACE */int rt_tmbench_ioctl_nrt(struct rtdm_dev_context *context, rtdm_user_info_t *user_info, int request, void *arg){ struct rt_tmbench_context *ctx; int ret = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -