source: rtems/cpukit/score/src/coremsg.c @ 6b5f22dc

Last change on this file since 6b5f22dc was 4a4f41e, checked in by Sebastian Huber <sebastian.huber@…>, on 09/23/20 at 14:47:58

rtems: Add rtems_message_queue_construct()

In contrast to message queues created by rtems_message_queue_create(), the
message queues constructed by this directive use a user-provided message buffer
storage area.

Add RTEMS_MESSAGE_QUEUE_BUFFER() to define a message buffer type for message
buffer storage areas.

Update #4007.

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Initialize a Message Queue
5 *  @ingroup RTEMSScoreMessageQueue
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#ifdef HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/coremsgimpl.h>
22#include <rtems/score/assert.h>
23
24#define MESSAGE_SIZE_LIMIT \
25  ( SIZE_MAX - sizeof( uintptr_t ) + 1 - sizeof( CORE_message_queue_Buffer ) )
26
27RTEMS_STATIC_ASSERT(
28  offsetof( CORE_message_queue_Buffer, buffer )
29    == sizeof( CORE_message_queue_Buffer ),
30  CORE_MESSAGE_QUEUE_BUFFER_OFFSET
31);
32
33Status_Control _CORE_message_queue_Initialize(
34  CORE_message_queue_Control          *the_message_queue,
35  CORE_message_queue_Disciplines       discipline,
36  uint32_t                             maximum_pending_messages,
37  size_t                               maximum_message_size,
38  CORE_message_queue_Allocate_buffers  allocate_buffers,
39  const void                          *arg
40)
41{
42  size_t buffer_size;
43
44  /* Make sure the message size computation does not overflow */
45  if ( maximum_message_size > MESSAGE_SIZE_LIMIT ) {
46    return STATUS_MESSAGE_QUEUE_INVALID_SIZE;
47  }
48
49  buffer_size = RTEMS_ALIGN_UP( maximum_message_size, sizeof( uintptr_t ) );
50  _Assert( buffer_size >= maximum_message_size );
51
52  buffer_size += sizeof( CORE_message_queue_Buffer );
53  _Assert( buffer_size >= sizeof( CORE_message_queue_Buffer ) );
54
55  /* Make sure the memory allocation size computation does not overflow */
56  if ( maximum_pending_messages > SIZE_MAX / buffer_size ) {
57    return STATUS_MESSAGE_QUEUE_INVALID_NUMBER;
58  }
59
60  the_message_queue->message_buffers = ( *allocate_buffers )(
61    the_message_queue,
62    (size_t) maximum_pending_messages * buffer_size,
63    arg
64  );
65
66  if ( the_message_queue->message_buffers == NULL ) {
67    return STATUS_MESSAGE_QUEUE_NO_MEMORY;
68  }
69
70  the_message_queue->maximum_pending_messages   = maximum_pending_messages;
71  the_message_queue->number_of_pending_messages = 0;
72  the_message_queue->maximum_message_size       = maximum_message_size;
73
74  _CORE_message_queue_Set_notify( the_message_queue, NULL );
75  _Chain_Initialize_empty( &the_message_queue->Pending_messages );
76  _Thread_queue_Object_initialize( &the_message_queue->Wait_queue );
77
78  if ( discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY ) {
79    the_message_queue->operations = &_Thread_queue_Operations_priority;
80  } else {
81    the_message_queue->operations = &_Thread_queue_Operations_FIFO;
82  }
83
84  _Chain_Initialize (
85    &the_message_queue->Inactive_messages,
86    the_message_queue->message_buffers,
87    (size_t) maximum_pending_messages,
88    buffer_size
89  );
90
91  return STATUS_SUCCESSFUL;
92}
Note: See TracBrowser for help on using the repository browser.