source: rtems/cpukit/score/include/rtems/score/userextimpl.h @ 48fed9a

4.115
Last change on this file since 48fed9a was 48fed9a, checked in by Sebastian Huber <sebastian.huber@…>, on 06/25/15 at 12:11:53

score: Simplify <rtems/system.h>

Drop the <rtems/score/percpu.h> include since this file exposes a lot of
implementation details.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreUserExt
5 *
6 * @brief User Extension Handler API
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2009.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_USEREXTIMPL_H
19#define _RTEMS_SCORE_USEREXTIMPL_H
20
21#include <rtems/score/userext.h>
22#include <rtems/score/chainimpl.h>
23#include <rtems/score/percpu.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/**
30 * @defgroup ScoreUserExt User Extension Handler
31 *
32 * @ingroup Score
33 *
34 * @addtogroup ScoreUserExt
35 */
36/**@{**/
37
38/**
39 * @brief List of active extensions.
40 */
41extern Chain_Control _User_extensions_List;
42
43/**
44 * @brief List of active task switch extensions.
45 */
46extern Chain_Control _User_extensions_Switches_list;
47
48/**
49 * @name Extension Maintainance
50 */
51/**@{**/
52
53void _User_extensions_Handler_initialization( void );
54
55void _User_extensions_Add_set(
56  User_extensions_Control *extension
57);
58
59RTEMS_INLINE_ROUTINE void _User_extensions_Add_API_set(
60  User_extensions_Control *extension
61)
62{
63  _User_extensions_Add_set( extension );
64}
65
66RTEMS_INLINE_ROUTINE void _User_extensions_Add_set_with_table(
67  User_extensions_Control     *extension,
68  const User_extensions_Table *extension_table
69)
70{
71  extension->Callouts = *extension_table;
72
73  _User_extensions_Add_set( extension );
74}
75
76void _User_extensions_Remove_set(
77  User_extensions_Control *extension
78);
79
80/**
81 * @brief User extension visitor.
82 *
83 * @param[in, out] executing The currently executing thread.
84 * @param[in, out] arg The argument passed to _User_extensions_Iterate().
85 * @param[in] callouts The current callouts.
86 */
87typedef void (*User_extensions_Visitor)(
88  Thread_Control              *executing,
89  void                        *arg,
90  const User_extensions_Table *callouts
91);
92
93typedef struct {
94  Thread_Control *created;
95  bool            ok;
96} User_extensions_Thread_create_context;
97
98void _User_extensions_Thread_create_visitor(
99  Thread_Control              *executing,
100  void                        *arg,
101  const User_extensions_Table *callouts
102);
103
104void _User_extensions_Thread_delete_visitor(
105  Thread_Control              *executing,
106  void                        *arg,
107  const User_extensions_Table *callouts
108);
109
110void _User_extensions_Thread_start_visitor(
111  Thread_Control              *executing,
112  void                        *arg,
113  const User_extensions_Table *callouts
114);
115
116void _User_extensions_Thread_restart_visitor(
117  Thread_Control              *executing,
118  void                        *arg,
119  const User_extensions_Table *callouts
120);
121
122void _User_extensions_Thread_begin_visitor(
123  Thread_Control              *executing,
124  void                        *arg,
125  const User_extensions_Table *callouts
126);
127
128void _User_extensions_Thread_exitted_visitor(
129  Thread_Control              *executing,
130  void                        *arg,
131  const User_extensions_Table *callouts
132);
133
134typedef struct {
135  Internal_errors_Source source;
136  bool                   is_internal;
137  Internal_errors_t      error;
138} User_extensions_Fatal_context;
139
140void _User_extensions_Fatal_visitor(
141  Thread_Control              *executing,
142  void                        *arg,
143  const User_extensions_Table *callouts
144);
145
146void _User_extensions_Thread_terminate_visitor(
147  Thread_Control              *executing,
148  void                        *arg,
149  const User_extensions_Table *callouts
150);
151
152/**
153 * @brief Iterates through all user extensions and calls the visitor for each.
154 *
155 * @param[in, out] arg The argument passed to the visitor.
156 * @param[in] visitor is the visitor for each extension.
157 */
158void _User_extensions_Iterate(
159  void                    *arg,
160  User_extensions_Visitor  visitor
161);
162
163/** @} */
164
165/**
166 * @name Extension Callout Dispatcher
167 */
168/**@{**/
169
170static inline bool _User_extensions_Thread_create( Thread_Control *created )
171{
172  User_extensions_Thread_create_context ctx = { created, true };
173
174  _User_extensions_Iterate( &ctx, _User_extensions_Thread_create_visitor );
175
176  return ctx.ok;
177}
178
179static inline void _User_extensions_Thread_delete( Thread_Control *deleted )
180{
181  _User_extensions_Iterate(
182    deleted,
183    _User_extensions_Thread_delete_visitor
184  );
185}
186
187static inline void _User_extensions_Thread_start( Thread_Control *started )
188{
189  _User_extensions_Iterate(
190    started,
191    _User_extensions_Thread_start_visitor
192  );
193}
194
195static inline void _User_extensions_Thread_restart( Thread_Control *restarted )
196{
197  _User_extensions_Iterate(
198    restarted,
199    _User_extensions_Thread_restart_visitor
200  );
201}
202
203static inline void _User_extensions_Thread_begin( Thread_Control *executing )
204{
205  _User_extensions_Iterate(
206    executing,
207    _User_extensions_Thread_begin_visitor
208  );
209}
210
211static inline void _User_extensions_Thread_switch(
212  Thread_Control *executing,
213  Thread_Control *heir
214)
215{
216  const Chain_Control *chain = &_User_extensions_Switches_list;
217  const Chain_Node    *tail = _Chain_Immutable_tail( chain );
218  const Chain_Node    *node = _Chain_Immutable_first( chain );
219
220  if ( node != tail ) {
221    Per_CPU_Control *cpu_self = _Per_CPU_Get();
222
223    _Per_CPU_Acquire( cpu_self );
224
225    while ( node != tail ) {
226      const User_extensions_Switch_control *extension =
227        (const User_extensions_Switch_control *) node;
228
229      (*extension->thread_switch)( executing, heir );
230
231      node = _Chain_Immutable_next( node );
232    }
233
234    _Per_CPU_Release( cpu_self );
235  }
236}
237
238static inline void _User_extensions_Thread_exitted( Thread_Control *executing )
239{
240  _User_extensions_Iterate(
241    executing,
242    _User_extensions_Thread_exitted_visitor
243  );
244}
245
246static inline void _User_extensions_Fatal(
247  Internal_errors_Source source,
248  bool                   is_internal,
249  Internal_errors_t      error
250)
251{
252  User_extensions_Fatal_context ctx = { source, is_internal, error };
253
254  _User_extensions_Iterate( &ctx, _User_extensions_Fatal_visitor );
255}
256
257static inline void _User_extensions_Thread_terminate(
258  Thread_Control *executing
259)
260{
261  _User_extensions_Iterate(
262    executing,
263    _User_extensions_Thread_terminate_visitor
264  );
265}
266
267/** @} */
268
269/** @} */
270
271#ifdef __cplusplus
272}
273#endif
274
275#endif
276/* end of include file */
Note: See TracBrowser for help on using the repository browser.