source: rtems/testsuites/sptests/spcpucounter01/init.c @ 0d796d6

Last change on this file since 0d796d6 was 0d796d6, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 2, 2017 at 1:08:02 PM

tests: Delete obsolete TESTS_USE_PRINTF

Update #3170.
Update #3199.

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <stdio.h>
20#include <inttypes.h>
21
22#include <rtems.h>
23#include <rtems/counter.h>
24
25#include "tmacros.h"
26
27const char rtems_test_name[] = "SPCPUCOUNTER 1";
28
29#define NS_PER_TICK 1000000
30
31#define N 10
32
33typedef struct {
34  rtems_counter_ticks delay_ns_t[N][2];
35  rtems_counter_ticks delay_ticks_t[N][2];
36  rtems_counter_ticks overhead_t[N][5];
37  rtems_counter_ticks overhead_delta;
38} test_context;
39
40static test_context test_instance;
41
42static rtems_interval sync_with_clock_tick(void)
43{
44  rtems_interval start = rtems_clock_get_ticks_since_boot();
45  rtems_interval current;
46
47  do {
48    current = rtems_clock_get_ticks_since_boot();
49  } while (current == start);
50
51  return current;
52}
53
54static void test_converter(void)
55{
56  CPU_Counter_ticks frequency = rtems_counter_nanoseconds_to_ticks(1000000000);
57  uint64_t ns = rtems_counter_ticks_to_nanoseconds(frequency);
58
59  printf("CPU counter frequency: %" PRIu32 "Hz\n", frequency);
60  printf("nanoseconds for frequency count ticks: %" PRIu64 "\n", ns);
61
62  rtems_test_assert(ns == 1000000000);
63}
64
65static void test_delay_nanoseconds(test_context *ctx)
66{
67  int i;
68
69  for (i = 0; i < N; ++i) {
70    rtems_counter_ticks t0;
71    rtems_counter_ticks t1;
72    rtems_interval tick;
73
74    tick = sync_with_clock_tick();
75
76    t0 = rtems_counter_read();
77    rtems_counter_delay_nanoseconds(NS_PER_TICK);
78    t1 = rtems_counter_read();
79
80    ctx->delay_ns_t[i][0] = t0;
81    ctx->delay_ns_t[i][1] = t1;
82
83    rtems_test_assert(tick < rtems_clock_get_ticks_since_boot());
84  }
85}
86
87static void test_delay_ticks(test_context *ctx)
88{
89  rtems_counter_ticks ticks = rtems_counter_nanoseconds_to_ticks(NS_PER_TICK);
90  int i;
91
92  for (i = 0; i < N; ++i) {
93    rtems_counter_ticks t0;
94    rtems_counter_ticks t1;
95    rtems_interval tick;
96
97    tick = sync_with_clock_tick();
98
99    t0 = rtems_counter_read();
100    rtems_counter_delay_ticks(ticks);
101    t1 = rtems_counter_read();
102
103    ctx->delay_ticks_t[i][0] = t0;
104    ctx->delay_ticks_t[i][1] = t1;
105
106    rtems_test_assert(tick < rtems_clock_get_ticks_since_boot());
107  }
108}
109
110static void test_overheads(test_context *ctx)
111{
112  int i;
113
114  for (i = 0; i < N; ++i) {
115    rtems_counter_ticks t0;
116    rtems_counter_ticks t1;
117    rtems_counter_ticks t2;
118    rtems_counter_ticks t3;
119    rtems_counter_ticks t4;
120    rtems_counter_ticks d;
121
122    t0 = rtems_counter_read();
123    t1 = rtems_counter_read();
124    d = rtems_counter_difference(t1, t0);
125    t2 = rtems_counter_read();
126    rtems_counter_delay_nanoseconds(0);
127    t3 = rtems_counter_read();
128    rtems_counter_delay_ticks(0);
129    t4 = rtems_counter_read();
130
131    ctx->overhead_t[i][0] = t0;
132    ctx->overhead_t[i][1] = t1;
133    ctx->overhead_t[i][2] = t2;
134    ctx->overhead_t[i][3] = t3;
135    ctx->overhead_t[i][4] = t4;
136    ctx->overhead_delta = d;
137  }
138}
139
140static void report_overhead(
141  const char *name,
142  rtems_counter_ticks t1,
143  rtems_counter_ticks t0
144)
145{
146  rtems_counter_ticks d;
147  uint64_t ns;
148
149  d = rtems_counter_difference(t1, t0);
150  ns = rtems_counter_ticks_to_nanoseconds(d);
151
152  printf(
153    "overhead %s: %" PRIu64 " ticks, %" PRIu64 "ns\n",
154    name,
155    (uint64_t) d,
156    ns
157  );
158}
159
160static uint64_t large_delta_to_ns(rtems_counter_ticks d)
161{
162  uint64_t ns;
163
164  ns = rtems_counter_ticks_to_nanoseconds(d);
165
166  /* Special case for CPU counters using the clock driver counter */
167  if (ns < rtems_configuration_get_nanoseconds_per_tick()) {
168    printf(
169      "warning: the RTEMS counter seems to be unable to\n"
170      "  measure intervals greater than the clock tick interval\n"
171    );
172
173    ns += rtems_configuration_get_nanoseconds_per_tick();
174  }
175
176  return ns;
177}
178
179static void test_report(test_context *ctx)
180{
181  double ns_per_tick = NS_PER_TICK;
182  rtems_counter_ticks d;
183  uint64_t ns;
184  size_t i;
185
186  printf("test delay nanoseconds (%i times)\n", N);
187
188  for (i = 0; i < N; ++i) {
189    d = rtems_counter_difference(ctx->delay_ns_t[i][1], ctx->delay_ns_t[i][0]);
190    ns = large_delta_to_ns(d);
191
192    printf(
193      "ns busy wait duration: %" PRIu64 "ns\n"
194      "ns busy wait relative to clock tick: %f\n",
195      ns,
196      (ns - ns_per_tick) / ns_per_tick
197    );
198  }
199
200  printf("test delay ticks (%i times)\n", N);
201
202  for (i = 0; i < N; ++i) {
203    d = rtems_counter_difference(
204      ctx->delay_ticks_t[i][1],
205      ctx->delay_ticks_t[i][0]
206    );
207    ns = large_delta_to_ns(d);
208
209    printf(
210      "ticks busy wait duration: %" PRIu64 "ns\n"
211      "ticks busy wait relative to clock tick: %f\n",
212      ns,
213      (ns - ns_per_tick) / ns_per_tick
214    );
215  }
216
217  printf("test overheads (%i times)\n", N);
218
219  for (i = 0; i < N; ++i) {
220    report_overhead("read", ctx->overhead_t[i][1], ctx->overhead_t[i][0]);
221    report_overhead("difference", ctx->overhead_t[i][2], ctx->overhead_t[i][1]);
222    report_overhead("delay ns", ctx->overhead_t[i][3], ctx->overhead_t[i][2]);
223    report_overhead("delay ticks", ctx->overhead_t[i][4], ctx->overhead_t[i][3]);
224  }
225}
226
227static void Init(rtems_task_argument arg)
228{
229  test_context *ctx = &test_instance;
230
231  TEST_BEGIN();
232
233  test_delay_nanoseconds(ctx);
234  test_delay_ticks(ctx);
235  test_overheads(ctx);
236  test_converter();
237  test_report(ctx);
238
239  TEST_END();
240
241  rtems_test_exit(0);
242}
243
244#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
245#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
246
247#define CONFIGURE_MICROSECONDS_PER_TICK (NS_PER_TICK / 1000)
248
249#define CONFIGURE_MAXIMUM_TASKS 1
250
251#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
252
253#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
254
255#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
256
257#define CONFIGURE_INIT
258
259#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.