RTEMS
userextiterate.c
Go to the documentation of this file.
1 
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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
28 
29 #include <pthread.h>
30 
34 #if defined(RTEMS_SMP)
35  ,
36  ISR_LOCK_INITIALIZER( "User Extensions List" )
37 #endif
38 };
39 
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 ) {
50 
51  ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
52  }
53 }
54 
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 
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 
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 
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 
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 
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 
136  Thread_Control *executing,
137  void *arg,
138  const User_extensions_Table *callouts
139 )
140 {
142  callouts->thread_terminate;
143 
144  if ( callout != NULL ) {
145  (*callout)( executing );
146  }
147 }
148 
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;
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 
178  } else {
180  }
181 
182  _User_extensions_Acquire( &lock_context );
183 
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 }
#define ISR_LOCK_INITIALIZER(_name)
Initializer for static initialization of ISR locks.
Definition: isrlock.h:146
void(* User_extensions_thread_delete_extension)(struct _Thread_Control *executing, struct _Thread_Control *deleted)
Task delete extension.
Definition: userext.h:89
static __inline__ void _Chain_Iterator_destroy(Chain_Iterator *the_iterator)
Destroys the iterator.
Definition: chainimpl.h:1121
static __inline__ void _Chain_Iterator_set_position(Chain_Iterator *the_iterator, Chain_Node *the_node)
Sets the iterator position.
Definition: chainimpl.h:1106
void(* User_extensions_thread_begin_extension)(struct _Thread_Control *executing)
Task begin extension.
Definition: userext.h:169
bool(* User_extensions_thread_create_extension)(struct _Thread_Control *executing, struct _Thread_Control *created)
Task create extension.
Definition: userext.h:69
#define CHAIN_INITIALIZER_EMPTY(name)
Chain initializer for an empty chain with designator name.
Definition: chainimpl.h:39
const size_t _User_extensions_Initial_count
The count of initial user extensions.
void _User_extensions_Thread_delete_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Deletes a visitor.
void _User_extensions_Thread_exitted_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Calls the exitted function of the thread callout for the visitor.
void(* User_extensions_thread_restart_extension)(struct _Thread_Control *executing, struct _Thread_Control *restarted)
Task restart extension.
Definition: userext.h:131
Chain iterator for dynamic user extensions.
Definition: userextimpl.h:46
User Extension Handler API.
void _User_extensions_Fatal_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Calls the fatal function of the thread callout for the visitor.
const User_extensions_Table _User_extensions_Initial_extensions[]
The table of initial user extensions.
static __inline__ struct _Thread_Control * _Thread_Get_executing(void)
Returns the thread control block of the executing thread.
Definition: percpu.h:878
struct User_extensions_Iterator * last_user_extensions_iterator
LIFO list of user extensions iterators.
Definition: thread.h:869
#define CHAIN_ITERATOR_REGISTRY_INITIALIZER(name)
Chain iterator registry initializer for static initialization.
Definition: chainimpl.h:943
void _User_extensions_Thread_restart_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Restarts a visitor.
void _User_extensions_Thread_begin_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Calls the begin function of the thread callout for the visitor.
void(* User_extensions_fatal_extension)(Internal_errors_Source source, bool always_set_to_false, Internal_errors_t code)
Fatal error extension.
Definition: userext.h:201
void(* User_extensions_thread_start_extension)(struct _Thread_Control *executing, struct _Thread_Control *started)
Task start extension.
Definition: userext.h:109
User_extensions_List _User_extensions_List
List of active extensions.
static __inline__ Chain_Node * _Chain_Iterator_next(const Chain_Iterator *the_iterator)
Returns the next node in the iterator direction.
Definition: chainimpl.h:1089
static void _User_extensions_Release(ISR_lock_Context *lock_context)
Releases the lock context and enables interrupts.
Definition: userextimpl.h:486
void _User_extensions_Iterate(void *arg, User_extensions_Visitor visitor, Chain_Iterator_direction direction)
Iterates through all user extensions and calls the visitor for each.
void(* User_extensions_Visitor)(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
User extension visitor.
Definition: userextimpl.h:143
void(* User_extensions_thread_terminate_extension)(struct _Thread_Control *terminated)
Task termination extension.
Definition: userext.h:223
Iteration from head to tail.
Definition: chainimpl.h:888
User extension table.
Definition: userext.h:230
Chain_Iterator_registry Iterators
Chain iterator registration.
Definition: userextimpl.h:60
Manages each user extension set.
Definition: userextdata.h:50
Chain_Control Active
Active dynamically added user extensions.
Definition: userextimpl.h:55
static __inline__ const Chain_Node * _Chain_Immutable_head(const Chain_Control *the_chain)
Returns pointer to immutable chain head.
Definition: chainimpl.h:211
void _User_extensions_Thread_create_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Creates a visitor.
void _User_extensions_Thread_terminate_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Terminates a visitor.
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
Chain_Iterator_direction
The chain iterator direction.
Definition: chainimpl.h:884
static void _User_extensions_Acquire(ISR_lock_Context *lock_context)
Disables interrupts and acquires the lock context.
Definition: userextimpl.h:473
static __inline__ void _Chain_Iterator_initialize(Chain_Control *the_chain, Chain_Iterator_registry *the_registry, Chain_Iterator *the_iterator, Chain_Iterator_direction direction)
Initializes the chain iterator.
Definition: chainimpl.h:1057
Iteration from tail to head.
Definition: chainimpl.h:893
void _User_extensions_Thread_start_visitor(Thread_Control *executing, void *arg, const User_extensions_Table *callouts)
Starts a visitor.
static __inline__ const Chain_Node * _Chain_Immutable_tail(const Chain_Control *the_chain)
Returns pointer to immutable chain tail.
Definition: chainimpl.h:243
void(* User_extensions_thread_exitted_extension)(struct _Thread_Control *executing)
Task exitted extension.
Definition: userext.h:183