File indexing completed on 2025-05-11 08:24:47
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 <sys/stat.h>
0033 #include <errno.h>
0034 #include <fcntl.h>
0035 #include <string.h>
0036 #include <unistd.h>
0037
0038 #include <rtems/imfs.h>
0039 #include <rtems/libio_.h>
0040 #include <rtems/test-info.h>
0041 #include <rtems/test.h>
0042
0043 const char rtems_test_name[] = "SPINTRCRITICAL 24";
0044
0045 typedef struct {
0046 int fd;
0047 rtems_libio_t *iop;
0048 long early_count;
0049 long late_count;
0050 long potential_hit_count;
0051 long append_count;
0052 long no_append_count;
0053 volatile bool closed;
0054 } test_context;
0055
0056 static const char path[] = "generic";
0057
0058 static int handler_close(rtems_libio_t *iop)
0059 {
0060 test_context *ctx;
0061
0062 ctx = IMFS_generic_get_context_by_iop(iop);
0063 ctx->closed = true;
0064
0065 if (rtems_libio_iop_is_append(iop)) {
0066 ++ctx->append_count;
0067 } else {
0068 ++ctx->no_append_count;
0069 }
0070
0071 return 0;
0072 }
0073
0074 static const rtems_filesystem_file_handlers_r node_handlers = {
0075 .open_h = rtems_filesystem_default_open,
0076 .close_h = handler_close,
0077 .fstat_h = rtems_filesystem_default_fstat,
0078 .fcntl_h = rtems_filesystem_default_fcntl
0079 };
0080
0081 static const IMFS_node_control node_control = {
0082 .handlers = &node_handlers,
0083 .node_initialize = IMFS_node_initialize_generic,
0084 .node_remove = IMFS_node_remove_default,
0085 .node_destroy = IMFS_node_destroy_default
0086 };
0087
0088 static T_interrupt_test_state interrupt(void *arg)
0089 {
0090 test_context *ctx;
0091 T_interrupt_test_state state;
0092 int rv;
0093 unsigned int flags;
0094
0095 state = T_interrupt_test_get_state();
0096
0097 if (state != T_INTERRUPT_TEST_ACTION) {
0098 return T_INTERRUPT_TEST_CONTINUE;
0099 }
0100
0101 ctx = arg;
0102 flags = rtems_libio_iop_flags_set(ctx->iop, 0);
0103
0104 if ((flags & LIBIO_FLAGS_OPEN) != 0) {
0105 ++ctx->early_count;
0106 state = T_INTERRUPT_TEST_EARLY;
0107 } else if (ctx->closed) {
0108 ++ctx->late_count;
0109 state = T_INTERRUPT_TEST_LATE;
0110 } else {
0111 ++ctx->potential_hit_count;
0112
0113 if (ctx->potential_hit_count >= 13) {
0114 state = T_INTERRUPT_TEST_DONE;
0115 } else {
0116 state = T_INTERRUPT_TEST_CONTINUE;
0117 }
0118 }
0119
0120 rv = fcntl(ctx->fd, F_SETFL, O_APPEND);
0121
0122 if (rv != 0) {
0123 T_quiet_psx_error(rv, EBADF);
0124 }
0125
0126 return state;
0127 }
0128
0129 static void prepare(void *arg)
0130 {
0131 test_context *ctx;
0132
0133 ctx = arg;
0134
0135 ctx->fd = open(path, O_RDWR);
0136 T_quiet_ge_int(ctx->fd, 0);
0137
0138 ctx->closed = false;
0139 ctx->iop = rtems_libio_iop(ctx->fd);
0140 }
0141
0142 static void action(void *arg)
0143 {
0144 test_context *ctx;
0145 int rv;
0146
0147 ctx = arg;
0148
0149 rv = close(ctx->fd);
0150 T_quiet_psx_success(rv);
0151
0152 T_interrupt_test_busy_wait_for_interrupt();
0153 }
0154
0155 static const T_interrupt_test_config config = {
0156 .prepare = prepare,
0157 .action = action,
0158 .interrupt = interrupt,
0159 .max_iteration_count = 10000
0160 };
0161
0162 T_TEST_CASE(CloseInterrupt)
0163 {
0164 test_context ctx;
0165 const char *path = "generic";
0166 int rv;
0167 T_interrupt_test_state state;
0168
0169 memset(&ctx, 0, sizeof(ctx));
0170
0171 rv = IMFS_make_generic_node(
0172 path,
0173 S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
0174 &node_control,
0175 &ctx
0176 );
0177 T_psx_success(rv);
0178
0179 state = T_interrupt_test(&config, &ctx);
0180 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0181
0182 T_log(T_NORMAL, "early count = %ld", ctx.early_count);
0183 T_log(T_NORMAL, "late count = %ld", ctx.late_count);
0184 T_log(T_NORMAL, "potential hit count = %ld", ctx.potential_hit_count);
0185 T_log(T_NORMAL, "append count = %ld", ctx.append_count);
0186 T_log(T_NORMAL, "no append count = %ld", ctx.no_append_count);
0187
0188
0189 T_gt_int(ctx.early_count, 0);
0190 T_gt_int(ctx.late_count, 0);
0191 T_gt_int(ctx.potential_hit_count, 0);
0192 T_gt_int(ctx.append_count, 0);
0193 T_gt_int(ctx.no_append_count, 0);
0194
0195 rv = unlink(path);
0196 T_psx_success(rv);
0197 }
0198
0199 static void Init(rtems_task_argument arg)
0200 {
0201 rtems_test_run(arg, TEST_STATE);
0202 }
0203
0204 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0205 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0206
0207 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0208
0209 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
0210
0211 #define CONFIGURE_MAXIMUM_TASKS 1
0212
0213 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0214
0215 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0216
0217 #define CONFIGURE_INIT
0218
0219 #include <rtems/confdefs.h>