source: rtems/cpukit/score/include/rtems/score/userext.h @ 864d3475

4.115
Last change on this file since 864d3475 was 1b1be254, checked in by Sebastian Huber <sebastian.huber@…>, on 03/25/14 at 09:54:49

score: Thread life cycle re-implementation

The thread deletion is now supported on SMP.

This change fixes the following PRs:

PR1814: SMP race condition between stack free and dispatch

PR2035: psxcancel reveals NULL pointer access in _Thread_queue_Extract()

The POSIX cleanup handler are now called in the right context (should be
called in the context of the terminating thread).

http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html

Add a user extension the reflects a thread termination event. This is
used to reclaim the Newlib reentrancy structure (may use file
operations), the POSIX cleanup handlers and the POSIX key destructors.

  • Property mode set to 100644
File size: 8.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_USEREXT_H
19#define _RTEMS_SCORE_USEREXT_H
20
21#include <rtems/score/interr.h>
22#include <rtems/score/chain.h>
23#include <rtems/score/thread.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29typedef void User_extensions_routine RTEMS_COMPILER_DEPRECATED_ATTRIBUTE;
30
31/**
32 * @defgroup ScoreUserExt User Extension Handler
33 *
34 * @ingroup Score
35 *
36 * @brief The User Extension Handler provides invocation of application
37 * dependent routines at critical points in the life of each thread and the
38 * system as a whole.
39 */
40/**@{**/
41
42/**
43 * @brief Task create extension.
44 *
45 * It corresponds to _Thread_Initialize() (used by the rtems_task_create()
46 * directive and pthread_create()).
47 *
48 * It is invoked after the new thread has been completely initialized, but
49 * before it is placed on a ready chain.
50 *
51 * Thread dispatching may be disabled.  This depends on the context of the
52 * _Thread_Initialize() call.  Thread dispatch is disabled during the creation
53 * of the idle thread and the initialization threads.  It can be considered as
54 * an invalid API usage, if the application calls _Thread_Initialize() with
55 * disabled thread dispatching.  Disabled thread dispatching is different from
56 * disabled preemption.
57 *
58 * It can be assumed that the executing thread locked the allocator mutex.
59 * The only exception is the creation of the idle thread.  In this case the
60 * allocator mutex is not locked.  Since the allocator mutex allows nesting the
61 * normal memory allocation routines can be used.
62 *
63 * @param[in] executing The executing thread.
64 * @param[in] created The created thread.
65 *
66 * @retval true Successful operation.
67 * @retval false A thread create user extension will frequently attempt to
68 * allocate resources.  If this allocation fails, then the extension should
69 * return @a false and the entire thread create operation will fail.
70 */
71typedef bool ( *User_extensions_thread_create_extension )(
72  Thread_Control *executing,
73  Thread_Control *created
74);
75
76/**
77 * @brief Task delete extension.
78 *
79 * It corresponds to _Thread_Close() (used by the rtems_task_delete()
80 * directive, pthread_exit() and pthread_cancel()).
81 *
82 * It is invoked before all resources of the thread are deleted.  The executing
83 * and deleted arguments are never equal.
84 *
85 * Thread dispatching is enabled.  The executing thread locked the allocator
86 * mutex.
87 *
88 * @param[in] executing The executing thread.
89 * @param[in] deleted The deleted thread.
90 */
91typedef void( *User_extensions_thread_delete_extension )(
92  Thread_Control *executing,
93  Thread_Control *deleted
94);
95
96/**
97 * @brief Task start extension.
98 *
99 * It corresponds to _Thread_Start() (used by the rtems_task_start()
100 * directive).
101 *
102 * It is invoked after the environment of the thread has been loaded and the
103 * thread has been made ready.
104 *
105 * Thread dispatching is disabled.  The executing thread is not the holder of
106 * the allocator mutex.
107 *
108 * @param[in] executing The executing thread.
109 * @param[in] started The started thread.
110 */
111typedef void( *User_extensions_thread_start_extension )(
112  Thread_Control *executing,
113  Thread_Control *started
114);
115
116/**
117 * @brief Task restart extension.
118 *
119 * It corresponds to _Thread_Restart() (used by the rtems_task_restart()
120 * directive).
121 *
122 * It is invoked in the context of the restarted thread right before the
123 * execution context is reloaded.  The executing and restarted arguments are
124 * always equal.  The thread stack reflects the previous execution context.
125 *
126 * Thread dispatching is enabled.  The thread is not the holder of the
127 * allocator mutex.  The thread life is protected.  Thread restart and delete
128 * requests issued by restart extensions lead to recursion.
129 *
130 * @param[in] executing The executing thread.
131 * @param[in] restarted The executing thread.  Yes, the executing thread.
132 */
133typedef void( *User_extensions_thread_restart_extension )(
134  Thread_Control *executing,
135  Thread_Control *restarted
136);
137
138/**
139 * @brief Task switch extension.
140 *
141 * It corresponds to _Thread_Dispatch().
142 *
143 * It is invoked before the context switch from the executing to the heir
144 * thread.
145 *
146 * Thread dispatching is disabled.  The state of the allocator mutex is
147 * arbitrary.  Interrupts are disabled and the per-CPU lock is acquired on SMP
148 * configurations.
149 *
150 * The context switches initiated through _Thread_Start_multitasking() are not
151 * covered by this extension.
152 *
153 * @param[in] executing The executing thread.
154 * @param[in] heir The heir thread.
155 */
156typedef void( *User_extensions_thread_switch_extension )(
157  Thread_Control *executing,
158  Thread_Control *heir
159);
160
161/**
162 * @brief Task begin extension.
163 *
164 * It corresponds to _Thread_Handler().
165 *
166 * Thread dispatching is disabled.  The executing thread is not the holder of
167 * the allocator mutex.
168 *
169 * @param[in] executing The executing thread.
170 */
171typedef void( *User_extensions_thread_begin_extension )(
172  Thread_Control *executing
173);
174
175/**
176 * @brief Task exitted extension.
177 *
178 * It corresponds to _Thread_Handler() after a return of the entry function.
179 *
180 * Thread dispatching is disabled.  The state of the allocator mutex is
181 * arbitrary.
182 *
183 * @param[in] executing The executing thread.
184 */
185typedef void( *User_extensions_thread_exitted_extension )(
186  Thread_Control *executing
187);
188
189/**
190 * @brief Fatal error extension.
191 *
192 * It corresponds to _Terminate() (used by the rtems_fatal() directive).
193 *
194 * This extension should not call any RTEMS directives.
195 *
196 * @param[in] source The fatal source indicating the subsystem the fatal
197 * condition originated in.
198 * @param[in] is_internal Indicates if the fatal condition was generated
199 * internally to the executive.
200 * @param[in] code The fatal error code.  This value must be interpreted with
201 * respect to the source.
202 */
203typedef void( *User_extensions_fatal_extension )(
204  Internal_errors_Source source,
205  bool                   is_internal,
206  Internal_errors_t      code
207);
208
209/**
210 * @brief Task termination extension.
211 *
212 * This extension is invoked by _Thread_Life_action_handler() in case a
213 * termination request is recognized.
214 *
215 * It is invoked in the context of the terminated thread right before the
216 * thread dispatch to the heir thread.  The POSIX cleanup and key destructors
217 * execute in this context.
218 *
219 * Thread dispatching is enabled.  The thread is not the holder of the
220 * allocator mutex.  The thread life is protected.  Thread restart and delete
221 * requests issued by terminate extensions lead to recursion.
222 *
223 * @param[in] terminated The terminated thread.
224 */
225typedef void( *User_extensions_thread_terminate_extension )(
226  Thread_Control *terminated
227);
228
229/**
230 * @brief User extension table.
231 */
232typedef struct {
233  User_extensions_thread_create_extension  thread_create;
234  User_extensions_thread_start_extension   thread_start;
235  User_extensions_thread_restart_extension thread_restart;
236  User_extensions_thread_delete_extension  thread_delete;
237  User_extensions_thread_switch_extension  thread_switch;
238  User_extensions_thread_begin_extension   thread_begin;
239  User_extensions_thread_exitted_extension thread_exitted;
240  User_extensions_fatal_extension          fatal;
241  User_extensions_thread_terminate_extension thread_terminate;
242}   User_extensions_Table;
243
244/**
245 * @brief Manages the switch callouts.
246 *
247 * They are managed separately from other extensions for performance reasons.
248 */
249typedef struct {
250  Chain_Node                              Node;
251  User_extensions_thread_switch_extension thread_switch;
252}   User_extensions_Switch_control;
253
254/**
255 * @brief Manages each user extension set.
256 *
257 * The switch control is part of the extensions control even if not used due to
258 * the extension not having a switch handler.
259 */
260typedef struct {
261  Chain_Node                     Node;
262  User_extensions_Switch_control Switch;
263  User_extensions_Table          Callouts;
264}   User_extensions_Control;
265
266/** @} */
267
268#ifdef __cplusplus
269}
270#endif
271
272#endif
273/* end of include file */
Note: See TracBrowser for help on using the repository browser.