File indexing completed on 2025-05-11 08:24:21
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 <pthread.h>
0044 #include <signal.h>
0045 #include <errno.h>
0046
0047 #include <rtems/posix/pthreadimpl.h>
0048 #include <rtems/posix/psignalimpl.h>
0049 #include <rtems/score/isr.h>
0050 #include <rtems/score/statesimpl.h>
0051 #include <rtems/seterr.h>
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 #if defined(DEBUG_SIGNAL_PROCESSING)
0062 #include <rtems/bspIo.h>
0063 #define DEBUG_STEP(_x) printk(_x)
0064 #else
0065 #define DEBUG_STEP(_x)
0066 #endif
0067
0068
0069
0070
0071
0072
0073
0074 #define _POSIX_signals_Is_interested( _api, _mask ) \
0075 ( (_api)->signals_unblocked & (_mask) )
0076
0077 int _POSIX_signals_Send(
0078 pid_t pid,
0079 int sig,
0080 const union sigval *value
0081 )
0082 {
0083 sigset_t mask;
0084 POSIX_API_Control *api;
0085 uint32_t the_api;
0086 uint32_t index;
0087 uint32_t maximum;
0088 Objects_Information *the_info;
0089 Objects_Control **object_table;
0090 Thread_Control *the_thread;
0091 Thread_Control *interested;
0092 Priority_Control interested_priority;
0093 Chain_Node *the_node;
0094 siginfo_t siginfo_struct;
0095 siginfo_t *siginfo;
0096 POSIX_signals_Siginfo_node *psiginfo;
0097 Thread_queue_Heads *heads;
0098 Thread_queue_Context queue_context;
0099 Per_CPU_Control *cpu_self;
0100
0101
0102
0103
0104 if ( pid != getpid() )
0105 rtems_set_errno_and_return_minus_one( ESRCH );
0106
0107
0108
0109
0110 if ( !sig )
0111 rtems_set_errno_and_return_minus_one( EINVAL );
0112
0113 if ( !is_valid_signo(sig) )
0114 rtems_set_errno_and_return_minus_one( EINVAL );
0115
0116
0117
0118
0119 if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
0120 return 0;
0121
0122
0123
0124
0125
0126
0127 if ( (sig == SIGFPE) || (sig == SIGILL) || (sig == SIGSEGV ) )
0128 return pthread_kill( pthread_self(), sig );
0129
0130 mask = signo_to_mask( sig );
0131
0132
0133
0134
0135 siginfo = &siginfo_struct;
0136 siginfo->si_signo = sig;
0137 siginfo->si_code = SI_USER;
0138 if ( !value ) {
0139 siginfo->si_value.sival_int = 0;
0140 } else {
0141 siginfo->si_value = *value;
0142 }
0143
0144
0145 cpu_self = _Thread_Dispatch_disable();
0146
0147
0148
0149
0150
0151 the_thread = _Per_CPU_Get_executing( cpu_self );
0152
0153 api = the_thread->API_Extensions[ THREAD_API_POSIX ];
0154 if ( _POSIX_signals_Is_interested( api, mask ) ) {
0155 goto process_it;
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 heads = _POSIX_signals_Wait_queue.Queue.heads;
0167 if ( heads != NULL ) {
0168 Chain_Control *the_chain = &heads->Heads.Fifo;
0169
0170 for ( the_node = _Chain_First( the_chain );
0171 !_Chain_Is_tail( the_chain, the_node ) ;
0172 the_node = the_node->next ) {
0173 Scheduler_Node *scheduler_node;
0174
0175 scheduler_node = SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( the_node );
0176 the_thread = _Scheduler_Node_get_owner( scheduler_node );
0177 api = the_thread->API_Extensions[ THREAD_API_POSIX ];
0178
0179 #if defined(DEBUG_SIGNAL_PROCESSING)
0180 printk( "Waiting Thread=%p option=0x%08x mask=0x%08x blocked=0x%08x\n",
0181 the_thread, the_thread->Wait.option, mask, ~api->signals_unblocked);
0182 #endif
0183
0184
0185
0186
0187 if (the_thread->Wait.option & mask)
0188 goto process_it;
0189
0190
0191
0192
0193
0194 if (api->signals_unblocked & mask)
0195 goto process_it;
0196 }
0197 }
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 interested = NULL;
0215 interested_priority = UINT64_MAX;
0216
0217 for (the_api = OBJECTS_CLASSIC_API; the_api <= OBJECTS_APIS_LAST; the_api++) {
0218 _Assert( _Objects_Information_table[ the_api ] != NULL );
0219 the_info = _Objects_Information_table[ the_api ][ 1 ];
0220 if ( !the_info )
0221 continue;
0222
0223 maximum = _Objects_Get_maximum_index( the_info );
0224 object_table = the_info->local_table;
0225
0226 for ( index = 0 ; index < maximum ; ++index ) {
0227 the_thread = (Thread_Control *) object_table[ index ];
0228
0229 if ( !the_thread )
0230 continue;
0231
0232 #if defined(DEBUG_SIGNAL_PROCESSING)
0233 printk("\n 0x%08x/0x%08x %d/%d 0x%08x 1",
0234 the_thread->Object.id,
0235 ((interested) ? interested->Object.id : 0),
0236 _Thread_Get_priority( the_thread ), interested_priority,
0237 the_thread->current_state
0238 );
0239 #endif
0240
0241
0242
0243
0244
0245 if ( _Thread_Get_priority( the_thread ) > interested_priority )
0246 continue;
0247 DEBUG_STEP("2");
0248
0249
0250
0251
0252 api = the_thread->API_Extensions[ THREAD_API_POSIX ];
0253
0254 #if defined(RTEMS_DEBUG)
0255 if ( !api )
0256 continue;
0257 #endif
0258
0259 if ( !_POSIX_signals_Is_interested( api, mask ) )
0260 continue;
0261 DEBUG_STEP("3");
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 if ( _Thread_Get_priority( the_thread ) < interested_priority ) {
0273 interested = the_thread;
0274 interested_priority = _Thread_Get_priority( the_thread );
0275 continue;
0276 }
0277 DEBUG_STEP("4");
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 if ( interested && !_States_Is_ready( interested->current_state ) ) {
0288
0289 DEBUG_STEP("5");
0290 if ( _States_Is_ready( the_thread->current_state ) ) {
0291 interested = the_thread;
0292 interested_priority = _Thread_Get_priority( the_thread );
0293 continue;
0294 }
0295
0296 DEBUG_STEP("6");
0297
0298 if ( !_States_Is_interruptible_by_signal(interested->current_state) ) {
0299 DEBUG_STEP("7");
0300 if ( _States_Is_interruptible_by_signal(the_thread->current_state) ) {
0301 DEBUG_STEP("8");
0302 interested = the_thread;
0303 interested_priority = _Thread_Get_priority( the_thread );
0304 continue;
0305 }
0306 }
0307 }
0308 }
0309 }
0310
0311 if ( interested ) {
0312 the_thread = interested;
0313 goto process_it;
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 goto post_process_signal;
0327
0328
0329
0330
0331
0332
0333 process_it:
0334
0335
0336
0337
0338
0339 if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
0340 _Thread_Dispatch_enable( cpu_self );
0341 return 0;
0342 }
0343
0344 post_process_signal:
0345
0346
0347
0348
0349
0350 _POSIX_signals_Set_process_signals( mask );
0351
0352 _Thread_queue_Context_initialize( &queue_context );
0353 _POSIX_signals_Acquire( &queue_context );
0354
0355 if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
0356
0357 psiginfo = (POSIX_signals_Siginfo_node *)
0358 _Chain_Get_unprotected( &_POSIX_signals_Inactive_siginfo );
0359 if ( !psiginfo ) {
0360 _POSIX_signals_Release( &queue_context );
0361 _Thread_Dispatch_enable( cpu_self );
0362 rtems_set_errno_and_return_minus_one( EAGAIN );
0363 }
0364
0365 psiginfo->Info = *siginfo;
0366
0367 _Chain_Append_unprotected(
0368 &_POSIX_signals_Siginfo[ sig ],
0369 &psiginfo->Node
0370 );
0371 }
0372
0373 _POSIX_signals_Release( &queue_context );
0374 DEBUG_STEP("\n");
0375 _Thread_Dispatch_enable( cpu_self );
0376 return 0;
0377 }