RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
smplockstats.h
Go to the documentation of this file.
1
9/*
10 * Copyright (c) 2013, 2018 embedded brains GmbH
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef _RTEMS_SCORE_SMPLOCKSTATS_H
18#define _RTEMS_SCORE_SMPLOCKSTATS_H
19
20#include <rtems/score/cpu.h>
21
22#if defined(RTEMS_SMP)
23
24#include <rtems/score/chain.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif /* __cplusplus */
29
36#if defined(RTEMS_PROFILING)
37
41#define SMP_LOCK_STATS_CONTENTION_COUNTS 4
42
61typedef struct {
65 Chain_Node Node;
66
70 CPU_Counter_ticks max_acquire_time;
71
75 CPU_Counter_ticks max_section_time;
76
82 uint64_t usage_count;
83
93 uint64_t total_acquire_time;
94
105 uint64_t contention_counts[SMP_LOCK_STATS_CONTENTION_COUNTS];
106
115 uint64_t total_section_time;
116
120 const char *name;
121} SMP_lock_Stats;
122
126typedef struct {
132 CPU_Counter_ticks acquire_instant;
133
137 SMP_lock_Stats *stats;
138} SMP_lock_Stats_context;
139
143#define SMP_LOCK_STATS_INITIALIZER( name ) \
144 { { NULL, NULL }, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, name }
145
153static inline void _SMP_lock_Stats_initialize(
154 SMP_lock_Stats *stats,
155 const char *name
156)
157{
158 SMP_lock_Stats init = SMP_LOCK_STATS_INITIALIZER( name );
159
160 *stats = init;
161}
162
168void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats );
169
177void _SMP_lock_Stats_register_or_max_section_time(
178 SMP_lock_Stats *stats,
179 CPU_Counter_ticks max_section_time
180);
181
182typedef struct {
183 CPU_Counter_ticks first;
184} SMP_lock_Stats_acquire_context;
185
191static inline void _SMP_lock_Stats_acquire_begin(
192 SMP_lock_Stats_acquire_context *acquire_context
193)
194{
195 acquire_context->first = _CPU_Counter_read();
196}
197
206static inline void _SMP_lock_Stats_acquire_end(
207 const SMP_lock_Stats_acquire_context *acquire_context,
208 SMP_lock_Stats *stats,
209 SMP_lock_Stats_context *stats_context,
210 unsigned int queue_length
211)
212{
213 CPU_Counter_ticks second;
214 CPU_Counter_ticks delta;
215
216 second = _CPU_Counter_read();
217 stats_context->acquire_instant = second;
218 delta = _CPU_Counter_difference( second, acquire_context->first );
219
220 ++stats->usage_count;
221
222 stats->total_acquire_time += delta;
223
224 if ( stats->max_acquire_time < delta ) {
225 stats->max_acquire_time = delta;
226 }
227
228 if ( queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
229 queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
230 }
231 ++stats->contention_counts[ queue_length ];
232
233 stats_context->stats = stats;
234}
235
241static inline void _SMP_lock_Stats_release_update(
242 const SMP_lock_Stats_context *stats_context
243)
244{
245 SMP_lock_Stats *stats;
246 CPU_Counter_ticks first;
247 CPU_Counter_ticks second;
248 CPU_Counter_ticks delta;
249
250 stats = stats_context->stats;
251 first = stats_context->acquire_instant;
252 second = _CPU_Counter_read();
253 delta = _CPU_Counter_difference( second, first );
254
255 stats->total_section_time += delta;
256
257 if ( stats->max_section_time < delta ) {
258 _SMP_lock_Stats_register_or_max_section_time( stats, delta );
259 }
260}
261
262typedef struct {
263 Chain_Node Node;
264 SMP_lock_Stats *current;
265} SMP_lock_Stats_iteration_context;
266
272void _SMP_lock_Stats_iteration_start(
273 SMP_lock_Stats_iteration_context *iteration_context
274);
275
287bool _SMP_lock_Stats_iteration_next(
288 SMP_lock_Stats_iteration_context *iteration_context,
289 SMP_lock_Stats *snapshot,
290 char *name,
291 size_t name_size
292);
293
299void _SMP_lock_Stats_iteration_stop(
300 SMP_lock_Stats_iteration_context *iteration_context
301);
302
303#else /* RTEMS_PROFILING */
304
305#define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 )
306
307#define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 )
308
309#endif /* !RTEMS_PROFILING */
310
313#ifdef __cplusplus
314}
315#endif /* __cplusplus */
316
317#endif /* RTEMS_SMP */
318
319#endif /* _RTEMS_SCORE_SMPLOCKSTATS_H */
CPU_Counter_ticks _CPU_Counter_read(void)
Returns the current CPU counter value.
Definition: system-clocks.c:117
Chain Handler API.
Definition: chain.h:68