RTEMS 6.1-rc5
Loading...
Searching...
No Matches
smplockstats.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * Copyright (C) 2013, 2018 embedded brains GmbH & Co. KG
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _RTEMS_SCORE_SMPLOCKSTATS_H
38#define _RTEMS_SCORE_SMPLOCKSTATS_H
39
40#include <rtems/score/cpu.h>
41
42#if defined(RTEMS_SMP)
43
44#include <rtems/score/chain.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif /* __cplusplus */
49
56#if defined(RTEMS_PROFILING)
57
61#define SMP_LOCK_STATS_CONTENTION_COUNTS 4
62
81typedef struct {
85 Chain_Node Node;
86
90 CPU_Counter_ticks max_acquire_time;
91
95 CPU_Counter_ticks max_section_time;
96
102 uint64_t usage_count;
103
113 uint64_t total_acquire_time;
114
125 uint64_t contention_counts[SMP_LOCK_STATS_CONTENTION_COUNTS];
126
135 uint64_t total_section_time;
136
140 const char *name;
141} SMP_lock_Stats;
142
146typedef struct {
152 CPU_Counter_ticks acquire_instant;
153
157 SMP_lock_Stats *stats;
158} SMP_lock_Stats_context;
159
163#define SMP_LOCK_STATS_INITIALIZER( name ) \
164 { { NULL, NULL }, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, name }
165
173static inline void _SMP_lock_Stats_initialize(
174 SMP_lock_Stats *stats,
175 const char *name
176)
177{
178 SMP_lock_Stats init = SMP_LOCK_STATS_INITIALIZER( name );
179
180 *stats = init;
181}
182
188void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats );
189
197void _SMP_lock_Stats_register_or_max_section_time(
198 SMP_lock_Stats *stats,
199 CPU_Counter_ticks max_section_time
200);
201
202typedef struct {
203 CPU_Counter_ticks first;
204} SMP_lock_Stats_acquire_context;
205
211static inline void _SMP_lock_Stats_acquire_begin(
212 SMP_lock_Stats_acquire_context *acquire_context
213)
214{
215 acquire_context->first = _CPU_Counter_read();
216}
217
226static inline void _SMP_lock_Stats_acquire_end(
227 const SMP_lock_Stats_acquire_context *acquire_context,
228 SMP_lock_Stats *stats,
229 SMP_lock_Stats_context *stats_context,
230 unsigned int queue_length
231)
232{
233 CPU_Counter_ticks second;
234 CPU_Counter_ticks delta;
235
236 second = _CPU_Counter_read();
237 stats_context->acquire_instant = second;
238 delta = second - acquire_context->first;
239
240 ++stats->usage_count;
241
242 stats->total_acquire_time += delta;
243
244 if ( stats->max_acquire_time < delta ) {
245 stats->max_acquire_time = delta;
246 }
247
248 if ( queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
249 queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
250 }
251 ++stats->contention_counts[ queue_length ];
252
253 stats_context->stats = stats;
254}
255
261static inline void _SMP_lock_Stats_release_update(
262 const SMP_lock_Stats_context *stats_context
263)
264{
265 SMP_lock_Stats *stats;
266 CPU_Counter_ticks first;
267 CPU_Counter_ticks second;
268 CPU_Counter_ticks delta;
269
270 stats = stats_context->stats;
271 first = stats_context->acquire_instant;
272 second = _CPU_Counter_read();
273 delta = second - first;
274
275 stats->total_section_time += delta;
276
277 if ( stats->max_section_time < delta ) {
278 _SMP_lock_Stats_register_or_max_section_time( stats, delta );
279 }
280}
281
282typedef struct {
283 Chain_Node Node;
284 SMP_lock_Stats *current;
285} SMP_lock_Stats_iteration_context;
286
292void _SMP_lock_Stats_iteration_start(
293 SMP_lock_Stats_iteration_context *iteration_context
294);
295
307bool _SMP_lock_Stats_iteration_next(
308 SMP_lock_Stats_iteration_context *iteration_context,
309 SMP_lock_Stats *snapshot,
310 char *name,
311 size_t name_size
312);
313
319void _SMP_lock_Stats_iteration_stop(
320 SMP_lock_Stats_iteration_context *iteration_context
321);
322
323#else /* RTEMS_PROFILING */
324
325#define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 )
326
327#define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 )
328
329#endif /* !RTEMS_PROFILING */
330
333#ifdef __cplusplus
334}
335#endif /* __cplusplus */
336
337#endif /* RTEMS_SMP */
338
339#endif /* _RTEMS_SCORE_SMPLOCKSTATS_H */
CPU_Counter_ticks _CPU_Counter_read(void)
Gets the current CPU counter value.
Definition: system-clocks.c:130
This header file provides interfaces of the Chain Handler which are used by the implementation and th...
This structure represents a chain node.
Definition: chain.h:78