File indexing completed on 2025-05-11 08:24:34
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 #include <rtems/record.h>
0029
0030 #include <rtems.h>
0031 #include <string.h>
0032
0033 #include <rtems/test-info.h>
0034 #include <rtems/test.h>
0035
0036 #define ITEM_CAPACITY 512
0037
0038 #define RECOMMENDED_ITEM_COUNT (ITEM_CAPACITY + 2)
0039
0040 typedef struct {
0041 bool early;
0042 bool late;
0043 bool interrupt;
0044 bool good;
0045 uint32_t how_many;
0046 rtems_record_item items[RECOMMENDED_ITEM_COUNT];
0047 } RecordFetchConcurrentContext;
0048
0049 static void action(void *arg) {
0050 RecordFetchConcurrentContext *ctx;
0051 rtems_record_fetch_control control;
0052
0053 ctx = arg;
0054 rtems_record_fetch_initialize(&control, &ctx->items[0],
0055 RTEMS_ARRAY_SIZE(ctx->items));
0056 ctx->early = false;
0057 (void)rtems_record_fetch(&control);
0058 ctx->late = true;
0059
0060 if (control.fetched_count < ITEM_CAPACITY) {
0061 size_t i;
0062
0063 ctx->good = true;
0064 T_eq_u32(RTEMS_RECORD_GET_EVENT(control.fetched_items[0].event),
0065 RTEMS_RECORD_PROCESSOR);
0066 T_eq_ulong(control.fetched_items[0].data, 0);
0067 T_eq_u32(RTEMS_RECORD_GET_EVENT(control.fetched_items[1].event),
0068 RTEMS_RECORD_PER_CPU_OVERFLOW);
0069
0070 for (i = 2; i < control.fetched_count; ++i) {
0071 rtems_record_event event;
0072
0073 event = RTEMS_RECORD_GET_EVENT(control.fetched_items[i].event);
0074 T_true(event == RTEMS_RECORD_USER_0 || event == RTEMS_RECORD_UPTIME_LOW ||
0075 event == RTEMS_RECORD_UPTIME_HIGH);
0076 }
0077 }
0078 }
0079
0080 static void prepare(void *arg) {
0081 RecordFetchConcurrentContext *ctx;
0082 uint32_t i;
0083
0084 ctx = arg;
0085 ctx->early = true;
0086 ctx->late = false;
0087 ctx->interrupt = false;
0088
0089 for (i = 0; i < RECOMMENDED_ITEM_COUNT - 2; ++i) {
0090 rtems_record_produce(RTEMS_RECORD_USER_0, 0);
0091 }
0092 }
0093
0094 static T_interrupt_test_state interrupt(void *arg) {
0095 RecordFetchConcurrentContext *ctx;
0096
0097 ctx = arg;
0098
0099 if (ctx->good) {
0100 return T_INTERRUPT_TEST_DONE;
0101 }
0102
0103 if (ctx->early) {
0104 return T_INTERRUPT_TEST_EARLY;
0105 }
0106
0107 if (ctx->late) {
0108 return T_INTERRUPT_TEST_LATE;
0109 }
0110
0111 if (!ctx->interrupt) {
0112 uint32_t i;
0113
0114 for (i = 0; i < ctx->how_many; ++i) {
0115 rtems_record_produce(RTEMS_RECORD_USER_1, 0);
0116 }
0117 }
0118
0119 ctx->interrupt = true;
0120 return T_INTERRUPT_TEST_CONTINUE;
0121 }
0122
0123 static const T_interrupt_test_config config = {.prepare = prepare,
0124 .action = action,
0125 .interrupt = interrupt,
0126 .max_iteration_count = 10000};
0127
0128 T_TEST_CASE(RecordFetchConcurrent) {
0129 RecordFetchConcurrentContext ctx;
0130
0131 memset(&ctx, 0, sizeof(ctx));
0132 ctx.how_many = ITEM_CAPACITY + 1;
0133 T_interrupt_test(&config, &ctx);
0134 T_true(ctx.good);
0135
0136 memset(&ctx, 0, sizeof(ctx));
0137 ctx.how_many = ITEM_CAPACITY / 2;
0138 T_interrupt_test(&config, &ctx);
0139 T_true(ctx.good);
0140 }
0141
0142 const char rtems_test_name[] = "RECORD 4";
0143
0144 static void Init(rtems_task_argument argument) {
0145 rtems_test_run(argument, TEST_STATE);
0146 }
0147
0148 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0149
0150 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0151
0152 #define CONFIGURE_MAXIMUM_TASKS 1
0153
0154 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0155
0156 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0157
0158 #define CONFIGURE_RECORD_PER_PROCESSOR_ITEMS 512
0159
0160 #define CONFIGURE_INIT
0161
0162 #include <rtems/confdefs.h>