source: rtems/cpukit/score/src/profilingsmplock.c @ 0b836337

5
Last change on this file since 0b836337 was 0b836337, checked in by Sebastian Huber <sebastian.huber@…>, on 07/27/16 at 08:55:17

score: Fix for RTEMS_DEBUG

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/score/smplock.h>
20
21#include <string.h>
22
23#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
24
25typedef struct {
26  SMP_lock_Control Lock;
27  Chain_Control Stats_chain;
28  Chain_Control Iterator_chain;
29} SMP_lock_Stats_control;
30
31static SMP_lock_Stats_control _SMP_lock_Stats_control = {
32  .Lock = {
33    .Ticket_lock = {
34      .next_ticket = ATOMIC_INITIALIZER_UINT( 0U ),
35      .now_serving = ATOMIC_INITIALIZER_UINT( 0U )
36    },
37    .Stats = {
38      .Node = CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN(
39        &_SMP_lock_Stats_control.Stats_chain
40      ),
41      .name = "SMP Lock Stats"
42    }
43  },
44  .Stats_chain = CHAIN_INITIALIZER_ONE_NODE(
45    &_SMP_lock_Stats_control.Lock.Stats.Node
46  ),
47  .Iterator_chain = CHAIN_INITIALIZER_EMPTY(
48    _SMP_lock_Stats_control.Iterator_chain
49  )
50};
51
52void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats )
53{
54  if ( !_Chain_Is_node_off_chain( &stats->Node ) ) {
55    SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
56    SMP_lock_Context lock_context;
57    SMP_lock_Stats_iteration_context *iteration_context;
58    SMP_lock_Stats_iteration_context *iteration_context_tail;
59    SMP_lock_Stats *next_stats;
60
61    _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
62
63    next_stats = (SMP_lock_Stats *) _Chain_Next( &stats->Node );
64    _Chain_Extract_unprotected( &stats->Node );
65
66    iteration_context = (SMP_lock_Stats_iteration_context *)
67      _Chain_First( &control->Iterator_chain );
68    iteration_context_tail = (SMP_lock_Stats_iteration_context *)
69      _Chain_Tail( &control->Iterator_chain );
70
71    while ( iteration_context != iteration_context_tail ) {
72      if ( iteration_context->current == stats ) {
73        iteration_context->current = next_stats;
74      }
75
76      iteration_context = (SMP_lock_Stats_iteration_context *)
77        _Chain_Next( &iteration_context->Node );
78    }
79
80    _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
81  }
82}
83
84void _SMP_lock_Stats_register( SMP_lock_Stats *stats )
85{
86      SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
87      SMP_lock_Context lock_context;
88
89      _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
90      _Chain_Append_unprotected( &control->Stats_chain, &stats->Node );
91      _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
92}
93
94void _SMP_lock_Stats_iteration_start(
95  SMP_lock_Stats_iteration_context *iteration_context
96)
97{
98  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
99  SMP_lock_Context lock_context;
100
101  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
102
103  _Chain_Initialize_node( &iteration_context->Node );
104  _Chain_Append_unprotected(
105    &control->Iterator_chain,
106    &iteration_context->Node
107  );
108  iteration_context->current =
109    (SMP_lock_Stats *) _Chain_First( &control->Stats_chain );
110
111  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
112}
113
114bool _SMP_lock_Stats_iteration_next(
115  SMP_lock_Stats_iteration_context *iteration_context,
116  SMP_lock_Stats                   *snapshot,
117  char                             *name,
118  size_t                            name_size
119)
120{
121  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
122  SMP_lock_Context lock_context;
123  SMP_lock_Stats *current;
124  bool valid;
125
126  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
127
128  current = iteration_context->current;
129  if ( !_Chain_Is_tail( &control->Stats_chain, &current->Node ) ) {
130    size_t name_len = current->name != NULL ? strlen(current->name) : 0;
131
132    valid = true;
133
134    iteration_context->current = (SMP_lock_Stats *)
135      _Chain_Next( &current->Node );
136
137    *snapshot = *current;
138    snapshot->name = name;
139
140    if ( name_len >= name_size ) {
141      name_len = name_size - 1;
142    }
143
144    name[name_len] = '\0';
145    memcpy(name, current->name, name_len);
146  } else {
147    valid = false;
148  }
149
150  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
151
152  return valid;
153}
154
155void _SMP_lock_Stats_iteration_stop(
156  SMP_lock_Stats_iteration_context *iteration_context
157)
158{
159  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
160  SMP_lock_Context lock_context;
161
162  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
163  _Chain_Extract_unprotected( &iteration_context->Node );
164  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
165}
166
167#endif /* RTEMS_SMP && RTEMS_PROFILING */
Note: See TracBrowser for help on using the repository browser.