File indexing completed on 2025-05-11 08:24:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #ifdef HAVE_CONFIG_H
0045 #include "config.h"
0046 #endif
0047
0048 #include <rtems/score/userextimpl.h>
0049
0050 User_extensions_List _User_extensions_List = {
0051 CHAIN_INITIALIZER_EMPTY( _User_extensions_List.Active ),
0052 CHAIN_ITERATOR_REGISTRY_INITIALIZER( _User_extensions_List.Iterators )
0053 #if defined(RTEMS_SMP)
0054 ,
0055 ISR_LOCK_INITIALIZER( "User Extensions List" )
0056 #endif
0057 };
0058
0059 void _User_extensions_Thread_create_visitor(
0060 Thread_Control *executing,
0061 void *arg,
0062 const User_extensions_Table *callouts
0063 )
0064 {
0065 User_extensions_thread_create_extension callout = callouts->thread_create;
0066
0067 if ( callout != NULL ) {
0068 User_extensions_Thread_create_context *ctx = arg;
0069
0070 ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
0071 }
0072 }
0073
0074 void _User_extensions_Thread_delete_visitor(
0075 Thread_Control *executing,
0076 void *arg,
0077 const User_extensions_Table *callouts
0078 )
0079 {
0080 User_extensions_thread_delete_extension callout = callouts->thread_delete;
0081
0082 if ( callout != NULL ) {
0083 (*callout)( executing, arg );
0084 }
0085 }
0086
0087 void _User_extensions_Thread_start_visitor(
0088 Thread_Control *executing,
0089 void *arg,
0090 const User_extensions_Table *callouts
0091 )
0092 {
0093 User_extensions_thread_start_extension callout = callouts->thread_start;
0094
0095 if ( callout != NULL ) {
0096 (*callout)( executing, arg );
0097 }
0098 }
0099
0100 void _User_extensions_Thread_restart_visitor(
0101 Thread_Control *executing,
0102 void *arg,
0103 const User_extensions_Table *callouts
0104 )
0105 {
0106 User_extensions_thread_restart_extension callout = callouts->thread_restart;
0107
0108 if ( callout != NULL ) {
0109 (*callout)( executing, arg );
0110 }
0111 }
0112
0113 void _User_extensions_Thread_begin_visitor(
0114 Thread_Control *executing,
0115 void *arg,
0116 const User_extensions_Table *callouts
0117 )
0118 {
0119 User_extensions_thread_begin_extension callout = callouts->thread_begin;
0120
0121 (void) arg;
0122
0123 if ( callout != NULL ) {
0124 (*callout)( executing );
0125 }
0126 }
0127
0128 void _User_extensions_Thread_exitted_visitor(
0129 Thread_Control *executing,
0130 void *arg,
0131 const User_extensions_Table *callouts
0132 )
0133 {
0134 User_extensions_thread_exitted_extension callout = callouts->thread_exitted;
0135
0136 if ( callout != NULL ) {
0137 (*callout)( executing );
0138 }
0139 }
0140
0141 void _User_extensions_Fatal_visitor(
0142 Thread_Control *executing,
0143 void *arg,
0144 const User_extensions_Table *callouts
0145 )
0146 {
0147 User_extensions_fatal_extension callout = callouts->fatal;
0148
0149 if ( callout != NULL ) {
0150 const User_extensions_Fatal_context *ctx = arg;
0151
0152 (*callout)( ctx->source, false, ctx->error );
0153 }
0154 }
0155
0156 void _User_extensions_Thread_terminate_visitor(
0157 Thread_Control *executing,
0158 void *arg,
0159 const User_extensions_Table *callouts
0160 )
0161 {
0162 User_extensions_thread_terminate_extension callout =
0163 callouts->thread_terminate;
0164
0165 if ( callout != NULL ) {
0166 (*callout)( executing );
0167 }
0168 }
0169
0170 void _User_extensions_Iterate(
0171 void *arg,
0172 User_extensions_Visitor visitor,
0173 Chain_Iterator_direction direction
0174 )
0175 {
0176 Thread_Control *executing;
0177 const User_extensions_Table *initial_current;
0178 const User_extensions_Table *initial_begin;
0179 const User_extensions_Table *initial_end;
0180 const Chain_Node *end;
0181 Chain_Node *node;
0182 User_extensions_Iterator iter;
0183 ISR_lock_Context lock_context;
0184
0185 executing = _Thread_Get_executing();
0186
0187 initial_begin = _User_extensions_Initial_extensions;
0188 initial_end = initial_begin + _User_extensions_Initial_count;
0189
0190 if ( direction == CHAIN_ITERATOR_FORWARD ) {
0191 initial_current = initial_begin;
0192
0193 while ( initial_current != initial_end ) {
0194 (*visitor)( executing, arg, initial_current );
0195 ++initial_current;
0196 }
0197
0198 end = _Chain_Immutable_tail( &_User_extensions_List.Active );
0199 } else {
0200 end = _Chain_Immutable_head( &_User_extensions_List.Active );
0201 }
0202
0203 _User_extensions_Acquire( &lock_context );
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 #pragma GCC diagnostic push
0215 #pragma GCC diagnostic ignored "-Wdangling-pointer="
0216 _Chain_Iterator_initialize(
0217 &_User_extensions_List.Active,
0218 &_User_extensions_List.Iterators,
0219 &iter.Iterator,
0220 direction
0221 );
0222 #pragma GCC diagnostic pop
0223
0224 if ( executing != NULL ) {
0225 iter.previous = executing->last_user_extensions_iterator;
0226 executing->last_user_extensions_iterator = &iter;
0227 }
0228
0229 while ( ( node = _Chain_Iterator_next( &iter.Iterator ) ) != end ) {
0230 const User_extensions_Control *extension;
0231
0232 _Chain_Iterator_set_position( &iter.Iterator, node );
0233
0234 _User_extensions_Release( &lock_context );
0235
0236 extension = (const User_extensions_Control *) node;
0237 ( *visitor )( executing, arg, &extension->Callouts );
0238
0239 _User_extensions_Acquire( &lock_context );
0240 }
0241
0242 if ( executing != NULL ) {
0243 executing->last_user_extensions_iterator = iter.previous;
0244 }
0245
0246 _Chain_Iterator_destroy( &iter.Iterator );
0247
0248 _User_extensions_Release( &lock_context );
0249
0250 if ( direction == CHAIN_ITERATOR_BACKWARD ) {
0251 initial_current = initial_end;
0252
0253 while ( initial_current != initial_begin ) {
0254 --initial_current;
0255 (*visitor)( executing, arg, initial_current );
0256 }
0257 }
0258 }