RTEMS  5.0.0
record.h
1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (C) 2018, 2019 embedded brains GmbH
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef _RTEMS_RECORD_H
29 #define _RTEMS_RECORD_H
30 
31 #include "recorddata.h"
32 
33 #include <rtems/score/atomic.h>
34 #include <rtems/score/cpu.h>
35 #include <rtems/score/percpudata.h>
36 #include <rtems/score/watchdog.h>
37 #include <rtems/rtems/intr.h>
38 #include <rtems/rtems/tasks.h>
39 #include <rtems/counter.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif /* __cplusplus */
44 
46  Atomic_Uint head;
47  unsigned int tail;
48  unsigned int mask;
49  Watchdog_Control Watchdog;
50  rtems_record_item Header[ 3 ];
51  rtems_record_item Items[ RTEMS_ZERO_LENGTH_ARRAY ];
52 };
53 
54 typedef struct Record_Control Record_Control;
55 
57  struct Record_Configured_control Record_Configured_control;
58 
59 typedef struct {
60  Record_Control *control;
61  unsigned int head;
62  uint32_t now;
65 
66 PER_CPU_DATA_ITEM_DECLARE( Record_Configured_control, _Record_Per_CPU );
67 
68 extern const unsigned int _Record_Item_count;
69 
70 void _Record_Initialize( void );
71 
72 bool _Record_Thread_create(
73  struct _Thread_Control *executing,
74  struct _Thread_Control *created
75 );
76 
77 void _Record_Thread_start(
78  struct _Thread_Control *executing,
79  struct _Thread_Control *started
80 );
81 
82 void _Record_Thread_restart(
83  struct _Thread_Control *executing,
84  struct _Thread_Control *restarted
85 );
86 
87 void _Record_Thread_delete(
88  struct _Thread_Control *executing,
89  struct _Thread_Control *deleted
90 );
91 
92 void _Record_Thread_switch(
93  struct _Thread_Control *executing,
94  struct _Thread_Control *heir
95 );
96 
97 void _Record_Thread_begin( struct _Thread_Control *executing );
98 
99 void _Record_Thread_exitted( struct _Thread_Control *executing );
100 
101 void _Record_Thread_terminate(
102  struct _Thread_Control *executing
103 );
104 
105 #define RECORD_EXTENSION \
106  { \
107  _Record_Thread_create, \
108  _Record_Thread_start, \
109  _Record_Thread_restart, \
110  _Record_Thread_delete, \
111  _Record_Thread_switch, \
112  _Record_Thread_begin, \
113  _Record_Thread_exitted, \
114  NULL, \
115  _Record_Thread_terminate \
116  }
117 
118 RTEMS_INLINE_ROUTINE unsigned int _Record_Index(
119  const Record_Control *control,
120  unsigned int index
121 )
122 {
123  return index & control->mask;
124 }
125 
126 RTEMS_INLINE_ROUTINE unsigned int _Record_Head( const Record_Control *control )
127 {
128  return _Atomic_Load_uint( &control->head, ATOMIC_ORDER_RELAXED );
129 }
130 
131 RTEMS_INLINE_ROUTINE unsigned int _Record_Tail( const Record_Control *control )
132 {
133  return control->tail;
134 }
135 
136 RTEMS_INLINE_ROUTINE bool _Record_Is_overflow(
137  const Record_Control *control,
138  unsigned int tail,
139  unsigned int head
140 )
141 {
142  return head - tail >= control->mask + 1U;
143 }
144 
145 RTEMS_INLINE_ROUTINE unsigned int _Record_Capacity(
146  const Record_Control *control,
147  unsigned int tail,
148  unsigned int head
149 )
150 {
151  return ( tail - head - 1U ) & control->mask;
152 }
153 
154 RTEMS_INLINE_ROUTINE rtems_counter_ticks _Record_Now( void )
155 {
156  return rtems_counter_read();
157 }
158 
159 typedef struct RTEMS_PACKED {
160  uint32_t format;
161  uint32_t magic;
162  rtems_record_item Version;
163  rtems_record_item Processor_maximum;
164  rtems_record_item Count;
165  rtems_record_item Frequency;
167 
168 void _Record_Stream_header_initialize( Record_Stream_header *header );
169 
188 {
189  rtems_interrupt_level level;
190  const Per_CPU_Control *cpu_self;
191  Record_Control *control;
192  unsigned int head;
193 
195  context->now = RTEMS_RECORD_TIME_EVENT( _Record_Now(), 0 );
196  context->level = level;
197  cpu_self = _Per_CPU_Get();
198  control = cpu_self->record;
199  context->control = control;
200  head = _Record_Head( control );
201  context->head = head;
202 }
203 
213  rtems_record_event event,
214  rtems_record_data data
215 )
216 {
217  Record_Control *control;
218  rtems_record_item *item;
219  unsigned int head;
220 
221  control = context->control;
222  head = context->head;
223  item = &control->Items[ _Record_Index( control, head ) ];
224  context->head = head + 1;
225 
226  item->event = context->now | event;
227  item->data = data;
228 }
229 
236 {
237  _Atomic_Store_uint(
238  &context->control->head,
239  context->head,
240  ATOMIC_ORDER_RELEASE
241  );
242  rtems_interrupt_local_enable( context->level );
243 }
244 
252 
262  rtems_record_event event_0,
263  rtems_record_data data_0,
264  rtems_record_event event_1,
265  rtems_record_data data_1
266 );
267 
275  const rtems_record_item *items,
276  size_t n
277 );
278 
279 typedef void ( *rtems_record_drain_visitor )(
280  const rtems_record_item *items,
281  size_t count,
282  void *arg
283 );
284 
293 void rtems_record_drain( rtems_record_drain_visitor visitor, void *arg );
294 
305 ssize_t rtems_record_writev( int fd, bool *written );
306 
313 void rtems_record_server( uint16_t port, rtems_interval period );
314 
323  rtems_task_priority priority,
324  uint16_t port,
325  rtems_interval period
326 );
327 
330 #ifdef __cplusplus
331 }
332 #endif /* __cplusplus */
333 
334 #endif /* _RTEMS_RECORD_H */
#define PER_CPU_DATA_ITEM_DECLARE(type, item)
Declares a per-CPU item of the specified type.
Definition: percpudata.h:49
#define CPU_CACHE_LINE_BYTES
Definition: cpu.h:218
void rtems_record_produce_2(rtems_record_event event_0, rtems_record_data data_0, rtems_record_event event_1, rtems_record_data data_1)
Produces two record items.
Definition: record.c:56
Watchdog_Interval rtems_interval
Used to manage and manipulate intervals specified by clock ticks.
Definition: types.h:127
Definition: record.h:45
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:65
Definition: mknod-pack_dev.c:254
rtems_record_event
The record events.
Definition: recorddata.h:88
The control block used to manage each watchdog timer.
Definition: watchdog.h:87
void rtems_record_produce_n(const rtems_record_item *items, size_t n)
Produces n record items.
Definition: record.c:71
Atomic Operations API.
void rtems_record_produce(rtems_record_event event, rtems_record_data data)
Produces a record item.
Definition: record.c:47
RTEMS_INLINE_ROUTINE void rtems_record_commit(rtems_record_context *context)
Commits a set of record items.
Definition: record.h:235
void rtems_record_server(uint16_t port, rtems_interval period)
Runs a record TCP server loop.
Definition: record-server.c:168
ssize_t rtems_record_writev(int fd, bool *written)
Drains the record items on all processors an writes them to the file descriptor.
Definition: record-server.c:74
rtems_status_code
Classic API Status.
Definition: status.h:43
Definition: thread.h:728
#define rtems_interrupt_local_enable(_isr_cookie)
This macro restores the previous interrupt level on the current processor.
Definition: intr.h:148
RTEMS_INLINE_ROUTINE void rtems_record_add(rtems_record_context *context, rtems_record_event event, rtems_record_data data)
Adds a record item.
Definition: record.h:211
Per CPU Core Structure.
Definition: percpu.h:290
Classic Task Manager API.
#define RTEMS_RECORD_TIME_EVENT(time, event)
Builds a time event for the specified time stamp and event.
Definition: recorddata.h:1148
Free-Running Counter and Busy Wait Delay API.
Constants and Structures Associated with Watchdog Timers.
Used for passing and retrieving registers content to/from real mode interrupt call.
Definition: realmode_int.h:43
Definition: intercom.c:74
Definition: record.h:59
rtems_status_code rtems_record_start_server(rtems_task_priority priority, uint16_t port, rtems_interval period)
Starts a record TCP server task.
Definition: record-server.c:260
RTEMS_INLINE_ROUTINE void rtems_record_prepare(rtems_record_context *context)
Prepares to add and commit record items.
Definition: record.h:187
void rtems_record_drain(rtems_record_drain_visitor visitor, void *arg)
Drains the record items on all processors.
Definition: record.c:91
#define RTEMS_ALIGNED(_alignment)
Instructs the compiler to enforce the specified alignment.
Definition: basedefs.h:204
ISR_Level rtems_interrupt_level
Interrupt level type.
Definition: intr.h:42
unsigned long rtems_record_data
The record data integer type.
Definition: recorddata.h:1168
unsigned context
Definition: tlb.h:108
#define rtems_interrupt_local_disable(_isr_cookie)
This macro disables the interrupts on the current processor.
Definition: intr.h:138
CPU_Counter_ticks rtems_counter_ticks
Unsigned integer type for counter values.
Definition: counter.h:62
uint32_t rtems_task_priority
Definition: tasks.h:54