From d78082ce76f241314573aa340e6e0ce4601ad16d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 29 Aug 2019 16:50:12 +0200 Subject: [PATCH] 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 | 86 ++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 39 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,6 +88,51 @@ void rtems_record_produce_n( rtems_record_commit( &context ); } +void _Record_Drain( + Record_Control *control, + uint32_t cpu_index, + rtems_record_drain_visitor visitor, + void *arg +) +{ + unsigned int tail; + unsigned int head; + + tail = _Record_Tail( control ); + head = _Atomic_Load_uint( &control->head, ATOMIC_ORDER_ACQUIRE ); + + if ( tail == head ) { + return; + } + + control->tail = 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 ( _Record_Is_overflow( control, tail, head ) ) { + tail = head + 1; + } + + tail = _Record_Index( control, tail ); + head = _Record_Index( control, head ); + + if ( tail < head ) { + ( *visitor )( &control->Items[ tail ], head - tail, arg ); + } else { + ( *visitor )( &control->Items[ tail ], control->mask + 1 - tail, arg ); + + if ( head > 0 ) { + ( *visitor )( &control->Items[ 0 ], head, arg ); + } + } +} + void rtems_record_drain( rtems_record_drain_visitor visitor, void *arg ) { uint32_t cpu_max; @@ -96,46 +141,9 @@ void rtems_record_drain( rtems_record_drain_visitor visitor, void *arg ) cpu_max = rtems_configuration_get_maximum_processors(); for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) { - Per_CPU_Control *cpu; - Record_Control *control; - unsigned int tail; - unsigned int head; + Per_CPU_Control *cpu; cpu = _Per_CPU_Get_by_index( cpu_index ); - control = cpu->record; - - tail = _Record_Tail( control ); - head = _Atomic_Load_uint( &control->head, ATOMIC_ORDER_ACQUIRE ); - - if ( tail == head ) { - continue; - } - - control->tail = 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 ( _Record_Is_overflow( control, tail, head ) ) { - tail = head + 1; - } - - tail = _Record_Index( control, tail ); - head = _Record_Index( control, head ); - - if ( tail < head ) { - ( *visitor )( &control->Items[ tail ], head - tail, arg ); - } else { - ( *visitor )( &control->Items[ tail ], control->mask + 1 - tail, arg ); - - if ( head > 0 ) { - ( *visitor )( &control->Items[ 0 ], head, arg ); - } - } + _Record_Drain( cpu->record, cpu_index, visitor, arg ); } }