[3652ad35] | 1 | /* |
---|
| 2 | * CORE Message Queue Handler |
---|
| 3 | * |
---|
| 4 | * DESCRIPTION: |
---|
| 5 | * |
---|
| 6 | * This package is the implementation of the CORE Message Queue Handler. |
---|
| 7 | * This core object provides task synchronization and communication functions |
---|
| 8 | * via messages passed to queue objects. |
---|
| 9 | * |
---|
[08311cc3] | 10 | * COPYRIGHT (c) 1989-1999. |
---|
[3652ad35] | 11 | * On-Line Applications Research Corporation (OAR). |
---|
| 12 | * |
---|
[98e4ebf5] | 13 | * The license and distribution terms for this file may be |
---|
| 14 | * found in the file LICENSE in this distribution or at |
---|
[dd687d97] | 15 | * http://www.rtems.com/license/LICENSE. |
---|
[3652ad35] | 16 | * |
---|
| 17 | * $Id$ |
---|
| 18 | */ |
---|
| 19 | |
---|
[a8eed23] | 20 | #if HAVE_CONFIG_H |
---|
| 21 | #include "config.h" |
---|
| 22 | #endif |
---|
| 23 | |
---|
[3652ad35] | 24 | #include <rtems/system.h> |
---|
[5e9b32b] | 25 | #include <rtems/score/chain.h> |
---|
| 26 | #include <rtems/score/isr.h> |
---|
| 27 | #include <rtems/score/object.h> |
---|
| 28 | #include <rtems/score/coremsg.h> |
---|
| 29 | #include <rtems/score/states.h> |
---|
| 30 | #include <rtems/score/thread.h> |
---|
| 31 | #include <rtems/score/wkspace.h> |
---|
[3652ad35] | 32 | |
---|
| 33 | /*PAGE |
---|
| 34 | * |
---|
| 35 | * _CORE_message_queue_Initialize |
---|
| 36 | * |
---|
| 37 | * This routine initializes a newly created message queue based on the |
---|
| 38 | * specified data. |
---|
| 39 | * |
---|
| 40 | * Input parameters: |
---|
| 41 | * the_message_queue - the message queue to initialize |
---|
| 42 | * the_class - the API specific object class |
---|
| 43 | * the_message_queue_attributes - the message queue's attributes |
---|
| 44 | * maximum_pending_messages - maximum message and reserved buffer count |
---|
| 45 | * maximum_message_size - maximum size of each message |
---|
| 46 | * |
---|
| 47 | * Output parameters: |
---|
[aae7f1a1] | 48 | * true - if the message queue is initialized |
---|
| 49 | * false - if the message queue is NOT initialized |
---|
[3652ad35] | 50 | */ |
---|
| 51 | |
---|
[484a769] | 52 | bool _CORE_message_queue_Initialize( |
---|
[3652ad35] | 53 | CORE_message_queue_Control *the_message_queue, |
---|
| 54 | CORE_message_queue_Attributes *the_message_queue_attributes, |
---|
[c1a886be] | 55 | uint32_t maximum_pending_messages, |
---|
[f773c012] | 56 | size_t maximum_message_size |
---|
[3652ad35] | 57 | ) |
---|
| 58 | { |
---|
[f773c012] | 59 | size_t message_buffering_required; |
---|
| 60 | size_t allocated_message_size; |
---|
[3652ad35] | 61 | |
---|
| 62 | the_message_queue->maximum_pending_messages = maximum_pending_messages; |
---|
| 63 | the_message_queue->number_of_pending_messages = 0; |
---|
| 64 | the_message_queue->maximum_message_size = maximum_message_size; |
---|
[507d382] | 65 | #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) |
---|
| 66 | _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL ); |
---|
| 67 | #endif |
---|
[9b63fbf8] | 68 | |
---|
[3652ad35] | 69 | /* |
---|
[9b63fbf8] | 70 | * Round size up to multiple of a pointer for chain init and |
---|
| 71 | * check for overflow on adding overhead to each message. |
---|
[3652ad35] | 72 | */ |
---|
[9b63fbf8] | 73 | |
---|
[3652ad35] | 74 | allocated_message_size = maximum_message_size; |
---|
[9929e2d] | 75 | if (allocated_message_size & (sizeof(uint32_t) - 1)) { |
---|
| 76 | allocated_message_size += sizeof(uint32_t); |
---|
| 77 | allocated_message_size &= ~(sizeof(uint32_t) - 1); |
---|
[3652ad35] | 78 | } |
---|
[9b63fbf8] | 79 | |
---|
| 80 | if (allocated_message_size < maximum_message_size) |
---|
[484a769] | 81 | return false; |
---|
[05279b84] | 82 | |
---|
[9b63fbf8] | 83 | /* |
---|
| 84 | * Calculate how much total memory is required for message buffering and |
---|
| 85 | * check for overflow on the multiplication. |
---|
| 86 | */ |
---|
[f773c012] | 87 | message_buffering_required = (size_t) maximum_pending_messages * |
---|
[3652ad35] | 88 | (allocated_message_size + sizeof(CORE_message_queue_Buffer_control)); |
---|
[9b63fbf8] | 89 | |
---|
| 90 | if (message_buffering_required < allocated_message_size) |
---|
[484a769] | 91 | return false; |
---|
[05279b84] | 92 | |
---|
[9b63fbf8] | 93 | /* |
---|
| 94 | * Attempt to allocate the message memory |
---|
| 95 | */ |
---|
| 96 | the_message_queue->message_buffers = (CORE_message_queue_Buffer *) |
---|
[3652ad35] | 97 | _Workspace_Allocate( message_buffering_required ); |
---|
[9b63fbf8] | 98 | |
---|
[3652ad35] | 99 | if (the_message_queue->message_buffers == 0) |
---|
[484a769] | 100 | return false; |
---|
[9b63fbf8] | 101 | |
---|
| 102 | /* |
---|
| 103 | * Initialize the pool of inactive messages, pending messages, |
---|
| 104 | * and set of waiting threads. |
---|
| 105 | */ |
---|
[3652ad35] | 106 | _Chain_Initialize ( |
---|
| 107 | &the_message_queue->Inactive_messages, |
---|
| 108 | the_message_queue->message_buffers, |
---|
[f773c012] | 109 | (size_t) maximum_pending_messages, |
---|
[3652ad35] | 110 | allocated_message_size + sizeof( CORE_message_queue_Buffer_control ) |
---|
| 111 | ); |
---|
[9b63fbf8] | 112 | |
---|
[3652ad35] | 113 | _Chain_Initialize_empty( &the_message_queue->Pending_messages ); |
---|
[9b63fbf8] | 114 | |
---|
[3652ad35] | 115 | _Thread_queue_Initialize( |
---|
| 116 | &the_message_queue->Wait_queue, |
---|
| 117 | _CORE_message_queue_Is_priority( the_message_queue_attributes ) ? |
---|
| 118 | THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, |
---|
| 119 | STATES_WAITING_FOR_MESSAGE, |
---|
| 120 | CORE_MESSAGE_QUEUE_STATUS_TIMEOUT |
---|
| 121 | ); |
---|
| 122 | |
---|
[484a769] | 123 | return true; |
---|
[3652ad35] | 124 | } |
---|