source: rtems/cpukit/score/src/userextiterate.c @ 4c20da4b

5
Last change on this file since 4c20da4b was 4c20da4b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/19 at 07:18:11

doxygen: Rename Score* groups in RTEMSScore*

Update #3706

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief User Extension Iteration Helpers
5 *
6 * @ingroup RTEMSScoreUserExt
7 */
8
9/*
10 * Copyright (c) 2012, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#if HAVE_CONFIG_H
24  #include "config.h"
25#endif
26
27#include <rtems/config.h>
28#include <rtems/score/userextimpl.h>
29
30#include <pthread.h>
31
32User_extensions_List _User_extensions_List = {
33  CHAIN_INITIALIZER_EMPTY( _User_extensions_List.Active ),
34  CHAIN_ITERATOR_REGISTRY_INITIALIZER( _User_extensions_List.Iterators )
35#if defined(RTEMS_SMP)
36  ,
37  ISR_LOCK_INITIALIZER( "User Extensions List" )
38#endif
39};
40
41void _User_extensions_Thread_create_visitor(
42  Thread_Control              *executing,
43  void                        *arg,
44  const User_extensions_Table *callouts
45)
46{
47  User_extensions_thread_create_extension callout = callouts->thread_create;
48
49  if ( callout != NULL ) {
50    User_extensions_Thread_create_context *ctx = arg;
51
52    ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
53  }
54}
55
56void _User_extensions_Thread_delete_visitor(
57  Thread_Control              *executing,
58  void                        *arg,
59  const User_extensions_Table *callouts
60)
61{
62  User_extensions_thread_delete_extension callout = callouts->thread_delete;
63
64  if ( callout != NULL ) {
65    (*callout)( executing, arg );
66  }
67}
68
69void _User_extensions_Thread_start_visitor(
70  Thread_Control              *executing,
71  void                        *arg,
72  const User_extensions_Table *callouts
73)
74{
75  User_extensions_thread_start_extension callout = callouts->thread_start;
76
77  if ( callout != NULL ) {
78    (*callout)( executing, arg );
79  }
80}
81
82void _User_extensions_Thread_restart_visitor(
83  Thread_Control              *executing,
84  void                        *arg,
85  const User_extensions_Table *callouts
86)
87{
88  User_extensions_thread_restart_extension callout = callouts->thread_restart;
89
90  if ( callout != NULL ) {
91    (*callout)( executing, arg );
92  }
93}
94
95void _User_extensions_Thread_begin_visitor(
96  Thread_Control              *executing,
97  void                        *arg,
98  const User_extensions_Table *callouts
99)
100{
101  User_extensions_thread_begin_extension callout = callouts->thread_begin;
102
103  if ( callout != NULL ) {
104    (*callout)( executing );
105  }
106}
107
108void _User_extensions_Thread_exitted_visitor(
109  Thread_Control              *executing,
110  void                        *arg,
111  const User_extensions_Table *callouts
112)
113{
114  User_extensions_thread_exitted_extension callout = callouts->thread_exitted;
115
116  if ( callout != NULL ) {
117    (*callout)( executing );
118  }
119}
120
121void _User_extensions_Fatal_visitor(
122  Thread_Control              *executing,
123  void                        *arg,
124  const User_extensions_Table *callouts
125)
126{
127  User_extensions_fatal_extension callout = callouts->fatal;
128
129  if ( callout != NULL ) {
130    const User_extensions_Fatal_context *ctx = arg;
131
132    (*callout)( ctx->source, false, ctx->error );
133  }
134}
135
136void _User_extensions_Thread_terminate_visitor(
137  Thread_Control              *executing,
138  void                        *arg,
139  const User_extensions_Table *callouts
140)
141{
142  User_extensions_thread_terminate_extension callout =
143    callouts->thread_terminate;
144
145  if ( callout != NULL ) {
146    (*callout)( executing );
147  }
148}
149
150void _User_extensions_Iterate(
151  void                     *arg,
152  User_extensions_Visitor   visitor,
153  Chain_Iterator_direction  direction
154)
155{
156  Thread_Control              *executing;
157  const User_extensions_Table *initial_current;
158  const User_extensions_Table *initial_begin;
159  const User_extensions_Table *initial_end;
160  const Chain_Node            *end;
161  Chain_Node                  *node;
162  User_extensions_Iterator     iter;
163  ISR_lock_Context             lock_context;
164
165  executing = _Thread_Get_executing();
166
167  initial_begin = rtems_configuration_get_user_extension_table();
168  initial_end =
169    initial_begin + rtems_configuration_get_number_of_initial_extensions();
170
171  if ( direction == CHAIN_ITERATOR_FORWARD ) {
172    initial_current = initial_begin;
173
174    while ( initial_current != initial_end ) {
175      (*visitor)( executing, arg, initial_current );
176      ++initial_current;
177    }
178
179    end = _Chain_Immutable_tail( &_User_extensions_List.Active );
180  } else {
181    end = _Chain_Immutable_head( &_User_extensions_List.Active );
182  }
183
184  _User_extensions_Acquire( &lock_context );
185
186  _Chain_Iterator_initialize(
187    &_User_extensions_List.Active,
188    &_User_extensions_List.Iterators,
189    &iter.Iterator,
190    direction
191  );
192
193  if ( executing != NULL ) {
194    iter.previous = executing->last_user_extensions_iterator;
195    executing->last_user_extensions_iterator = &iter;
196  }
197
198  while ( ( node = _Chain_Iterator_next( &iter.Iterator ) ) != end ) {
199    const User_extensions_Control *extension;
200
201    _Chain_Iterator_set_position( &iter.Iterator, node );
202
203    _User_extensions_Release( &lock_context );
204
205    extension = (const User_extensions_Control *) node;
206    ( *visitor )( executing, arg, &extension->Callouts );
207
208    _User_extensions_Acquire( &lock_context );
209  }
210
211  if ( executing != NULL ) {
212    executing->last_user_extensions_iterator = iter.previous;
213  }
214
215  _Chain_Iterator_destroy( &iter.Iterator );
216
217  _User_extensions_Release( &lock_context );
218
219  if ( direction == CHAIN_ITERATOR_BACKWARD ) {
220    initial_current = initial_end;
221
222    while ( initial_current != initial_begin ) {
223      --initial_current;
224      (*visitor)( executing, arg, initial_current );
225    }
226  }
227}
Note: See TracBrowser for help on using the repository browser.