File indexing completed on 2025-05-11 08:24:21
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
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <rtems/record.h>
0041
0042 #include <rtems.h>
0043 #include <string.h>
0044
0045
0046
0047
0048
0049 #define RECORD_FETCH_HEADER_ITEMS 2
0050
0051 size_t rtems_record_get_item_count_for_fetch( void )
0052 {
0053 return _Record_Configuration.item_count + RECORD_FETCH_HEADER_ITEMS
0054 #ifdef RTEMS_SMP
0055
0056 - 1
0057 #endif
0058 ;
0059 }
0060
0061 void rtems_record_fetch_initialize(
0062 rtems_record_fetch_control *control,
0063 rtems_record_item *items,
0064 size_t count
0065 )
0066 {
0067 control = memset( control, 0, sizeof( *control ) );
0068 control->internal.storage_items = items;
0069 control->internal.storage_item_count = count;
0070 }
0071
0072
0073 rtems_record_fetch_status rtems_record_fetch(
0074 rtems_record_fetch_control *control
0075 )
0076 {
0077 rtems_record_fetch_status status;
0078 rtems_record_item *items;
0079 size_t count;
0080 uint32_t cpu_index;
0081 Per_CPU_Control *cpu;
0082 Record_Control *record_control;
0083 rtems_record_item *item;
0084 unsigned int mask;
0085 unsigned int red_zone;
0086 unsigned int capacity;
0087 unsigned int tail;
0088 unsigned int head;
0089 unsigned int available;
0090 unsigned int overflow;
0091 unsigned int new_tail;
0092 unsigned int new_items;
0093 rtems_record_item *fetched_items;
0094 size_t fetched_count;
0095
0096 items = control->internal.storage_items;
0097 count = control->internal.storage_item_count;
0098
0099 if ( count < RECORD_FETCH_HEADER_ITEMS + 1 ) {
0100 control->fetched_items = 0;
0101 return RTEMS_RECORD_FETCH_INVALID_ITEM_COUNT;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 #ifdef RTEMS_SMP
0118 red_zone = 1;
0119 #else
0120 red_zone = 0;
0121 #endif
0122
0123 #ifdef RTEMS_SMP
0124 cpu_index = control->internal.cpu_index;
0125 #else
0126 cpu_index = 0;
0127 #endif
0128 cpu = _Per_CPU_Get_by_index( cpu_index );
0129 record_control = cpu->record;
0130 mask = record_control->mask;
0131 capacity = mask + 1 - red_zone;
0132 tail = _Record_Tail( record_control );
0133 head = _Record_Head( record_control );
0134
0135 available = control->internal.cpu_todo;
0136 control->internal.cpu_todo = 0;
0137
0138 if ( available == 0 ) {
0139 available = head - tail;
0140 }
0141
0142 if ( available > capacity ) {
0143 overflow = available - capacity;
0144 available = capacity;
0145 tail = head - capacity;
0146 } else {
0147 overflow = 0;
0148 }
0149
0150 if ( available + RECORD_FETCH_HEADER_ITEMS > count ) {
0151 control->internal.cpu_todo = available - count + RECORD_FETCH_HEADER_ITEMS;
0152 available = count - RECORD_FETCH_HEADER_ITEMS;
0153 status = RTEMS_RECORD_FETCH_CONTINUE;
0154 } else {
0155 #ifdef RTEMS_SMP
0156 if ( cpu_index + 1 < rtems_scheduler_get_processor_maximum() ) {
0157 control->internal.cpu_index = cpu_index + 1;
0158 status = RTEMS_RECORD_FETCH_CONTINUE;
0159 } else {
0160 control->internal.cpu_index = 0;
0161 status = RTEMS_RECORD_FETCH_DONE;
0162 }
0163 #else
0164 status = RTEMS_RECORD_FETCH_DONE;
0165 #endif
0166 }
0167
0168 new_tail = tail + available;
0169 record_control->tail = new_tail;
0170 item = items + 2;
0171
0172 while ( tail != new_tail ) {
0173 *item = record_control->Items[ tail & mask ];
0174 ++item;
0175 ++tail;
0176 }
0177
0178 fetched_items = items + RECORD_FETCH_HEADER_ITEMS;
0179 fetched_count = available;
0180 new_items = _Record_Head( record_control ) - head;
0181
0182 if ( available + new_items > capacity ) {
0183 unsigned int overwritten;
0184
0185 overwritten = available + new_items - capacity;
0186 overflow += overwritten;
0187
0188 if ( overwritten > available ) {
0189 overwritten = available;
0190 }
0191
0192 fetched_items += overwritten;
0193 fetched_count -= overwritten;
0194 }
0195
0196 if ( overflow > 0 ) {
0197 --fetched_items;
0198 ++fetched_count;
0199 fetched_items->event = RTEMS_RECORD_PER_CPU_OVERFLOW;
0200 fetched_items->data = overflow;
0201 }
0202
0203 --fetched_items;
0204 ++fetched_count;
0205 fetched_items->event = RTEMS_RECORD_PROCESSOR;
0206 fetched_items->data = cpu_index;
0207
0208 control->fetched_items = fetched_items;
0209 control->fetched_count = fetched_count;
0210 return status;
0211 }