source: rtems/cpukit/score/src/userextiterate.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: 7.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreUserExt
7 *
8 * @brief This source file contains the definition of ::_User_extensions_List
9 *   and the implementation of _User_extensions_Fatal_visitor(),
10 *   _User_extensions_Iterate(), _User_extensions_Thread_begin_visitor(),
11 *   _User_extensions_Thread_create_visitor(),
12 *   _User_extensions_Thread_delete_visitor(),
13 *   _User_extensions_Thread_exitted_visitor(),
14 *   _User_extensions_Thread_restart_visitor(),
15 *   _User_extensions_Thread_start_visitor(), and
16 *   _User_extensions_Thread_terminate_visitor().
17 */
18
19/*
20 * Copyright (c) 2012, 2019 embedded brains GmbH.  All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 *    notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 *    notice, this list of conditions and the following disclaimer in the
29 *    documentation and/or other materials provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#ifdef HAVE_CONFIG_H
45#include "config.h"
46#endif
47
48#include <rtems/score/userextimpl.h>
49
50#include <pthread.h>
51
52User_extensions_List _User_extensions_List = {
53  CHAIN_INITIALIZER_EMPTY( _User_extensions_List.Active ),
54  CHAIN_ITERATOR_REGISTRY_INITIALIZER( _User_extensions_List.Iterators )
55#if defined(RTEMS_SMP)
56  ,
57  ISR_LOCK_INITIALIZER( "User Extensions List" )
58#endif
59};
60
61void _User_extensions_Thread_create_visitor(
62  Thread_Control              *executing,
63  void                        *arg,
64  const User_extensions_Table *callouts
65)
66{
67  User_extensions_thread_create_extension callout = callouts->thread_create;
68
69  if ( callout != NULL ) {
70    User_extensions_Thread_create_context *ctx = arg;
71
72    ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
73  }
74}
75
76void _User_extensions_Thread_delete_visitor(
77  Thread_Control              *executing,
78  void                        *arg,
79  const User_extensions_Table *callouts
80)
81{
82  User_extensions_thread_delete_extension callout = callouts->thread_delete;
83
84  if ( callout != NULL ) {
85    (*callout)( executing, arg );
86  }
87}
88
89void _User_extensions_Thread_start_visitor(
90  Thread_Control              *executing,
91  void                        *arg,
92  const User_extensions_Table *callouts
93)
94{
95  User_extensions_thread_start_extension callout = callouts->thread_start;
96
97  if ( callout != NULL ) {
98    (*callout)( executing, arg );
99  }
100}
101
102void _User_extensions_Thread_restart_visitor(
103  Thread_Control              *executing,
104  void                        *arg,
105  const User_extensions_Table *callouts
106)
107{
108  User_extensions_thread_restart_extension callout = callouts->thread_restart;
109
110  if ( callout != NULL ) {
111    (*callout)( executing, arg );
112  }
113}
114
115void _User_extensions_Thread_begin_visitor(
116  Thread_Control              *executing,
117  void                        *arg,
118  const User_extensions_Table *callouts
119)
120{
121  User_extensions_thread_begin_extension callout = callouts->thread_begin;
122
123  if ( callout != NULL ) {
124    (*callout)( executing );
125  }
126}
127
128void _User_extensions_Thread_exitted_visitor(
129  Thread_Control              *executing,
130  void                        *arg,
131  const User_extensions_Table *callouts
132)
133{
134  User_extensions_thread_exitted_extension callout = callouts->thread_exitted;
135
136  if ( callout != NULL ) {
137    (*callout)( executing );
138  }
139}
140
141void _User_extensions_Fatal_visitor(
142  Thread_Control              *executing,
143  void                        *arg,
144  const User_extensions_Table *callouts
145)
146{
147  User_extensions_fatal_extension callout = callouts->fatal;
148
149  if ( callout != NULL ) {
150    const User_extensions_Fatal_context *ctx = arg;
151
152    (*callout)( ctx->source, false, ctx->error );
153  }
154}
155
156void _User_extensions_Thread_terminate_visitor(
157  Thread_Control              *executing,
158  void                        *arg,
159  const User_extensions_Table *callouts
160)
161{
162  User_extensions_thread_terminate_extension callout =
163    callouts->thread_terminate;
164
165  if ( callout != NULL ) {
166    (*callout)( executing );
167  }
168}
169
170void _User_extensions_Iterate(
171  void                     *arg,
172  User_extensions_Visitor   visitor,
173  Chain_Iterator_direction  direction
174)
175{
176  Thread_Control              *executing;
177  const User_extensions_Table *initial_current;
178  const User_extensions_Table *initial_begin;
179  const User_extensions_Table *initial_end;
180  const Chain_Node            *end;
181  Chain_Node                  *node;
182  User_extensions_Iterator     iter;
183  ISR_lock_Context             lock_context;
184
185  executing = _Thread_Get_executing();
186
187  initial_begin = _User_extensions_Initial_extensions;
188  initial_end = initial_begin + _User_extensions_Initial_count;
189
190  if ( direction == CHAIN_ITERATOR_FORWARD ) {
191    initial_current = initial_begin;
192
193    while ( initial_current != initial_end ) {
194      (*visitor)( executing, arg, initial_current );
195      ++initial_current;
196    }
197
198    end = _Chain_Immutable_tail( &_User_extensions_List.Active );
199  } else {
200    end = _Chain_Immutable_head( &_User_extensions_List.Active );
201  }
202
203  _User_extensions_Acquire( &lock_context );
204
205  _Chain_Iterator_initialize(
206    &_User_extensions_List.Active,
207    &_User_extensions_List.Iterators,
208    &iter.Iterator,
209    direction
210  );
211
212  if ( executing != NULL ) {
213    iter.previous = executing->last_user_extensions_iterator;
214    executing->last_user_extensions_iterator = &iter;
215  }
216
217  while ( ( node = _Chain_Iterator_next( &iter.Iterator ) ) != end ) {
218    const User_extensions_Control *extension;
219
220    _Chain_Iterator_set_position( &iter.Iterator, node );
221
222    _User_extensions_Release( &lock_context );
223
224    extension = (const User_extensions_Control *) node;
225    ( *visitor )( executing, arg, &extension->Callouts );
226
227    _User_extensions_Acquire( &lock_context );
228  }
229
230  if ( executing != NULL ) {
231    executing->last_user_extensions_iterator = iter.previous;
232  }
233
234  _Chain_Iterator_destroy( &iter.Iterator );
235
236  _User_extensions_Release( &lock_context );
237
238  if ( direction == CHAIN_ITERATOR_BACKWARD ) {
239    initial_current = initial_end;
240
241    while ( initial_current != initial_begin ) {
242      --initial_current;
243      (*visitor)( executing, arg, initial_current );
244    }
245  }
246}
Note: See TracBrowser for help on using the repository browser.