![]() |
|
|||
File indexing completed on 2025-05-11 08:24:12
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreMessageQueue 0007 * 0008 * @brief This header file provides interfaces of the 0009 * @ref RTEMSScoreMessageQueue which are used by the implementation and the 0010 * @ref RTEMSImplApplConfig. 0011 */ 0012 0013 /* 0014 * COPYRIGHT (c) 1989-2009. 0015 * On-Line Applications Research Corporation (OAR). 0016 * 0017 * Redistribution and use in source and binary forms, with or without 0018 * modification, are permitted provided that the following conditions 0019 * are met: 0020 * 1. Redistributions of source code must retain the above copyright 0021 * notice, this list of conditions and the following disclaimer. 0022 * 2. Redistributions in binary form must reproduce the above copyright 0023 * notice, this list of conditions and the following disclaimer in the 0024 * documentation and/or other materials provided with the distribution. 0025 * 0026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0036 * POSSIBILITY OF SUCH DAMAGE. 0037 */ 0038 0039 #ifndef _RTEMS_SCORE_COREMSGIMPL_H 0040 #define _RTEMS_SCORE_COREMSGIMPL_H 0041 0042 #include <rtems/score/coremsg.h> 0043 #include <rtems/score/status.h> 0044 #include <rtems/score/chainimpl.h> 0045 #include <rtems/score/threaddispatch.h> 0046 #include <rtems/score/threadqimpl.h> 0047 0048 #include <limits.h> 0049 #include <string.h> 0050 0051 #ifdef __cplusplus 0052 extern "C" { 0053 #endif 0054 0055 /** 0056 * @addtogroup RTEMSScoreMessageQueue 0057 * 0058 * @{ 0059 */ 0060 0061 /** 0062 * @brief Used when appending messages onto a message queue. 0063 * 0064 * This is the priority constant used when appending messages onto 0065 * a message queue. 0066 */ 0067 #define CORE_MESSAGE_QUEUE_SEND_REQUEST INT_MAX 0068 0069 /** 0070 * @brief Used when prepending messages onto a message queue. 0071 * 0072 * This is the priority constant used when prepending messages onto 0073 * a message queue. 0074 */ 0075 #define CORE_MESSAGE_QUEUE_URGENT_REQUEST INT_MIN 0076 0077 /** 0078 * @brief The modes in which a message may be submitted to a message queue. 0079 * 0080 * The following type details the modes in which a message 0081 * may be submitted to a message queue. The message may be posted 0082 * in a send or urgent fashion. 0083 * 0084 * @note All other values are message priorities. Numerically smaller 0085 * priorities indicate higher priority messages. 0086 */ 0087 typedef int CORE_message_queue_Submit_types; 0088 0089 /** 0090 * @brief This handler shall allocate the message buffer storage area for a 0091 * message queue. 0092 * 0093 * The handler shall set the CORE_message_queue_Control::free_message_buffers 0094 * member. 0095 * 0096 * @param[out] the_message_queue is the message queue control. 0097 * 0098 * @param size is the message buffer storage area size to allocate. 0099 * 0100 * @param arg is the handler argument. 0101 * 0102 * @retval NULL The allocation failed. 0103 * 0104 * @return Otherwise the pointer to the allocated message buffer storage area 0105 * begin shall be returned. 0106 */ 0107 typedef void *( *CORE_message_queue_Allocate_buffers )( 0108 CORE_message_queue_Control *the_message_queue, 0109 size_t size, 0110 const void *arg 0111 ); 0112 0113 /** 0114 * @brief This handler allocates the message buffer storage area for a message 0115 * queue from the RTEMS Workspace. 0116 * 0117 * The handler sets the CORE_message_queue_Control::free_message_buffers 0118 * to _Workspace_Free(). 0119 * 0120 * @param[out] the_message_queue is the message queue control. 0121 * 0122 * @param size is the message buffer storage area size to allocate. 0123 * 0124 * @param arg is the unused handler argument. 0125 * 0126 * @retval NULL The allocation failed. 0127 * 0128 * @return Otherwise the pointer to the allocated message buffer storage area 0129 * begin is returned. 0130 */ 0131 void *_CORE_message_queue_Workspace_allocate( 0132 CORE_message_queue_Control *the_message_queue, 0133 size_t size, 0134 const void *arg 0135 ); 0136 0137 /** 0138 * @brief Initializes a message queue. 0139 * 0140 * @param[out] the_message_queue is the message queue to initialize. 0141 * 0142 * @param discipline is the blocking discipline for the message queue. 0143 * 0144 * @param maximum_pending_messages is the maximum number of messages that will 0145 * be allowed to be pending at any given time. 0146 * 0147 * @param maximum_message_size is the size of the largest message that may be 0148 * sent to this message queue instance. 0149 * 0150 * @param allocate_buffers is the message buffer storage area allocation 0151 * handler. 0152 * 0153 * @param arg is the message buffer storage area allocation handler argument. 0154 * 0155 * @retval STATUS_SUCCESSFUL The message queue was initialized. 0156 * 0157 * @retval STATUS_MESSAGE_QUEUE_INVALID_SIZE Calculations with the maximum 0158 * pending messages or maximum message size produced an integer overflow. 0159 * 0160 * @retval STATUS_MESSAGE_QUEUE_NO_MEMORY The message buffer storage area 0161 * allocation failed. 0162 */ 0163 Status_Control _CORE_message_queue_Initialize( 0164 CORE_message_queue_Control *the_message_queue, 0165 CORE_message_queue_Disciplines discipline, 0166 uint32_t maximum_pending_messages, 0167 size_t maximum_message_size, 0168 CORE_message_queue_Allocate_buffers allocate_buffers, 0169 const void *arg 0170 ); 0171 0172 /** 0173 * @brief Closes a message queue. 0174 * 0175 * This package is the implementation of the CORE Message Queue Handler. 0176 * This core object provides task synchronization and communication functions 0177 * via messages passed to queue objects. 0178 * 0179 * This function closes a message by returning all allocated space and 0180 * flushing @a the_message_queue's task wait queue. 0181 * 0182 * @param[in, out] the_message_queue The message queue to close. 0183 * @param[in, out] queue_context The thread queue context used for 0184 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0185 */ 0186 void _CORE_message_queue_Close( 0187 CORE_message_queue_Control *the_message_queue, 0188 Thread_queue_Context *queue_context 0189 ); 0190 0191 /** 0192 * @brief Flushes pending messages. 0193 * 0194 * This package is the implementation of the CORE Message Queue Handler. 0195 * This core object provides task synchronization and communication functions 0196 * via messages passed to queue objects. 0197 * 0198 * This function flushes @a the_message_queue's pending message queue. The 0199 * number of messages flushed from the queue is returned. 0200 * 0201 * @param[in, out] the_message_queue The message queue to flush. 0202 * @param queue_context The thread queue context with interrupts disabled. 0203 * 0204 * @return This method returns the number of message pending messages flushed. 0205 */ 0206 uint32_t _CORE_message_queue_Flush( 0207 CORE_message_queue_Control *the_message_queue, 0208 Thread_queue_Context *queue_context 0209 ); 0210 0211 #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) 0212 /** 0213 * @brief Flushes waiting threads. 0214 * 0215 * This function flushes the threads which are blocked on 0216 * @a the_message_queue's pending message queue. They are 0217 * unblocked whether blocked sending or receiving. It returns 0218 * the number of messages flushed from the queue. 0219 * 0220 * @param[in, out] the_message_queue The message queue to flush. 0221 * 0222 * @return This method returns the number of messages flushed from the queue. 0223 */ 0224 void _CORE_message_queue_Flush_waiting_threads( 0225 CORE_message_queue_Control *the_message_queue 0226 ); 0227 #endif 0228 0229 /** 0230 * @brief Broadcasts a message to the message queue. 0231 * 0232 * This package is the implementation of the CORE Message Queue Handler. 0233 * This core object provides task synchronization and communication functions 0234 * via messages passed to queue objects. 0235 * 0236 * This function sends a message for every thread waiting on the queue and 0237 * returns the number of threads made ready by the message. 0238 * 0239 * @param[in, out] the_message_queue The message queue to operate upon. 0240 * @param buffer The starting address of the message to broadcast. 0241 * @param size The size of the message being broadcast. 0242 * @param[out] count The variable that will contain the 0243 * number of tasks that are sent this message. 0244 * @param queue_context The thread queue context used for 0245 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0246 * 0247 * @retval STATUS_SUCCESSFUL The message was successfully broadcast. 0248 * @retval STATUS_MESSAGE_INVALID_SIZE The message size was too big. 0249 */ 0250 Status_Control _CORE_message_queue_Broadcast( 0251 CORE_message_queue_Control *the_message_queue, 0252 const void *buffer, 0253 size_t size, 0254 uint32_t *count, 0255 Thread_queue_Context *queue_context 0256 ); 0257 0258 /** 0259 * @brief Submits a message to the message queue. 0260 * 0261 * This routine implements the send and urgent message functions. It 0262 * processes a message that is to be submitted to the designated 0263 * message queue. The message will either be processed as a 0264 * send message which it will be inserted at the rear of the queue 0265 * or it will be processed as an urgent message which will be inserted 0266 * at the front of the queue. 0267 * 0268 * @param[in, out] the_message_queue The message queue to operate upon. 0269 * @param executing The executing thread. 0270 * @param buffer The starting address of the message to send. 0271 * @param size The size of the message being send. 0272 * @param submit_type Determines whether the message is prepended, 0273 * appended, or enqueued in priority order. 0274 * @param wait Indicates whether the calling thread is willing to block 0275 * if the message queue is full. 0276 * @param queue_context The thread queue context used for 0277 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0278 * 0279 * @retval STATUS_SUCCESSFUL The message was successfully submitted to the message queue. 0280 * @retval STATUS_MESSAGE_INVALID_SIZE The message size was too big. 0281 * @retval STATUS_TOO_MANY No message buffers were available. 0282 * @retval STATUS_MESSAGE_QUEUE_WAIT_IN_ISR The caller is in an ISR, do not block! 0283 * @retval STATUS_TIMEOUT A timeout occurred. 0284 */ 0285 Status_Control _CORE_message_queue_Submit( 0286 CORE_message_queue_Control *the_message_queue, 0287 Thread_Control *executing, 0288 const void *buffer, 0289 size_t size, 0290 CORE_message_queue_Submit_types submit_type, 0291 bool wait, 0292 Thread_queue_Context *queue_context 0293 ); 0294 0295 /** 0296 * @brief Seizes a message from the message queue. 0297 * 0298 * This package is the implementation of the CORE Message Queue Handler. 0299 * This core object provides task synchronization and communication functions 0300 * via messages passed to queue objects. 0301 * 0302 * This kernel routine dequeues a message, copies the message buffer to 0303 * a given destination buffer, and frees the message buffer to the 0304 * inactive message pool. The thread will be blocked if wait is true, 0305 * otherwise an error will be given to the thread if no messages are available. 0306 * 0307 * @param[in, out] the_message_queue The message queue to seize a message from. 0308 * @param executing The executing thread. 0309 * @param[out] buffer The starting address of the message buffer to 0310 * to be filled in with a message. 0311 * @param[out] size_p The size of the @a buffer, 0312 * indicates the maximum size message that the caller can receive. 0313 * @param wait Indicates whether the calling thread is willing to block 0314 * if the message queue is empty. 0315 * @param queue_context The thread queue context used for 0316 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0317 * 0318 * @retval STATUS_SUCCESSFUL The message was successfully seized from the message queue. 0319 * @retval STATUS_UNSATISFIED Wait was set to false and there is currently no pending message. 0320 * @retval STATUS_TIMEOUT A timeout occurred. 0321 * 0322 * @note Returns message priority via return area in TCB. 0323 * 0324 * - INTERRUPT LATENCY: 0325 * + available 0326 * + wait 0327 */ 0328 Status_Control _CORE_message_queue_Seize( 0329 CORE_message_queue_Control *the_message_queue, 0330 Thread_Control *executing, 0331 void *buffer, 0332 size_t *size_p, 0333 bool wait, 0334 Thread_queue_Context *queue_context 0335 ); 0336 0337 /** 0338 * @brief Inserts a message into the message queue. 0339 * 0340 * Copies the specified content into the message storage space and then 0341 * inserts the message into the message queue according to the submit type. 0342 * 0343 * @param[in, out] the_message_queue The message queue to insert a message in. 0344 * @param[in, out] the_message The message to insert in the message queue. 0345 * @param content_source The message content source. 0346 * @param content_size The message content size in bytes. 0347 * @param submit_type Determines whether the message is prepended, 0348 * appended, or enqueued in priority order. 0349 */ 0350 void _CORE_message_queue_Insert_message( 0351 CORE_message_queue_Control *the_message_queue, 0352 CORE_message_queue_Buffer *the_message, 0353 const void *content_source, 0354 size_t content_size, 0355 CORE_message_queue_Submit_types submit_type 0356 ); 0357 0358 /** 0359 * @brief Sends a message to the message queue. 0360 * 0361 * @param[in, out] the_message_queue The message queue to send a message to. 0362 * @param buffer The starting address of the message to send. 0363 * @param sizeis The size of the message being send. 0364 * @param wait Indicates whether the calling thread is willing to block 0365 * if the message queue is full. 0366 * @param queue_context The thread queue context used for 0367 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0368 * 0369 * @retval STATUS_SUCCESSFUL The message was successfully submitted to the message queue. 0370 * @retval STATUS_MESSAGE_INVALID_SIZE The message size was too big. 0371 * @retval STATUS_TOO_MANY No message buffers were available. 0372 * @retval STATUS_MESSAGE_QUEUE_WAIT_IN_ISR The caller is in an ISR, do not block! 0373 * @retval STATUS_TIMEOUT A timeout occurred. 0374 */ 0375 static inline Status_Control _CORE_message_queue_Send( 0376 CORE_message_queue_Control *the_message_queue, 0377 const void *buffer, 0378 size_t size, 0379 bool wait, 0380 Thread_queue_Context *queue_context 0381 ) 0382 { 0383 return _CORE_message_queue_Submit( 0384 the_message_queue, 0385 _Thread_Executing, 0386 buffer, 0387 size, 0388 CORE_MESSAGE_QUEUE_SEND_REQUEST, 0389 wait, 0390 queue_context 0391 ); 0392 } 0393 0394 /** 0395 * @brief Sends an urgent message to the message queue. 0396 * 0397 * @param[in, out] the_message_queue The message queue to send an urgent message to. 0398 * @param buffer The starting address of the message to send. 0399 * @param sizeis The size of the message being send. 0400 * @param wait Indicates whether the calling thread is willing to block 0401 * if the message queue is full. 0402 * @param queue_context The thread queue context used for 0403 * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical(). 0404 * 0405 * @retval STATUS_SUCCESSFUL The message was successfully submitted to the message queue. 0406 * @retval STATUS_MESSAGE_INVALID_SIZE The message size was too big. 0407 * @retval STATUS_TOO_MANY No message buffers were available. 0408 * @retval STATUS_MESSAGE_QUEUE_WAIT_IN_ISR The caller is in an ISR, do not block! 0409 * @retval STATUS_TIMEOUT A timeout occurred. 0410 */ 0411 static inline Status_Control _CORE_message_queue_Urgent( 0412 CORE_message_queue_Control *the_message_queue, 0413 const void *buffer, 0414 size_t size, 0415 bool wait, 0416 Thread_queue_Context *queue_context 0417 ) 0418 { 0419 return _CORE_message_queue_Submit( 0420 the_message_queue, 0421 _Thread_Executing, 0422 buffer, 0423 size, 0424 CORE_MESSAGE_QUEUE_URGENT_REQUEST, 0425 wait, 0426 queue_context 0427 ); 0428 } 0429 0430 /** 0431 * @brief Acquires the message queue. 0432 * 0433 * @param[in, out] the_message_queue The message queue to acquire. 0434 * @param queue_context The thread queue context. 0435 */ 0436 static inline void _CORE_message_queue_Acquire( 0437 CORE_message_queue_Control *the_message_queue, 0438 Thread_queue_Context *queue_context 0439 ) 0440 { 0441 _Thread_queue_Acquire( &the_message_queue->Wait_queue, queue_context ); 0442 } 0443 0444 /** 0445 * @brief Acquires the message queue critical. 0446 * 0447 * @param[in, out] the_message_queue The message queue to acquire critical. 0448 * @param queue_context The thread queue context. 0449 */ 0450 static inline void _CORE_message_queue_Acquire_critical( 0451 CORE_message_queue_Control *the_message_queue, 0452 Thread_queue_Context *queue_context 0453 ) 0454 { 0455 _Thread_queue_Acquire_critical( &the_message_queue->Wait_queue, queue_context ); 0456 } 0457 0458 /** 0459 * @brief Releases the message queue. 0460 * 0461 * @param[in, out] the_message_queue The message queue to release. 0462 * @param queue_context The thread queue context. 0463 */ 0464 static inline void _CORE_message_queue_Release( 0465 CORE_message_queue_Control *the_message_queue, 0466 Thread_queue_Context *queue_context 0467 ) 0468 { 0469 _Thread_queue_Release( &the_message_queue->Wait_queue, queue_context ); 0470 } 0471 0472 /** 0473 * @brief Copies the source message buffer to the destination message buffer. 0474 * 0475 * This routine copies the contents of the source message buffer 0476 * to the destination message buffer. 0477 * 0478 * @param source The source message buffer to be copied. 0479 * @param[out] destination The destination messag buffer to copy the source to. 0480 * @param size The size of the source buffer. 0481 */ 0482 static inline void _CORE_message_queue_Copy_buffer ( 0483 const void *source, 0484 void *destination, 0485 size_t size 0486 ) 0487 { 0488 memcpy(destination, source, size); 0489 } 0490 0491 /** 0492 * @brief Allocates a message buffer from the inactive message buffer chain. 0493 * 0494 * This function allocates a message buffer from the inactive 0495 * message buffer chain. 0496 * 0497 * @param the_message_queue The message queue to operate upon. 0498 * 0499 * @retval pointer The allocated message buffer. 0500 * @retval NULL The inactive message buffer chain is empty. 0501 */ 0502 static inline CORE_message_queue_Buffer * 0503 _CORE_message_queue_Allocate_message_buffer ( 0504 CORE_message_queue_Control *the_message_queue 0505 ) 0506 { 0507 return (CORE_message_queue_Buffer *) 0508 _Chain_Get_unprotected( &the_message_queue->Inactive_messages ); 0509 } 0510 0511 /** 0512 * @brief Frees a message buffer to inactive message buffer chain. 0513 * 0514 * This routine frees a message buffer to the inactive 0515 * message buffer chain. 0516 * 0517 * @param[in, out] the_message_queue The message queue to free the message buffer to. 0518 * @param[out] the_message The message to be freed. 0519 */ 0520 static inline void _CORE_message_queue_Free_message_buffer ( 0521 CORE_message_queue_Control *the_message_queue, 0522 CORE_message_queue_Buffer *the_message 0523 ) 0524 { 0525 _Chain_Append_unprotected( &the_message_queue->Inactive_messages, &the_message->Node ); 0526 } 0527 0528 /** 0529 * @brief Gets message priority. 0530 * 0531 * This function returns the priority of @a the_message. 0532 * 0533 * @param the_message The message to obtain the priority from. 0534 * 0535 * @retval priority The priority of this message. 0536 * @retval 0 Message priority is disabled. 0537 * 0538 * @note It encapsulates the optional behavior that message priority is 0539 * disabled if no API requires it. 0540 */ 0541 static inline int _CORE_message_queue_Get_message_priority ( 0542 const CORE_message_queue_Buffer *the_message 0543 ) 0544 { 0545 #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY) 0546 return the_message->priority; 0547 #else 0548 return 0; 0549 #endif 0550 } 0551 0552 /** 0553 * @brief Gets first message of message queue and removes it. 0554 * 0555 * This function removes the first message from the_message_queue 0556 * and returns a pointer to it. 0557 * 0558 * @param[in, out] the_message_queue The message queue to get the first message from. 0559 * 0560 * @retval pointer The first message if the message queue is not empty. 0561 * @retval NULL The message queue is empty. 0562 */ 0563 static inline 0564 CORE_message_queue_Buffer *_CORE_message_queue_Get_pending_message ( 0565 CORE_message_queue_Control *the_message_queue 0566 ) 0567 { 0568 return (CORE_message_queue_Buffer *) 0569 _Chain_Get_unprotected( &the_message_queue->Pending_messages ); 0570 } 0571 0572 #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) 0573 /** 0574 * @brief Checks if notification is enabled. 0575 * 0576 * This function returns true if notification is enabled on this message 0577 * queue and false otherwise. 0578 * 0579 * @param the_message_queue The message queue to check if the notification is enabled. 0580 * 0581 * @retval true Notification is enabled on this message queue. 0582 * @retval false Notification is not enabled on this message queue. 0583 */ 0584 static inline bool _CORE_message_queue_Is_notify_enabled ( 0585 CORE_message_queue_Control *the_message_queue 0586 ) 0587 { 0588 return (the_message_queue->notify_handler != NULL); 0589 } 0590 #endif 0591 0592 /** 0593 * @brief Initializes notification information. 0594 * 0595 * This routine initializes the notification information for 0596 * @a the_message_queue. 0597 * 0598 * @param[out] the_message_queue The message queue to initialize the notification information. 0599 * @param[out] the_handler The notification information for the message queue. 0600 */ 0601 #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) 0602 static inline void _CORE_message_queue_Set_notify ( 0603 CORE_message_queue_Control *the_message_queue, 0604 CORE_message_queue_Notify_Handler the_handler 0605 ) 0606 { 0607 the_message_queue->notify_handler = the_handler; 0608 } 0609 #else 0610 /* turn it into nothing if not enabled */ 0611 #define _CORE_message_queue_Set_notify( the_message_queue, the_handler ) \ 0612 do { } while ( 0 ) 0613 #endif 0614 0615 /** 0616 * @brief Gets the first locked thread waiting to receive and dequeues it. 0617 * 0618 * This method dequeues the first locked thread waiting to receive a message, 0619 * dequeues it and returns the corresponding Thread_Control. 0620 * 0621 * @param[in, out] the_message_queue The message queue to operate upon. 0622 * @param buffer The buffer that is copied to the threads mutable_object. 0623 * @param size The size of the buffer. 0624 * @param submit_type Indicates whether the thread should be willing to block in the future. 0625 * @param queue_context The thread queue context. 0626 * 0627 * @retval thread The Thread_Control for the first locked thread, if there is a locked thread. 0628 * @retval NULL There are pending messages or no thread waiting to receive. 0629 */ 0630 static inline Thread_Control *_CORE_message_queue_Dequeue_receiver( 0631 CORE_message_queue_Control *the_message_queue, 0632 const void *buffer, 0633 size_t size, 0634 CORE_message_queue_Submit_types submit_type, 0635 Thread_queue_Context *queue_context 0636 ) 0637 { 0638 Thread_queue_Heads *heads; 0639 Thread_Control *the_thread; 0640 0641 /* 0642 * If there are pending messages, then there can't be threads 0643 * waiting for us to send them a message. 0644 * 0645 * NOTE: This check is critical because threads can block on 0646 * send and receive and this ensures that we are broadcasting 0647 * the message to threads waiting to receive -- not to send. 0648 */ 0649 if ( the_message_queue->number_of_pending_messages != 0 ) { 0650 return NULL; 0651 } 0652 0653 /* 0654 * There must be no pending messages if there is a thread waiting to 0655 * receive a message. 0656 */ 0657 heads = the_message_queue->Wait_queue.Queue.heads; 0658 if ( heads == NULL ) { 0659 return NULL; 0660 } 0661 0662 the_thread = ( *the_message_queue->operations->surrender )( 0663 &the_message_queue->Wait_queue.Queue, 0664 heads, 0665 NULL, 0666 queue_context 0667 ); 0668 0669 *(size_t *) the_thread->Wait.return_argument = size; 0670 the_thread->Wait.count = (uint32_t) submit_type; 0671 0672 _CORE_message_queue_Copy_buffer( 0673 buffer, 0674 the_thread->Wait.return_argument_second.mutable_object, 0675 size 0676 ); 0677 0678 _Thread_queue_Resume( 0679 &the_message_queue->Wait_queue.Queue, 0680 the_thread, 0681 queue_context 0682 ); 0683 0684 return the_thread; 0685 } 0686 0687 /** @} */ 0688 0689 #ifdef __cplusplus 0690 } 0691 #endif 0692 0693 #endif 0694 /* end of include file */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |