Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:34

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2024 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #include <rtems/record.h>
0029 
0030 #include <rtems.h>
0031 #include <string.h>
0032 
0033 #include <rtems/test.h>
0034 #include <rtems/test-info.h>
0035 
0036 #define CHECK_ITEM(item, expected_event, expected_data)                        \
0037   do {                                                                         \
0038     T_eq_u32(RTEMS_RECORD_GET_EVENT((item)->event), expected_event);           \
0039     T_eq_ulong((item)->data, expected_data);                                   \
0040   } while (0)
0041 
0042 #ifdef RTEMS_SMP
0043 #define COUNT 17
0044 #else
0045 #define COUNT 18
0046 #endif
0047 
0048 static void
0049 check_other_cpu(rtems_record_fetch_control *control) {
0050 #ifdef RTEMS_SMP
0051   rtems_record_fetch_status status;
0052   rtems_record_item items_2[3];
0053   rtems_record_item *storage_items;
0054   size_t storage_item_count;
0055 
0056   memset(&items_2, 0xff, sizeof(items_2));
0057   storage_items = control->internal.storage_items;
0058   storage_item_count = control->internal.storage_item_count;
0059   control->internal.storage_items = items_2;
0060   control->internal.storage_item_count = RTEMS_ARRAY_SIZE(items_2);
0061   status = rtems_record_fetch(control);
0062   T_eq_int(status, RTEMS_RECORD_FETCH_CONTINUE);
0063   T_eq_ptr(control->fetched_items, &items_2[1]);
0064   T_eq_sz(control->fetched_count, 1);
0065   CHECK_ITEM(&items_2[1], RTEMS_RECORD_PROCESSOR, 0);
0066   control->internal.storage_items = storage_items;
0067   control->internal.storage_item_count = storage_item_count;
0068 #else
0069   (void)control;
0070 #endif
0071 }
0072 
0073 static uint32_t set_affinity(uint32_t cpu) {
0074 #ifdef RTEMS_SMP
0075   rtems_status_code sc;
0076   cpu_set_t set;
0077 
0078   CPU_ZERO(&set);
0079   CPU_SET((int)cpu, &set);
0080   sc = rtems_task_set_affinity(RTEMS_SELF, sizeof(set), &set);
0081   T_rsc_success(sc);
0082 #else
0083   cpu = 0;
0084 #endif
0085   return cpu;
0086 }
0087 
0088 T_TEST_CASE(RecordFetch) {
0089   rtems_record_fetch_control control;
0090   rtems_record_fetch_status status;
0091   rtems_record_item items[COUNT];
0092   uint32_t i;
0093   uint32_t cpu;
0094 
0095   T_eq_sz(rtems_record_get_item_count_for_fetch(), RTEMS_ARRAY_SIZE(items));
0096 
0097   memset(&control, 0xff, sizeof(control));
0098   rtems_record_fetch_initialize(&control, items, RTEMS_ARRAY_SIZE(items));
0099 #ifdef RTEMS_SMP
0100   T_eq_u32(control.internal.cpu_index, 0);
0101 #endif
0102   T_eq_sz(control.internal.cpu_todo, 0);
0103   T_null(control.fetched_items);
0104   T_eq_sz(control.fetched_count, 0);
0105 
0106   control.internal.storage_item_count = 2;
0107   status = rtems_record_fetch(&control);
0108   control.internal.storage_item_count = RTEMS_ARRAY_SIZE(items);
0109   T_eq_int(status, RTEMS_RECORD_FETCH_INVALID_ITEM_COUNT);
0110 
0111   cpu = set_affinity(0);
0112 
0113   /*
0114    * Fetch the initial uptime events produced by
0115    * _Record_Initialize_watchdogs().
0116    */
0117   memset(&items, 0xff, sizeof(items));
0118   status = rtems_record_fetch(&control);
0119 #ifdef RTEMS_SMP
0120   T_eq_int(status, RTEMS_RECORD_FETCH_CONTINUE);
0121 #else
0122   T_eq_int(status, RTEMS_RECORD_FETCH_DONE);
0123 #endif
0124   T_eq_ptr(control.fetched_items, &items[1]);
0125   T_eq_sz(control.fetched_count, 3);
0126   CHECK_ITEM(&items[1], RTEMS_RECORD_PROCESSOR, 0);
0127   CHECK_ITEM(&items[2], RTEMS_RECORD_UPTIME_LOW, 0);
0128   CHECK_ITEM(&items[3], RTEMS_RECORD_UPTIME_HIGH, 1);
0129 #ifdef RTEMS_SMP
0130   status = rtems_record_fetch(&control);
0131   T_eq_int(status, RTEMS_RECORD_FETCH_DONE);
0132   T_eq_ptr(control.fetched_items, &items[1]);
0133   T_eq_sz(control.fetched_count, 1);
0134   CHECK_ITEM(&items[1], RTEMS_RECORD_PROCESSOR, 1);
0135 #endif
0136 
0137   cpu = set_affinity(1);
0138 
0139   /* Fetch with no events available */
0140   memset(&items, 0xff, sizeof(items));
0141   check_other_cpu(&control);
0142   status = rtems_record_fetch(&control);
0143   T_eq_int(status, RTEMS_RECORD_FETCH_DONE);
0144   T_eq_ptr(control.fetched_items, &items[1]);
0145   T_eq_sz(control.fetched_count, 1);
0146   CHECK_ITEM(&items[1], RTEMS_RECORD_PROCESSOR, cpu);
0147 
0148   /* Fetch with overflow */
0149 
0150   for (i = 0; i < COUNT - 1; ++i) {
0151     rtems_record_produce(2 * i, 2 * i + 1);
0152   }
0153 
0154   memset(&items, 0xff, sizeof(items));
0155   check_other_cpu(&control);
0156   control.internal.storage_item_count = 4;
0157   status = rtems_record_fetch(&control);
0158   control.internal.storage_item_count = RTEMS_ARRAY_SIZE(items);
0159   T_eq_int(status, RTEMS_RECORD_FETCH_CONTINUE);
0160   T_eq_ptr(control.fetched_items, &items[0]);
0161   T_eq_sz(control.fetched_count, 4);
0162   CHECK_ITEM(&items[0], RTEMS_RECORD_PROCESSOR, cpu);
0163   CHECK_ITEM(&items[1], RTEMS_RECORD_PER_CPU_OVERFLOW, 1);
0164   CHECK_ITEM(&items[2], 2, 3);
0165   CHECK_ITEM(&items[3], 4, 5);
0166 
0167   status = rtems_record_fetch(&control);
0168   T_eq_int(status, RTEMS_RECORD_FETCH_DONE);
0169   T_eq_ptr(control.fetched_items, &items[1]);
0170   T_eq_sz(control.fetched_count, COUNT - 3);
0171   CHECK_ITEM(&items[1], RTEMS_RECORD_PROCESSOR, cpu);
0172 
0173   for (i = 0; i < COUNT - 4; ++i) {
0174     CHECK_ITEM(&items[i + 2], 2 * i + 6, 2 * i + 7);
0175   }
0176 }
0177 
0178 const char rtems_test_name[] = "RECORD 3";
0179 
0180 static void Init(rtems_task_argument argument)
0181 {
0182   rtems_test_run(argument, TEST_STATE);
0183 }
0184 
0185 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0186 
0187 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0188 
0189 #define CONFIGURE_MAXIMUM_TASKS 1
0190 
0191 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0192 
0193 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0194 
0195 #define CONFIGURE_MAXIMUM_PROCESSORS 2
0196 
0197 #define CONFIGURE_RECORD_PER_PROCESSOR_ITEMS 16
0198 
0199 #define CONFIGURE_INIT
0200 
0201 #include <rtems/confdefs.h>