source: rtems/cpukit/score/src/userextiterate.c @ 5ae6112

5
Last change on this file since 5ae6112 was 5ae6112, checked in by Sebastian Huber <sebastian.huber@…>, on 12/05/19 at 14:14:51

userext: Simplify configuration

Avoid the use of the workspace and use statically allocated switch
controls for the initial extensions.

  • 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, 2019 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/score/userextimpl.h>
28
29#include <pthread.h>
30
31User_extensions_List _User_extensions_List = {
32  CHAIN_INITIALIZER_EMPTY( _User_extensions_List.Active ),
33  CHAIN_ITERATOR_REGISTRY_INITIALIZER( _User_extensions_List.Iterators )
34#if defined(RTEMS_SMP)
35  ,
36  ISR_LOCK_INITIALIZER( "User Extensions List" )
37#endif
38};
39
40void _User_extensions_Thread_create_visitor(
41  Thread_Control              *executing,
42  void                        *arg,
43  const User_extensions_Table *callouts
44)
45{
46  User_extensions_thread_create_extension callout = callouts->thread_create;
47
48  if ( callout != NULL ) {
49    User_extensions_Thread_create_context *ctx = arg;
50
51    ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
52  }
53}
54
55void _User_extensions_Thread_delete_visitor(
56  Thread_Control              *executing,
57  void                        *arg,
58  const User_extensions_Table *callouts
59)
60{
61  User_extensions_thread_delete_extension callout = callouts->thread_delete;
62
63  if ( callout != NULL ) {
64    (*callout)( executing, arg );
65  }
66}
67
68void _User_extensions_Thread_start_visitor(
69  Thread_Control              *executing,
70  void                        *arg,
71  const User_extensions_Table *callouts
72)
73{
74  User_extensions_thread_start_extension callout = callouts->thread_start;
75
76  if ( callout != NULL ) {
77    (*callout)( executing, arg );
78  }
79}
80
81void _User_extensions_Thread_restart_visitor(
82  Thread_Control              *executing,
83  void                        *arg,
84  const User_extensions_Table *callouts
85)
86{
87  User_extensions_thread_restart_extension callout = callouts->thread_restart;
88
89  if ( callout != NULL ) {
90    (*callout)( executing, arg );
91  }
92}
93
94void _User_extensions_Thread_begin_visitor(
95  Thread_Control              *executing,
96  void                        *arg,
97  const User_extensions_Table *callouts
98)
99{
100  User_extensions_thread_begin_extension callout = callouts->thread_begin;
101
102  if ( callout != NULL ) {
103    (*callout)( executing );
104  }
105}
106
107void _User_extensions_Thread_exitted_visitor(
108  Thread_Control              *executing,
109  void                        *arg,
110  const User_extensions_Table *callouts
111)
112{
113  User_extensions_thread_exitted_extension callout = callouts->thread_exitted;
114
115  if ( callout != NULL ) {
116    (*callout)( executing );
117  }
118}
119
120void _User_extensions_Fatal_visitor(
121  Thread_Control              *executing,
122  void                        *arg,
123  const User_extensions_Table *callouts
124)
125{
126  User_extensions_fatal_extension callout = callouts->fatal;
127
128  if ( callout != NULL ) {
129    const User_extensions_Fatal_context *ctx = arg;
130
131    (*callout)( ctx->source, false, ctx->error );
132  }
133}
134
135void _User_extensions_Thread_terminate_visitor(
136  Thread_Control              *executing,
137  void                        *arg,
138  const User_extensions_Table *callouts
139)
140{
141  User_extensions_thread_terminate_extension callout =
142    callouts->thread_terminate;
143
144  if ( callout != NULL ) {
145    (*callout)( executing );
146  }
147}
148
149void _User_extensions_Iterate(
150  void                     *arg,
151  User_extensions_Visitor   visitor,
152  Chain_Iterator_direction  direction
153)
154{
155  Thread_Control              *executing;
156  const User_extensions_Table *initial_current;
157  const User_extensions_Table *initial_begin;
158  const User_extensions_Table *initial_end;
159  const Chain_Node            *end;
160  Chain_Node                  *node;
161  User_extensions_Iterator     iter;
162  ISR_lock_Context             lock_context;
163
164  executing = _Thread_Get_executing();
165
166  initial_begin = _User_extensions_Initial_extensions;
167  initial_end = initial_begin + _User_extensions_Initial_count;
168
169  if ( direction == CHAIN_ITERATOR_FORWARD ) {
170    initial_current = initial_begin;
171
172    while ( initial_current != initial_end ) {
173      (*visitor)( executing, arg, initial_current );
174      ++initial_current;
175    }
176
177    end = _Chain_Immutable_tail( &_User_extensions_List.Active );
178  } else {
179    end = _Chain_Immutable_head( &_User_extensions_List.Active );
180  }
181
182  _User_extensions_Acquire( &lock_context );
183
184  _Chain_Iterator_initialize(
185    &_User_extensions_List.Active,
186    &_User_extensions_List.Iterators,
187    &iter.Iterator,
188    direction
189  );
190
191  if ( executing != NULL ) {
192    iter.previous = executing->last_user_extensions_iterator;
193    executing->last_user_extensions_iterator = &iter;
194  }
195
196  while ( ( node = _Chain_Iterator_next( &iter.Iterator ) ) != end ) {
197    const User_extensions_Control *extension;
198
199    _Chain_Iterator_set_position( &iter.Iterator, node );
200
201    _User_extensions_Release( &lock_context );
202
203    extension = (const User_extensions_Control *) node;
204    ( *visitor )( executing, arg, &extension->Callouts );
205
206    _User_extensions_Acquire( &lock_context );
207  }
208
209  if ( executing != NULL ) {
210    executing->last_user_extensions_iterator = iter.previous;
211  }
212
213  _Chain_Iterator_destroy( &iter.Iterator );
214
215  _User_extensions_Release( &lock_context );
216
217  if ( direction == CHAIN_ITERATOR_BACKWARD ) {
218    initial_current = initial_end;
219
220    while ( initial_current != initial_begin ) {
221      --initial_current;
222      (*visitor)( executing, arg, initial_current );
223    }
224  }
225}
Note: See TracBrowser for help on using the repository browser.