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/messageimpl.h>
0043 #include <rtems/rtems/optionsimpl.h>
0044 #include <rtems/rtems/statusimpl.h>
0045 #include <rtems/score/coremsgimpl.h>
0046 #include <rtems/score/statesimpl.h>
0047 #include <rtems/score/threadimpl.h>
0048 #include <rtems/sysinit.h>
0049
0050 RTEMS_STATIC_ASSERT(
0051 MESSAGE_QUEUE_MP_PACKET_SIZE <= MP_PACKET_MINIMUM_PACKET_SIZE,
0052 Message_queue_MP_Packet
0053 );
0054
0055 static Message_queue_MP_Packet *_Message_queue_MP_Get_packet( void )
0056 {
0057 return (Message_queue_MP_Packet *) _MPCI_Get_packet();
0058 }
0059
0060
0061
0062
0063
0064
0065
0066 void _Message_queue_MP_Send_process_packet (
0067 Message_queue_MP_Remote_operations operation,
0068 Objects_Id message_queue_id,
0069 rtems_name name,
0070 Objects_Id proxy_id
0071 )
0072 {
0073 Message_queue_MP_Packet *the_packet;
0074 uint32_t node;
0075
0076 switch ( operation ) {
0077
0078 case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
0079 case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
0080 case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
0081
0082 the_packet = _Message_queue_MP_Get_packet();
0083 the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
0084 the_packet->Prefix.length = MESSAGE_QUEUE_MP_PACKET_SIZE;
0085 the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
0086 the_packet->operation = operation;
0087 the_packet->Prefix.id = message_queue_id;
0088 the_packet->name = name;
0089 the_packet->proxy_id = proxy_id;
0090
0091 if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY )
0092 node = _Objects_Get_node( message_queue_id );
0093 else
0094 node = MPCI_ALL_NODES;
0095
0096 _MPCI_Send_process_packet( node, &the_packet->Prefix );
0097 break;
0098
0099 case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
0100 case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
0101 case MESSAGE_QUEUE_MP_SEND_REQUEST:
0102 case MESSAGE_QUEUE_MP_SEND_RESPONSE:
0103 case MESSAGE_QUEUE_MP_URGENT_REQUEST:
0104 case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
0105 case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
0106 case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
0107 case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
0108 case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
0109 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
0110 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
0111 break;
0112
0113 }
0114 }
0115
0116
0117
0118
0119
0120
0121 static rtems_status_code _Message_queue_MP_Send_request_packet (
0122 Objects_Id message_queue_id,
0123 const void *buffer,
0124 size_t *size_p,
0125 rtems_option option_set,
0126 rtems_interval timeout,
0127 Message_queue_MP_Remote_operations operation
0128 )
0129 {
0130 Message_queue_MP_Packet *the_packet;
0131 Status_Control status;
0132
0133 if ( !_Message_queue_MP_Is_remote( message_queue_id ) ) {
0134 return RTEMS_INVALID_ID;
0135 }
0136
0137 switch ( operation ) {
0138
0139 case MESSAGE_QUEUE_MP_SEND_REQUEST:
0140 case MESSAGE_QUEUE_MP_URGENT_REQUEST:
0141 case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
0142 case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
0143 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
0144
0145 the_packet = _Message_queue_MP_Get_packet();
0146 the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
0147 the_packet->Prefix.length = MESSAGE_QUEUE_MP_PACKET_SIZE;
0148 if ( size_p )
0149 the_packet->Prefix.length += *size_p;
0150 the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
0151
0152
0153
0154
0155
0156
0157
0158 if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) {
0159 return RTEMS_INVALID_SIZE;
0160 }
0161
0162 if (! _Options_Is_no_wait(option_set))
0163 the_packet->Prefix.timeout = timeout;
0164
0165 the_packet->operation = operation;
0166 the_packet->Prefix.id = message_queue_id;
0167 the_packet->option_set = option_set;
0168
0169
0170
0171
0172
0173 if (buffer) {
0174 the_packet->size = *size_p;
0175 _CORE_message_queue_Copy_buffer(
0176 buffer,
0177 the_packet->buffer,
0178 *size_p
0179 );
0180 }
0181
0182 status = _MPCI_Send_request_packet(
0183 _Objects_Get_node(message_queue_id),
0184 &the_packet->Prefix,
0185 STATES_WAITING_FOR_MESSAGE
0186 );
0187 return _Status_Get( status );
0188
0189 case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
0190
0191 the_packet = _Message_queue_MP_Get_packet();
0192 the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE;
0193 the_packet->Prefix.length = MESSAGE_QUEUE_MP_PACKET_SIZE;
0194 the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
0195
0196 if (! _Options_Is_no_wait(option_set))
0197 the_packet->Prefix.timeout = timeout;
0198
0199 the_packet->operation = MESSAGE_QUEUE_MP_RECEIVE_REQUEST;
0200 the_packet->Prefix.id = message_queue_id;
0201 the_packet->option_set = option_set;
0202 the_packet->size = 0;
0203
0204 _Thread_Executing->Wait.return_argument_second.immutable_object = buffer;
0205 _Thread_Executing->Wait.return_argument = size_p;
0206
0207 status = _MPCI_Send_request_packet(
0208 _Objects_Get_node(message_queue_id),
0209 &the_packet->Prefix,
0210 STATES_WAITING_FOR_MESSAGE
0211 );
0212 return _Status_Get( status );
0213
0214 case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
0215 case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
0216 case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
0217 case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
0218 case MESSAGE_QUEUE_MP_SEND_RESPONSE:
0219 case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
0220 case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
0221 case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
0222 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
0223 break;
0224 }
0225
0226 return RTEMS_SUCCESSFUL;
0227 }
0228
0229 rtems_status_code _Message_queue_MP_Broadcast(
0230 rtems_id id,
0231 const void *buffer,
0232 size_t size,
0233 uint32_t *count
0234 )
0235 {
0236 _Thread_Get_executing()->Wait.return_argument = count;
0237 return _Message_queue_MP_Send_request_packet(
0238 id,
0239 buffer,
0240 &size,
0241 0,
0242 MPCI_DEFAULT_TIMEOUT,
0243 MESSAGE_QUEUE_MP_BROADCAST_REQUEST
0244 );
0245 }
0246
0247 rtems_status_code _Message_queue_MP_Flush(
0248 rtems_id id,
0249 uint32_t *count
0250 )
0251 {
0252 _Thread_Get_executing()->Wait.return_argument = count;
0253 return _Message_queue_MP_Send_request_packet(
0254 id,
0255 NULL,
0256 NULL,
0257 0,
0258 MPCI_DEFAULT_TIMEOUT,
0259 MESSAGE_QUEUE_MP_FLUSH_REQUEST
0260 );
0261 }
0262
0263 rtems_status_code _Message_queue_MP_Get_number_pending(
0264 rtems_id id,
0265 uint32_t *count
0266 )
0267 {
0268 _Thread_Get_executing()->Wait.return_argument = count;
0269 return _Message_queue_MP_Send_request_packet(
0270 id,
0271 NULL,
0272 NULL,
0273 0,
0274 MPCI_DEFAULT_TIMEOUT,
0275 MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST
0276 );
0277 }
0278
0279 rtems_status_code _Message_queue_MP_Receive(
0280 rtems_id id,
0281 void *buffer,
0282 size_t *size,
0283 rtems_option option_set,
0284 rtems_interval timeout
0285 )
0286 {
0287 return _Message_queue_MP_Send_request_packet(
0288 id,
0289 buffer,
0290 size,
0291 option_set,
0292 timeout,
0293 MESSAGE_QUEUE_MP_RECEIVE_REQUEST
0294 );
0295 }
0296
0297 rtems_status_code _Message_queue_MP_Send(
0298 rtems_id id,
0299 const void *buffer,
0300 size_t size
0301 )
0302 {
0303 return _Message_queue_MP_Send_request_packet(
0304 id,
0305 buffer,
0306 &size,
0307 0,
0308 MPCI_DEFAULT_TIMEOUT,
0309 MESSAGE_QUEUE_MP_SEND_REQUEST
0310 );
0311 }
0312
0313 rtems_status_code _Message_queue_MP_Urgent(
0314 rtems_id id,
0315 const void *buffer,
0316 size_t size
0317 )
0318 {
0319 return _Message_queue_MP_Send_request_packet(
0320 id,
0321 buffer,
0322 &size,
0323 0,
0324 MPCI_DEFAULT_TIMEOUT,
0325 MESSAGE_QUEUE_MP_URGENT_REQUEST
0326 );
0327 }
0328
0329
0330
0331
0332
0333
0334 static void _Message_queue_MP_Send_response_packet (
0335 Message_queue_MP_Remote_operations operation,
0336 Objects_Id message_queue_id,
0337 Thread_Control *the_thread
0338 )
0339 {
0340 Message_queue_MP_Packet *the_packet;
0341
0342 switch ( operation ) {
0343
0344 case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
0345 case MESSAGE_QUEUE_MP_SEND_RESPONSE:
0346 case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
0347 case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
0348 case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
0349 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
0350
0351 the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet;
0352
0353
0354
0355
0356
0357
0358
0359
0360 the_packet->operation = operation;
0361 the_packet->Prefix.id = the_packet->Prefix.source_tid;
0362
0363 if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE)
0364 the_packet->Prefix.length += the_packet->size;
0365
0366 _MPCI_Send_response_packet(
0367 _Objects_Get_node( the_packet->Prefix.source_tid ),
0368 &the_packet->Prefix
0369 );
0370 break;
0371
0372 case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
0373 case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
0374 case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
0375 case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
0376 case MESSAGE_QUEUE_MP_SEND_REQUEST:
0377 case MESSAGE_QUEUE_MP_URGENT_REQUEST:
0378 case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
0379 case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
0380 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
0381 break;
0382
0383 }
0384 }
0385
0386 static void _Message_queue_MP_Process_packet (
0387 rtems_packet_prefix *the_packet_prefix
0388 )
0389 {
0390 Message_queue_MP_Packet *the_packet;
0391 Thread_Control *the_thread;
0392
0393 the_packet = (Message_queue_MP_Packet *) the_packet_prefix;
0394
0395 switch ( the_packet->operation ) {
0396
0397 case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
0398
0399 _Objects_MP_Allocate_and_open(
0400 &_Message_queue_Information,
0401 the_packet->name,
0402 the_packet->Prefix.id,
0403 true
0404 );
0405
0406 _MPCI_Return_packet( the_packet_prefix );
0407 break;
0408
0409 case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
0410
0411 _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );
0412
0413 _MPCI_Return_packet( the_packet_prefix );
0414 break;
0415
0416 case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
0417
0418 the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
0419
0420 if ( the_thread != NULL ) {
0421 _Thread_queue_Extract( the_thread );
0422 }
0423
0424 _MPCI_Return_packet( the_packet_prefix );
0425 break;
0426
0427 case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
0428
0429 the_packet->Prefix.return_code = rtems_message_queue_receive(
0430 the_packet->Prefix.id,
0431 the_packet->buffer,
0432 &the_packet->size,
0433 the_packet->option_set,
0434 the_packet->Prefix.timeout
0435 );
0436
0437 if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
0438 _Message_queue_MP_Send_response_packet(
0439 MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
0440 the_packet->Prefix.id,
0441 _Thread_Executing
0442 );
0443 break;
0444
0445 case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
0446
0447 the_thread = _MPCI_Process_response( the_packet_prefix );
0448
0449 if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
0450 *(size_t *) the_thread->Wait.return_argument =
0451 the_packet->size;
0452
0453 _CORE_message_queue_Copy_buffer(
0454 the_packet->buffer,
0455 the_thread->Wait.return_argument_second.mutable_object,
0456 the_packet->size
0457 );
0458 }
0459
0460 _MPCI_Return_packet( the_packet_prefix );
0461 break;
0462
0463 case MESSAGE_QUEUE_MP_SEND_REQUEST:
0464
0465 the_packet->Prefix.return_code = rtems_message_queue_send(
0466 the_packet->Prefix.id,
0467 the_packet->buffer,
0468 the_packet->size
0469 );
0470
0471 _Message_queue_MP_Send_response_packet(
0472 MESSAGE_QUEUE_MP_SEND_RESPONSE,
0473 the_packet->Prefix.id,
0474 _Thread_Executing
0475 );
0476 break;
0477
0478 case MESSAGE_QUEUE_MP_SEND_RESPONSE:
0479 case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
0480
0481 the_thread = _MPCI_Process_response( the_packet_prefix );
0482
0483 _MPCI_Return_packet( the_packet_prefix );
0484 break;
0485
0486 case MESSAGE_QUEUE_MP_URGENT_REQUEST:
0487
0488 the_packet->Prefix.return_code = rtems_message_queue_urgent(
0489 the_packet->Prefix.id,
0490 the_packet->buffer,
0491 the_packet->size
0492 );
0493
0494 _Message_queue_MP_Send_response_packet(
0495 MESSAGE_QUEUE_MP_URGENT_RESPONSE,
0496 the_packet->Prefix.id,
0497 _Thread_Executing
0498 );
0499 break;
0500
0501 case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
0502
0503 the_packet->Prefix.return_code = rtems_message_queue_broadcast(
0504 the_packet->Prefix.id,
0505 the_packet->buffer,
0506 the_packet->size,
0507 &the_packet->count
0508 );
0509
0510 _Message_queue_MP_Send_response_packet(
0511 MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
0512 the_packet->Prefix.id,
0513 _Thread_Executing
0514 );
0515 break;
0516
0517 case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
0518 case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
0519 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
0520
0521 the_thread = _MPCI_Process_response( the_packet_prefix );
0522
0523 *(uint32_t *) the_thread->Wait.return_argument = the_packet->count;
0524
0525 _MPCI_Return_packet( the_packet_prefix );
0526 break;
0527
0528 case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
0529
0530 the_packet->Prefix.return_code = rtems_message_queue_flush(
0531 the_packet->Prefix.id,
0532 &the_packet->count
0533 );
0534
0535 _Message_queue_MP_Send_response_packet(
0536 MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
0537 the_packet->Prefix.id,
0538 _Thread_Executing
0539 );
0540 break;
0541
0542 case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
0543
0544 the_packet->Prefix.return_code = rtems_message_queue_get_number_pending(
0545 the_packet->Prefix.id,
0546 &the_packet->count
0547 );
0548
0549 _Message_queue_MP_Send_response_packet(
0550 MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE,
0551 the_packet->Prefix.id,
0552 _Thread_Executing
0553 );
0554 break;
0555
0556 }
0557 }
0558
0559
0560
0561
0562
0563
0564 void _Message_queue_MP_Send_object_was_deleted (
0565 Thread_Control *the_proxy,
0566 Objects_Id mp_id
0567 )
0568 {
0569 the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
0570
0571 _Message_queue_MP_Send_response_packet(
0572 MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
0573 mp_id,
0574 the_proxy
0575 );
0576 }
0577
0578
0579
0580
0581
0582
0583 void _Message_queue_MP_Send_extract_proxy (
0584 Thread_Control *the_thread,
0585 Objects_Id id
0586 )
0587 {
0588 _Message_queue_MP_Send_process_packet(
0589 MESSAGE_QUEUE_MP_EXTRACT_PROXY,
0590 id,
0591 (rtems_name) 0,
0592 the_thread->Object.id
0593 );
0594 }
0595
0596 void _Message_queue_Core_message_queue_mp_support(
0597 Thread_Control *the_thread,
0598 Objects_Id id
0599 )
0600 {
0601 the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
0602
0603 _Message_queue_MP_Send_response_packet(
0604 MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
0605 id,
0606 the_thread
0607 );
0608 }
0609
0610 static void _Message_queue_MP_Initialize( void )
0611 {
0612 _MPCI_Register_packet_processor(
0613 MP_PACKET_MESSAGE_QUEUE,
0614 _Message_queue_MP_Process_packet
0615 );
0616 }
0617
0618 RTEMS_SYSINIT_ITEM(
0619 _Message_queue_MP_Initialize,
0620 RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE_MP,
0621 RTEMS_SYSINIT_ORDER_MIDDLE
0622 );