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 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042
0043 #include <rtems/score/threadimpl.h>
0044 #include <rtems/score/isrlock.h>
0045 #include <rtems/score/schedulerimpl.h>
0046
0047 #include <string.h>
0048
0049 static RBTREE_DEFINE_EMPTY( _Thread_MP_Active_proxies );
0050
0051 static CHAIN_DEFINE_EMPTY( _Thread_MP_Inactive_proxies );
0052
0053 #if ISR_LOCK_NEEDS_OBJECT
0054 static ISR_lock_Control _Thread_MP_Proxies_lock =
0055 ISR_LOCK_INITIALIZER( "Thread MP Proxies" );
0056 #endif
0057
0058 static void _Thread_MP_Proxies_acquire( ISR_lock_Context *lock_context )
0059 {
0060 _ISR_lock_ISR_disable_and_acquire( &_Thread_MP_Proxies_lock, lock_context );
0061 }
0062
0063 static void _Thread_MP_Proxies_release( ISR_lock_Context *lock_context )
0064 {
0065 _ISR_lock_Release_and_ISR_enable( &_Thread_MP_Proxies_lock, lock_context );
0066 }
0067
0068 void _Thread_MP_Handler_initialization (
0069 uint32_t maximum_proxies
0070 )
0071 {
0072 size_t proxy_size;
0073 char *proxies;
0074 uint32_t i;
0075
0076 if ( maximum_proxies == 0 ) {
0077 return;
0078 }
0079
0080 proxy_size = sizeof( Thread_Proxy_control ) + _Thread_queue_Heads_size;
0081 proxies = (char *) _Thread_MP_Proxies;
0082
0083 _Chain_Initialize(
0084 &_Thread_MP_Inactive_proxies,
0085 proxies,
0086 maximum_proxies,
0087 proxy_size
0088 );
0089
0090 for ( i = 0 ; i < maximum_proxies ; ++i ) {
0091 Thread_Proxy_control *proxy;
0092
0093 proxy = (Thread_Proxy_control *) ( proxies + i * proxy_size );
0094
0095 _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) );
0096 _RBTree_Initialize_node( &proxy->Active );
0097
0098 proxy->Scheduler.nodes = &proxy->Scheduler_node;
0099 _Scheduler_Node_do_initialize(
0100 &_Scheduler_Table[ 0 ],
0101 &proxy->Scheduler_node,
0102 (Thread_Control *) proxy,
0103 0
0104 );
0105
0106 proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ];
0107 _Thread_queue_Heads_initialize( proxy->Wait.spare_heads );
0108 }
0109 }
0110
0111 #define THREAD_MP_PROXY_OF_ACTIVE_NODE( the_node ) \
0112 RTEMS_CONTAINER_OF( the_node, Thread_Proxy_control, Active )
0113
0114 static bool _Thread_MP_Proxy_equal(
0115 const void *left,
0116 const RBTree_Node *right
0117 )
0118 {
0119 const Objects_Id *the_left;
0120 const Thread_Proxy_control *the_right;
0121
0122 the_left = left;
0123 the_right = THREAD_MP_PROXY_OF_ACTIVE_NODE( right );
0124
0125 return *the_left == the_right->Object.id;
0126 }
0127
0128 static bool _Thread_MP_Proxy_less(
0129 const void *left,
0130 const RBTree_Node *right
0131 )
0132 {
0133 const Objects_Id *the_left;
0134 const Thread_Proxy_control *the_right;
0135
0136 the_left = left;
0137 the_right = THREAD_MP_PROXY_OF_ACTIVE_NODE( right );
0138
0139 return *the_left < the_right->Object.id;
0140 }
0141
0142 static void *_Thread_MP_Proxy_map( RBTree_Node *node )
0143 {
0144 return THREAD_MP_PROXY_OF_ACTIVE_NODE( node );
0145 }
0146
0147 Thread_Control *_Thread_MP_Allocate_proxy (
0148 States_Control the_state
0149 )
0150 {
0151 Thread_Proxy_control *the_proxy;
0152 ISR_lock_Context lock_context;
0153
0154 _Thread_MP_Proxies_acquire( &lock_context );
0155
0156 the_proxy = (Thread_Proxy_control *)
0157 _Chain_Get_unprotected( &_Thread_MP_Inactive_proxies );
0158 if ( the_proxy != NULL ) {
0159 Thread_Control *executing;
0160 MP_packet_Prefix *receive_packet;
0161 Objects_Id source_tid;
0162
0163 executing = _Thread_Executing;
0164 receive_packet = _MPCI_Receive_server_tcb->receive_packet;
0165 source_tid = receive_packet->source_tid;
0166
0167 executing->Wait.return_code = STATUS_PROXY_BLOCKING;
0168
0169 the_proxy->receive_packet = receive_packet;
0170 the_proxy->Object.id = source_tid;
0171 the_proxy->Real_priority.priority = receive_packet->source_priority;
0172 the_proxy->current_state = _States_Set( STATES_DORMANT, the_state );
0173
0174 the_proxy->Wait.count = executing->Wait.count;
0175 the_proxy->Wait.return_argument = executing->Wait.return_argument;
0176 the_proxy->Wait.return_argument_second = executing->Wait.return_argument_second;
0177 the_proxy->Wait.option = executing->Wait.option;
0178 the_proxy->Wait.return_code = executing->Wait.return_code;
0179
0180 the_proxy->thread_queue_callout = _Thread_queue_MP_callout_do_nothing;
0181
0182 _RBTree_Insert_inline(
0183 &_Thread_MP_Active_proxies,
0184 &the_proxy->Active,
0185 &source_tid,
0186 _Thread_MP_Proxy_less
0187 );
0188
0189 _Thread_MP_Proxies_release( &lock_context );
0190
0191 return (Thread_Control *) the_proxy;
0192 }
0193
0194 _Thread_MP_Proxies_release( &lock_context );
0195
0196 _Internal_error( INTERNAL_ERROR_OUT_OF_PROXIES );
0197
0198
0199
0200
0201
0202
0203 return NULL;
0204 }
0205
0206 Thread_Control *_Thread_MP_Find_proxy (
0207 Objects_Id the_id
0208 )
0209 {
0210 Thread_Proxy_control *the_proxy;
0211 ISR_lock_Context lock_context;
0212
0213 _Thread_MP_Proxies_acquire( &lock_context );
0214
0215 the_proxy = _RBTree_Find_inline(
0216 &_Thread_MP_Active_proxies,
0217 &the_id,
0218 _Thread_MP_Proxy_equal,
0219 _Thread_MP_Proxy_less,
0220 _Thread_MP_Proxy_map
0221 );
0222
0223 _Thread_MP_Proxies_release( &lock_context );
0224
0225 return (Thread_Control *) the_proxy;
0226 }
0227
0228 void _Thread_MP_Free_proxy( Thread_Control *the_thread )
0229 {
0230 Thread_Proxy_control *the_proxy;
0231 ISR_lock_Context lock_context;
0232
0233 the_proxy = (Thread_Proxy_control *) the_thread;
0234
0235 _Thread_MP_Proxies_acquire( &lock_context );
0236
0237 _RBTree_Extract( &_Thread_MP_Active_proxies, &the_proxy->Active );
0238 _Chain_Append_unprotected(
0239 &_Thread_MP_Inactive_proxies,
0240 &the_proxy->Object.Node
0241 );
0242
0243 _Thread_MP_Proxies_release( &lock_context );
0244 }