From d78082ce76f241314573aa340e6e0ce4601ad16d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 29 Aug 2019 16:50:12 +0200 Subject: record: Introduce _Record_Drain() This allows its use in crash dump procedures. Update #3665. --- cpukit/include/rtems/record.h | 7 ++++ cpukit/libtrace/record/record.c | 80 ++++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/cpukit/include/rtems/record.h b/cpukit/include/rtems/record.h index 2d1b2f4809..b667b46fa3 100644 --- a/cpukit/include/rtems/record.h +++ b/cpukit/include/rtems/record.h @@ -1054,6 +1054,13 @@ typedef void ( *rtems_record_drain_visitor )( void *arg ); +void _Record_Drain( + Record_Control *control, + uint32_t cpu_index, + rtems_record_drain_visitor visitor, + void *arg +); + /** * @brief Drains the record items on all processors. * diff --git a/cpukit/libtrace/record/record.c b/cpukit/libtrace/record/record.c index 996b861cf6..848e67e5ee 100644 --- a/cpukit/libtrace/record/record.c +++ b/cpukit/libtrace/record/record.c @@ -88,54 +88,62 @@ void rtems_record_produce_n( rtems_record_commit( &context ); } -void rtems_record_drain( rtems_record_drain_visitor visitor, void *arg ) +void _Record_Drain( + Record_Control *control, + uint32_t cpu_index, + rtems_record_drain_visitor visitor, + void *arg +) { - uint32_t cpu_max; - uint32_t cpu_index; + unsigned int tail; + unsigned int head; - cpu_max = rtems_configuration_get_maximum_processors(); + tail = _Record_Tail( control ); + head = _Atomic_Load_uint( &control->head, ATOMIC_ORDER_ACQUIRE ); - for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) { - Per_CPU_Control *cpu; - Record_Control *control; - unsigned int tail; - unsigned int head; + if ( tail == head ) { + return; + } - cpu = _Per_CPU_Get_by_index( cpu_index ); - control = cpu->record; + control->tail = head; - tail = _Record_Tail( control ); - head = _Atomic_Load_uint( &control->head, ATOMIC_ORDER_ACQUIRE ); + control->Header[ 0 ].event = RTEMS_RECORD_PROCESSOR; + control->Header[ 0 ].data = cpu_index; + control->Header[ 1 ].event = RTEMS_RECORD_PER_CPU_TAIL; + control->Header[ 1 ].data = tail; + control->Header[ 2 ].event = RTEMS_RECORD_PER_CPU_HEAD; + control->Header[ 2 ].data = head; + ( *visitor )( control->Header, RTEMS_ARRAY_SIZE( control->Header ), arg ); - if ( tail == head ) { - continue; - } + if ( _Record_Is_overflow( control, tail, head ) ) { + tail = head + 1; + } - control->tail = head; + tail = _Record_Index( control, tail ); + head = _Record_Index( control, head ); - control->Header[ 0 ].event = RTEMS_RECORD_PROCESSOR; - control->Header[ 0 ].data = cpu_index; - control->Header[ 1 ].event = RTEMS_RECORD_PER_CPU_TAIL; - control->Header[ 1 ].data = tail; - control->Header[ 2 ].event = RTEMS_RECORD_PER_CPU_HEAD; - control->Header[ 2 ].data = head; - ( *visitor )( control->Header, RTEMS_ARRAY_SIZE( control->Header ), arg ); + if ( tail < head ) { + ( *visitor )( &control->Items[ tail ], head - tail, arg ); + } else { + ( *visitor )( &control->Items[ tail ], control->mask + 1 - tail, arg ); - if ( _Record_Is_overflow( control, tail, head ) ) { - tail = head + 1; + if ( head > 0 ) { + ( *visitor )( &control->Items[ 0 ], head, arg ); } + } +} + +void rtems_record_drain( rtems_record_drain_visitor visitor, void *arg ) +{ + uint32_t cpu_max; + uint32_t cpu_index; - tail = _Record_Index( control, tail ); - head = _Record_Index( control, head ); + cpu_max = rtems_configuration_get_maximum_processors(); - if ( tail < head ) { - ( *visitor )( &control->Items[ tail ], head - tail, arg ); - } else { - ( *visitor )( &control->Items[ tail ], control->mask + 1 - tail, arg ); + for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) { + Per_CPU_Control *cpu; - if ( head > 0 ) { - ( *visitor )( &control->Items[ 0 ], head, arg ); - } - } + cpu = _Per_CPU_Get_by_index( cpu_index ); + _Record_Drain( cpu->record, cpu_index, visitor, arg ); } } -- cgit v1.2.3