source: rtems/cpukit/score/src/profilingsmplock.c @ 255fe43

Last change on this file since 255fe43 was 255fe43, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 20:40:44

cpukit/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreSMPLock
7 *
8 * @brief This source file contains the implementation of
9 *   _SMP_lock_Stats_destroy(), _SMP_lock_Stats_register_or_max_section_time(),
10 *   _SMP_lock_Stats_iteration_start(), _SMP_lock_Stats_iteration_next(), and
11 *   _SMP_lock_Stats_iteration_stop().
12 */
13
14/*
15 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#ifdef HAVE_CONFIG_H
40#include "config.h"
41#endif
42
43#include <rtems/score/smplock.h>
44#include <rtems/score/chainimpl.h>
45
46#include <string.h>
47
48#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
49
50typedef struct {
51  SMP_lock_Control Lock;
52  Chain_Control Stats_chain;
53  Chain_Control Iterator_chain;
54} SMP_lock_Stats_control;
55
56static SMP_lock_Stats_control _SMP_lock_Stats_control = {
57  .Lock = {
58    .Ticket_lock = {
59      .next_ticket = ATOMIC_INITIALIZER_UINT( 0U ),
60      .now_serving = ATOMIC_INITIALIZER_UINT( 0U )
61    },
62    .Stats = {
63      .Node = CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN(
64        &_SMP_lock_Stats_control.Stats_chain
65      ),
66      .name = "SMP Lock Stats"
67    }
68  },
69  .Stats_chain = CHAIN_INITIALIZER_ONE_NODE(
70    &_SMP_lock_Stats_control.Lock.Stats.Node
71  ),
72  .Iterator_chain = CHAIN_INITIALIZER_EMPTY(
73    _SMP_lock_Stats_control.Iterator_chain
74  )
75};
76
77void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats )
78{
79  if ( !_Chain_Is_node_off_chain( &stats->Node ) ) {
80    SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
81    SMP_lock_Context lock_context;
82    SMP_lock_Stats_iteration_context *iteration_context;
83    SMP_lock_Stats_iteration_context *iteration_context_tail;
84    SMP_lock_Stats *next_stats;
85
86    _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
87
88    next_stats = (SMP_lock_Stats *) _Chain_Next( &stats->Node );
89    _Chain_Extract_unprotected( &stats->Node );
90
91    iteration_context = (SMP_lock_Stats_iteration_context *)
92      _Chain_First( &control->Iterator_chain );
93    iteration_context_tail = (SMP_lock_Stats_iteration_context *)
94      _Chain_Tail( &control->Iterator_chain );
95
96    while ( iteration_context != iteration_context_tail ) {
97      if ( iteration_context->current == stats ) {
98        iteration_context->current = next_stats;
99      }
100
101      iteration_context = (SMP_lock_Stats_iteration_context *)
102        _Chain_Next( &iteration_context->Node );
103    }
104
105    _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
106  }
107}
108
109void _SMP_lock_Stats_register_or_max_section_time(
110  SMP_lock_Stats    *stats,
111  CPU_Counter_ticks  max_section_time
112)
113{
114  stats->max_section_time = max_section_time;
115
116  if ( _Chain_Is_node_off_chain( &stats->Node ) ) {
117    SMP_lock_Stats_control *control;
118    SMP_lock_Context        lock_context;
119
120    control = &_SMP_lock_Stats_control;
121    _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
122    _Chain_Append_unprotected( &control->Stats_chain, &stats->Node );
123    _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
124  }
125}
126
127void _SMP_lock_Stats_iteration_start(
128  SMP_lock_Stats_iteration_context *iteration_context
129)
130{
131  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
132  SMP_lock_Context lock_context;
133
134  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
135
136  _Chain_Initialize_node( &iteration_context->Node );
137  _Chain_Append_unprotected(
138    &control->Iterator_chain,
139    &iteration_context->Node
140  );
141  iteration_context->current =
142    (SMP_lock_Stats *) _Chain_First( &control->Stats_chain );
143
144  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
145}
146
147bool _SMP_lock_Stats_iteration_next(
148  SMP_lock_Stats_iteration_context *iteration_context,
149  SMP_lock_Stats                   *snapshot,
150  char                             *name,
151  size_t                            name_size
152)
153{
154  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
155  SMP_lock_Context lock_context;
156  SMP_lock_Stats *current;
157  bool valid;
158
159  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
160
161  current = iteration_context->current;
162  if ( !_Chain_Is_tail( &control->Stats_chain, &current->Node ) ) {
163    size_t name_len = current->name != NULL ? strlen(current->name) : 0;
164
165    valid = true;
166
167    iteration_context->current = (SMP_lock_Stats *)
168      _Chain_Next( &current->Node );
169
170    *snapshot = *current;
171    snapshot->name = name;
172
173    if ( name_len >= name_size ) {
174      name_len = name_size - 1;
175    }
176
177    name[name_len] = '\0';
178    memcpy(name, current->name, name_len);
179  } else {
180    valid = false;
181  }
182
183  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
184
185  return valid;
186}
187
188void _SMP_lock_Stats_iteration_stop(
189  SMP_lock_Stats_iteration_context *iteration_context
190)
191{
192  SMP_lock_Stats_control *control = &_SMP_lock_Stats_control;
193  SMP_lock_Context lock_context;
194
195  _SMP_lock_ISR_disable_and_acquire( &control->Lock, &lock_context );
196  _Chain_Extract_unprotected( &iteration_context->Node );
197  _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context );
198}
199
200#endif /* RTEMS_SMP && RTEMS_PROFILING */
Note: See TracBrowser for help on using the repository browser.