File indexing completed on 2025-05-11 08:24:22
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 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/rtems/signalimpl.h>
0043 #include <rtems/rtems/modesimpl.h>
0044 #include <rtems/rtems/tasksdata.h>
0045 #include <rtems/score/schedulerimpl.h>
0046 #include <rtems/score/threaddispatch.h>
0047 #include <rtems/score/threadimpl.h>
0048
0049 #include <rtems/sysinit.h>
0050
0051 static void _Signal_Action_handler(
0052 Thread_Control *executing,
0053 Thread_Action *action,
0054 ISR_lock_Context *lock_context
0055 )
0056 {
0057 RTEMS_API_Control *api;
0058 ASR_Information *asr;
0059 rtems_signal_set signal_set;
0060 bool normal_is_preemptible;
0061 Thread_CPU_budget_control normal_cpu_budget;
0062 uint32_t normal_isr_level;
0063 uint32_t before_call_isr_level;
0064 bool after_call_is_preemptible;
0065 bool after_call_asr_is_enabled;
0066
0067 (void) action;
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 api = executing->API_Extensions[ THREAD_API_RTEMS ];
0079 asr = &api->Signal;
0080
0081
0082 signal_set = asr->signals_pending;
0083 _Assert( signal_set != 0 );
0084 asr->signals_pending = 0;
0085
0086
0087
0088 _Assert( asr->is_enabled );
0089 normal_is_preemptible = executing->is_preemptible;
0090 normal_cpu_budget = executing->CPU_budget;
0091
0092
0093
0094 executing->is_preemptible = _Modes_Is_preempt( asr->mode_set );
0095 asr->is_enabled = !_Modes_Is_asr_disabled( asr->mode_set );
0096 _Modes_Apply_timeslice_to_thread( asr->mode_set, executing );
0097 before_call_isr_level = _Modes_Get_interrupt_level( asr->mode_set );
0098
0099 if ( executing->is_preemptible && !normal_is_preemptible ) {
0100 Per_CPU_Control *cpu_self;
0101
0102 cpu_self = _Thread_Dispatch_disable_critical( lock_context );
0103 _Scheduler_Schedule( executing );
0104 _Thread_State_release( executing, lock_context );
0105 _Thread_Dispatch_direct( cpu_self );
0106 } else {
0107 _Thread_State_release( executing, lock_context );
0108 }
0109
0110 normal_isr_level = _ISR_Get_level();
0111 _ISR_Set_level( before_call_isr_level );
0112
0113
0114 ( *asr->handler )( signal_set );
0115
0116
0117
0118 _ISR_Set_level( normal_isr_level );
0119
0120 _Thread_State_acquire( executing, lock_context );
0121
0122 executing->CPU_budget = normal_cpu_budget;
0123 after_call_is_preemptible = executing->is_preemptible;
0124 executing->is_preemptible = normal_is_preemptible;
0125
0126
0127
0128
0129
0130
0131
0132
0133 if ( normal_is_preemptible && !after_call_is_preemptible ) {
0134 Per_CPU_Control *cpu_self;
0135
0136 cpu_self = _Thread_Dispatch_disable_critical( lock_context );
0137 _Scheduler_Schedule( executing );
0138 _Thread_State_release( executing, lock_context );
0139 _Thread_Dispatch_direct( cpu_self );
0140 _Thread_State_acquire( executing, lock_context );
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150 after_call_asr_is_enabled = asr->is_enabled;
0151 asr->is_enabled = true;
0152
0153 if ( !after_call_asr_is_enabled && asr->signals_pending != 0 ) {
0154 _Thread_Append_post_switch_action( executing, action );
0155 }
0156 }
0157
0158 rtems_status_code rtems_signal_send(
0159 rtems_id id,
0160 rtems_signal_set signal_set
0161 )
0162 {
0163 Thread_Control *the_thread;
0164 ISR_lock_Context lock_context;
0165 RTEMS_API_Control *api;
0166 ASR_Information *asr;
0167
0168 if ( signal_set == 0 ) {
0169 return RTEMS_INVALID_NUMBER;
0170 }
0171
0172 the_thread = _Thread_Get( id, &lock_context );
0173
0174 if ( the_thread == NULL ) {
0175 #if defined(RTEMS_MULTIPROCESSING)
0176 return _Signal_MP_Send( id, signal_set );
0177 #else
0178 return RTEMS_INVALID_ID;
0179 #endif
0180 }
0181
0182 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
0183 asr = &api->Signal;
0184
0185 _Thread_State_acquire_critical( the_thread, &lock_context );
0186
0187 if ( asr->handler == NULL ) {
0188 _Thread_State_release( the_thread, &lock_context );
0189 return RTEMS_NOT_DEFINED;
0190 }
0191
0192
0193 asr->signals_pending |= signal_set;
0194
0195 if ( asr->is_enabled ) {
0196 Per_CPU_Control *cpu_self;
0197
0198 _Thread_Add_post_switch_action(
0199 the_thread,
0200 &api->Signal_action,
0201 _Signal_Action_handler
0202 );
0203 cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
0204 _Thread_State_release( the_thread, &lock_context );
0205 _Thread_Dispatch_enable( cpu_self );
0206 } else {
0207 _Thread_State_release( the_thread, &lock_context );
0208 }
0209
0210 return RTEMS_SUCCESSFUL;
0211 }
0212
0213 #if defined(RTEMS_MULTIPROCESSING)
0214 static void _Signal_MP_Initialize( void )
0215 {
0216 _MPCI_Register_packet_processor(
0217 MP_PACKET_SIGNAL,
0218 _Signal_MP_Process_packet
0219 );
0220 }
0221
0222 RTEMS_SYSINIT_ITEM(
0223 _Signal_MP_Initialize,
0224 RTEMS_SYSINIT_CLASSIC_SIGNAL_MP,
0225 RTEMS_SYSINIT_ORDER_MIDDLE
0226 );
0227 #endif