source: rtems/testsuites/sptests/spintrcritical24/init.c @ 6b795cd7

Last change on this file since 6b795cd7 was 6b795cd7, checked in by Sebastian Huber <sebastian.huber@…>, on 07/20/20 at 05:45:51

spintrcritical24: Use T_interrupt_test()

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (C) 2017, 2020 embedded brains GmbH (http://www.embedded-brains.de)
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include <sys/stat.h>
14#include <errno.h>
15#include <fcntl.h>
16#include <string.h>
17#include <unistd.h>
18
19#include <rtems/imfs.h>
20#include <rtems/libio_.h>
21#include <rtems/test-info.h>
22#include <rtems/test.h>
23
24const char rtems_test_name[] = "SPINTRCRITICAL 24";
25
26typedef struct {
27  int fd;
28  rtems_libio_t *iop;
29  long early_count;
30  long late_count;
31  long potential_hit_count;
32  long append_count;
33  long no_append_count;
34  volatile bool closed;
35} test_context;
36
37static const char path[] = "generic";
38
39static int handler_close(rtems_libio_t *iop)
40{
41  test_context *ctx;
42
43  ctx = IMFS_generic_get_context_by_iop(iop);
44  ctx->closed = true;
45
46  if (rtems_libio_iop_is_append(iop)) {
47    ++ctx->append_count;
48  } else {
49    ++ctx->no_append_count;
50  }
51
52  return 0;
53}
54
55static const rtems_filesystem_file_handlers_r node_handlers = {
56  .open_h = rtems_filesystem_default_open,
57  .close_h = handler_close,
58  .fstat_h = rtems_filesystem_default_fstat,
59  .fcntl_h = rtems_filesystem_default_fcntl
60};
61
62static const IMFS_node_control node_control = {
63  .handlers = &node_handlers,
64  .node_initialize = IMFS_node_initialize_generic,
65  .node_remove = IMFS_node_remove_default,
66  .node_destroy = IMFS_node_destroy_default
67};
68
69static T_interrupt_test_state interrupt(void *arg)
70{
71  test_context *ctx;
72  T_interrupt_test_state state;
73  int rv;
74  unsigned int flags;
75
76  state = T_interrupt_test_get_state();
77
78  if (state != T_INTERRUPT_TEST_ACTION) {
79    return T_INTERRUPT_TEST_CONTINUE;
80  }
81
82  ctx = arg;
83  flags = rtems_libio_iop_flags_set(ctx->iop, 0);
84
85  if ((flags & LIBIO_FLAGS_OPEN) != 0) {
86    ++ctx->early_count;
87    state = T_INTERRUPT_TEST_EARLY;
88  } else if (ctx->closed) {
89    ++ctx->late_count;
90    state = T_INTERRUPT_TEST_LATE;
91  } else {
92    ++ctx->potential_hit_count;
93
94    if (ctx->potential_hit_count >= 13) {
95      state = T_INTERRUPT_TEST_DONE;
96    } else {
97      state = T_INTERRUPT_TEST_CONTINUE;
98    }
99  }
100
101  rv = fcntl(ctx->fd, F_SETFL, O_APPEND);
102
103  if (rv != 0) {
104    T_quiet_psx_error(rv, EBADF);
105  }
106
107  return state;
108}
109
110static void prepare(void *arg)
111{
112  test_context *ctx;
113
114  ctx = arg;
115
116  ctx->fd = open(path, O_RDWR);
117  T_quiet_ge_int(ctx->fd, 0);
118
119  ctx->closed = false;
120  ctx->iop = rtems_libio_iop(ctx->fd);
121}
122
123static void action(void *arg)
124{
125  test_context *ctx;
126  int rv;
127
128  ctx = arg;
129
130  rv = close(ctx->fd);
131  T_quiet_psx_success(rv);
132
133  T_interrupt_test_busy_wait_for_interrupt();
134}
135
136static const T_interrupt_test_config config = {
137  .prepare = prepare,
138  .action = action,
139  .interrupt = interrupt,
140  .max_iteration_count = 10000
141};
142
143T_TEST_CASE(CloseInterrupt)
144{
145  test_context ctx;
146  const char *path = "generic";
147  int rv;
148  T_interrupt_test_state state;
149
150  memset(&ctx, 0, sizeof(ctx));
151
152  rv = IMFS_make_generic_node(
153    path,
154    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
155    &node_control,
156    &ctx
157  );
158  T_psx_success(rv);
159
160  state = T_interrupt_test(&config, &ctx);
161  T_eq_int(state, T_INTERRUPT_TEST_DONE);
162
163  T_log(T_NORMAL, "early count = %ld", ctx.early_count);
164  T_log(T_NORMAL, "late count = %ld", ctx.late_count);
165  T_log(T_NORMAL, "potential hit count = %ld", ctx.potential_hit_count);
166  T_log(T_NORMAL, "append count = %ld", ctx.append_count);
167  T_log(T_NORMAL, "no append count = %ld", ctx.no_append_count);
168
169  /* There is no reliable indicator if the test case has been hit */
170  T_gt_int(ctx.early_count, 0);
171  T_gt_int(ctx.late_count, 0);
172  T_gt_int(ctx.potential_hit_count, 0);
173  T_gt_int(ctx.append_count, 0);
174  T_gt_int(ctx.no_append_count, 0);
175
176  rv = unlink(path);
177  T_psx_success(rv);
178}
179
180static void Init(rtems_task_argument arg)
181{
182  rtems_test_run(arg, TEST_STATE);
183}
184
185#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
186#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
187
188#define CONFIGURE_MICROSECONDS_PER_TICK 1000
189
190#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
191
192#define CONFIGURE_MAXIMUM_TASKS 1
193
194#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
195
196#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
197
198#define CONFIGURE_INIT
199
200#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.