RTEMS
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
27 extern "C" {
28 #endif /* __cplusplus */
29 
36 #if defined(RTEMS_PROFILING)
37 
41 #define SMP_LOCK_STATS_CONTENTION_COUNTS 4
42 
61 typedef 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 
126 typedef 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 
153 static 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 
168 void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats );
169 
177 void _SMP_lock_Stats_register_or_max_section_time(
178  SMP_lock_Stats *stats,
179  CPU_Counter_ticks max_section_time
180 );
181 
182 typedef struct {
183  CPU_Counter_ticks first;
184 } SMP_lock_Stats_acquire_context;
185 
191 static 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 
206 static 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 
241 static 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 
262 typedef struct {
263  Chain_Node Node;
264  SMP_lock_Stats *current;
265 } SMP_lock_Stats_iteration_context;
266 
272 void _SMP_lock_Stats_iteration_start(
273  SMP_lock_Stats_iteration_context *iteration_context
274 );
275 
287 bool _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 
299 void _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 */
SPARC CPU Department Source.
Chain Handler API.