source: rtems/testsuites/tmtests/tmtimer01/init.c @ f831eff

Last change on this file since f831eff was f831eff, checked in by Sebastian Huber <sebastian.huber@…>, on Mar 2, 2016 at 7:07:58 AM

tmtests/tmtimer01: New test

Test run performed on T4240 running at 1667MHz in uni-processor
configuration.

Update #2554.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 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 "tmacros.h"
20
21#include <stdio.h>
22#include <inttypes.h>
23
24#include <rtems.h>
25#include <rtems/counter.h>
26
27const char rtems_test_name[] = "TMTIMER 1";
28
29typedef struct {
30  size_t cache_line_size;
31  size_t data_cache_size;
32  int dummy_value;
33  volatile int *dummy_data;
34  rtems_id first;
35} test_context;
36
37static test_context test_instance;
38
39static void prepare_cache(test_context *ctx)
40{
41  volatile int *data = ctx->dummy_data;
42  size_t m = ctx->data_cache_size / sizeof(*data);
43  size_t k = ctx->cache_line_size / sizeof(*data);
44  size_t j = ctx->dummy_value;
45  size_t i;
46
47  for (i = 0; i < m; i += k) {
48    data[i] = i + j;
49  }
50
51  ctx->dummy_value = i + j;
52  rtems_cache_invalidate_entire_instruction();
53}
54
55static void never(rtems_id id, void *arg)
56{
57  rtems_test_assert(0);
58}
59
60static rtems_interval interval(size_t i)
61{
62  rtems_interval d = 50000;
63
64  return i * d + d;
65}
66
67static void test_fire_and_cancel(
68  test_context *ctx,
69  size_t i,
70  size_t j,
71  const char *name
72)
73{
74  rtems_status_code sc;
75  rtems_status_code sc2;
76  rtems_counter_ticks a;
77  rtems_counter_ticks b;
78  rtems_counter_ticks d;
79  rtems_id id;
80  rtems_interrupt_level level;
81
82  id = ctx->first + i;
83  prepare_cache(ctx);
84
85  rtems_interrupt_local_disable(level);
86  a = rtems_counter_read();
87  sc = rtems_timer_fire_after(id, interval(j), never, NULL);
88  sc2 = rtems_timer_cancel(id);
89  b = rtems_counter_read();
90  rtems_interrupt_local_enable(level);
91
92  d = rtems_counter_difference(b, a);
93
94  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
95  rtems_test_assert(sc2 == RTEMS_SUCCESSFUL);
96
97  printf(
98    "<%s unit=\"ns\">%" PRIu64 "</%s>",
99    name,
100    rtems_counter_ticks_to_nanoseconds(d),
101    name
102  );
103}
104
105static void test_case(test_context *ctx, size_t j, size_t k)
106{
107  rtems_status_code sc;
108  size_t s;
109  size_t t;
110
111  s = j - k;
112
113  for (t = 0; t < s; ++t) {
114    size_t u = k + t;
115
116    sc = rtems_timer_fire_after(ctx->first + u, interval(u + 1), never, NULL);
117    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
118  }
119
120  printf("  <Sample>\n    <ActiveTimers>%zu</ActiveTimers>", j);
121
122  test_fire_and_cancel(ctx, j, 0, "First");
123  test_fire_and_cancel(ctx, j, j / 2, "Middle");
124  test_fire_and_cancel(ctx, j, j + 1, "Last");
125
126  printf("\n  </Sample>\n");
127}
128
129static void test(void)
130{
131  test_context *ctx = &test_instance;
132  rtems_status_code sc;
133  rtems_id id;
134  rtems_name n;
135  size_t j;
136  size_t k;
137  size_t timer_count;
138
139  ctx->cache_line_size = rtems_cache_get_data_line_size();
140  if (ctx->cache_line_size == 0) {
141    ctx->cache_line_size = 32;
142  }
143
144  ctx->data_cache_size = rtems_cache_get_data_cache_size(0);
145  if (ctx->data_cache_size == 0) {
146    ctx->data_cache_size = ctx->cache_line_size;
147  }
148
149  ctx->dummy_data = malloc(ctx->data_cache_size);
150  rtems_test_assert(ctx->dummy_data != NULL);
151
152  n = 1;
153  timer_count = 1;
154
155  sc = rtems_timer_create(n, &ctx->first);
156  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
157  rtems_test_assert(rtems_object_id_get_index(ctx->first) == n);
158
159  while (true) {
160    ++n;
161
162    sc = rtems_timer_create(n, &id);
163    if (sc != RTEMS_SUCCESSFUL) {
164      break;
165    }
166
167    rtems_test_assert(rtems_object_id_get_index(id) == n);
168    timer_count = n;
169  }
170
171  printf("<TMTimer01 timerCount=\"%zu\">\n", timer_count);
172
173  k = 0;
174  j = 0;
175
176  while (j < timer_count) {
177    test_case(ctx, j, k);
178    k = j;
179    j = (123 * (j + 1) + 99) / 100;
180  }
181
182  test_case(ctx, n - 2, k);
183
184  printf("</TMTimer01>\n");
185}
186
187static void Init(rtems_task_argument arg)
188{
189  TEST_BEGIN();
190
191  test();
192
193  TEST_END();
194  rtems_test_exit(0);
195}
196
197#define CONFIGURE_MICROSECONDS_PER_TICK 50000
198
199#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
200#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
201
202#define CONFIGURE_UNIFIED_WORK_AREAS
203
204#define CONFIGURE_MAXIMUM_TASKS 1
205#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(32)
206
207#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
208
209#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
210
211#define CONFIGURE_INIT
212
213#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.