File indexing completed on 2025-05-11 08:24:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include "tmacros.h"
0033
0034 #include <stdio.h>
0035 #include <inttypes.h>
0036
0037 #include <rtems.h>
0038 #include <rtems/counter.h>
0039
0040 const char rtems_test_name[] = "TMTIMER 1";
0041
0042 typedef struct {
0043 size_t cache_line_size;
0044 size_t data_cache_size;
0045 int dummy_value;
0046 volatile int *dummy_data;
0047 rtems_id first;
0048 } test_context;
0049
0050 static test_context test_instance;
0051
0052 static void prepare_cache(test_context *ctx)
0053 {
0054 volatile int *data = ctx->dummy_data;
0055 size_t m = ctx->data_cache_size / sizeof(*data);
0056 size_t k = ctx->cache_line_size / sizeof(*data);
0057 size_t j = ctx->dummy_value;
0058 size_t i;
0059
0060 for (i = 0; i < m; i += k) {
0061 data[i] = i + j;
0062 }
0063
0064 ctx->dummy_value = i + j;
0065 rtems_cache_invalidate_entire_instruction();
0066 }
0067
0068 static void never(rtems_id id, void *arg)
0069 {
0070 rtems_test_assert(0);
0071 }
0072
0073 static rtems_interval interval(size_t i)
0074 {
0075 rtems_interval d = 50000;
0076
0077 return i * d + d;
0078 }
0079
0080 static void test_fire_and_cancel(
0081 test_context *ctx,
0082 size_t i,
0083 size_t j,
0084 const char *name
0085 )
0086 {
0087 rtems_status_code sc;
0088 rtems_status_code sc2;
0089 rtems_counter_ticks a;
0090 rtems_counter_ticks b;
0091 rtems_counter_ticks d;
0092 rtems_id id;
0093 rtems_interrupt_level level;
0094
0095 id = ctx->first + i;
0096 prepare_cache(ctx);
0097
0098 rtems_interrupt_local_disable(level);
0099 a = rtems_counter_read();
0100 sc = rtems_timer_fire_after(id, interval(j), never, NULL);
0101 sc2 = rtems_timer_cancel(id);
0102 b = rtems_counter_read();
0103 rtems_interrupt_local_enable(level);
0104
0105 d = rtems_counter_difference(b, a);
0106
0107 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0108 rtems_test_assert(sc2 == RTEMS_SUCCESSFUL);
0109
0110 printf(
0111 ",\n \"%s\": %" PRIu64,
0112 name,
0113 rtems_counter_ticks_to_nanoseconds(d)
0114 );
0115 }
0116
0117 static const char *sep = "\n ";
0118
0119 static void test_case(test_context *ctx, size_t j, size_t k)
0120 {
0121 rtems_status_code sc;
0122 size_t s;
0123 size_t t;
0124
0125 s = j - k;
0126
0127 for (t = 0; t < s; ++t) {
0128 size_t u = k + t;
0129
0130 sc = rtems_timer_fire_after(ctx->first + u, interval(u + 1), never, NULL);
0131 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0132 }
0133
0134 printf(
0135 "%s{\n"
0136 " \"active-timers\": %zu",
0137 sep,
0138 j
0139 );
0140 sep = "\n }, ";
0141
0142 test_fire_and_cancel(ctx, j, 0, "first");
0143 test_fire_and_cancel(ctx, j, j / 2, "middle");
0144 test_fire_and_cancel(ctx, j, j + 1, "last");
0145 }
0146
0147 static void test(void)
0148 {
0149 test_context *ctx = &test_instance;
0150 rtems_status_code sc;
0151 rtems_id id;
0152 rtems_name n;
0153 size_t j;
0154 size_t k;
0155 size_t timer_count;
0156
0157 ctx->cache_line_size = rtems_cache_get_data_line_size();
0158 if (ctx->cache_line_size == 0) {
0159 ctx->cache_line_size = 32;
0160 }
0161
0162 ctx->data_cache_size = rtems_cache_get_data_cache_size(0);
0163 if (ctx->data_cache_size == 0) {
0164 ctx->data_cache_size = ctx->cache_line_size;
0165 }
0166
0167 ctx->dummy_data = malloc(ctx->data_cache_size);
0168 rtems_test_assert(ctx->dummy_data != NULL);
0169
0170 n = 1;
0171 timer_count = 1;
0172
0173 sc = rtems_timer_create(n, &ctx->first);
0174 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0175 rtems_test_assert(rtems_object_id_get_index(ctx->first) == n);
0176
0177 while (true) {
0178 ++n;
0179
0180 sc = rtems_timer_create(n, &id);
0181 if (sc != RTEMS_SUCCESSFUL) {
0182 break;
0183 }
0184
0185 rtems_test_assert(rtems_object_id_get_index(id) == n);
0186 timer_count = n;
0187 }
0188
0189 printf(
0190 "*** BEGIN OF JSON DATA ***\n"
0191 "{\n"
0192 " \"timer-count\": %zu,\n"
0193 " \"samples\": [",
0194 timer_count
0195 );
0196
0197 k = 0;
0198 j = 0;
0199
0200 while (j < timer_count) {
0201 test_case(ctx, j, k);
0202 k = j;
0203 j = (123 * (j + 1) + 99) / 100;
0204 }
0205
0206 test_case(ctx, n - 2, k);
0207
0208 printf("\n }\n ]\n}\n*** END OF JSON DATA ***\n");
0209 }
0210
0211 static void Init(rtems_task_argument arg)
0212 {
0213 TEST_BEGIN();
0214
0215 test();
0216
0217 TEST_END();
0218 rtems_test_exit(0);
0219 }
0220
0221 #define CONFIGURE_MICROSECONDS_PER_TICK 50000
0222
0223 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0224 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0225
0226 #define CONFIGURE_UNIFIED_WORK_AREAS
0227
0228 #define CONFIGURE_MAXIMUM_TASKS 1
0229 #define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(32)
0230
0231 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0232
0233 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0234
0235 #define CONFIGURE_INIT
0236
0237 #include <rtems/confdefs.h>