RTEMS  5.0.0
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 
170 void _SMP_lock_Stats_register_or_max_section_time(
171  SMP_lock_Stats *stats,
172  CPU_Counter_ticks max_section_time
173 );
174 
175 typedef struct {
176  CPU_Counter_ticks first;
177 } SMP_lock_Stats_acquire_context;
178 
179 static inline void _SMP_lock_Stats_acquire_begin(
180  SMP_lock_Stats_acquire_context *acquire_context
181 )
182 {
183  acquire_context->first = _CPU_Counter_read();
184 }
185 
186 static inline void _SMP_lock_Stats_acquire_end(
187  const SMP_lock_Stats_acquire_context *acquire_context,
188  SMP_lock_Stats *stats,
189  SMP_lock_Stats_context *stats_context,
190  unsigned int queue_length
191 )
192 {
193  CPU_Counter_ticks second;
194  CPU_Counter_ticks delta;
195 
196  second = _CPU_Counter_read();
197  stats_context->acquire_instant = second;
198  delta = _CPU_Counter_difference( second, acquire_context->first );
199 
200  ++stats->usage_count;
201 
202  stats->total_acquire_time += delta;
203 
204  if ( stats->max_acquire_time < delta ) {
205  stats->max_acquire_time = delta;
206  }
207 
208  if ( queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
209  queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
210  }
211  ++stats->contention_counts[ queue_length ];
212 
213  stats_context->stats = stats;
214 }
215 
221 static inline void _SMP_lock_Stats_release_update(
222  const SMP_lock_Stats_context *stats_context
223 )
224 {
225  SMP_lock_Stats *stats;
226  CPU_Counter_ticks first;
227  CPU_Counter_ticks second;
228  CPU_Counter_ticks delta;
229 
230  stats = stats_context->stats;
231  first = stats_context->acquire_instant;
232  second = _CPU_Counter_read();
233  delta = _CPU_Counter_difference( second, first );
234 
235  stats->total_section_time += delta;
236 
237  if ( stats->max_section_time < delta ) {
238  _SMP_lock_Stats_register_or_max_section_time( stats, delta );
239  }
240 }
241 
242 typedef struct {
243  Chain_Node Node;
244  SMP_lock_Stats *current;
245 } SMP_lock_Stats_iteration_context;
246 
247 void _SMP_lock_Stats_iteration_start(
248  SMP_lock_Stats_iteration_context *iteration_context
249 );
250 
251 
252 bool _SMP_lock_Stats_iteration_next(
253  SMP_lock_Stats_iteration_context *iteration_context,
254  SMP_lock_Stats *snapshot,
255  char *name,
256  size_t name_size
257 );
258 
259 void _SMP_lock_Stats_iteration_stop(
260  SMP_lock_Stats_iteration_context *iteration_context
261 );
262 
263 #else /* RTEMS_PROFILING */
264 
265 #define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 )
266 
267 #define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 )
268 
269 #endif /* !RTEMS_PROFILING */
270 
273 #ifdef __cplusplus
274 }
275 #endif /* __cplusplus */
276 
277 #endif /* RTEMS_SMP */
278 
279 #endif /* _RTEMS_SCORE_SMPLOCKSTATS_H */
Definition: chain.h:65
CPU_Counter_ticks _CPU_Counter_read(void)
Returns the current CPU counter value.
Definition: system-clocks.c:117
Chain Handler API.