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.
This commit is contained in:
Sebastian Huber
2020-09-23 16:47:58 +02:00
parent 24ea1cebeb
commit 4a4f41ed64
17 changed files with 588 additions and 167 deletions

View File

@@ -706,6 +706,7 @@ librtemscpu_a_SOURCES += rtems/src/intrcatch.c
librtemscpu_a_SOURCES += rtems/src/modes.c
librtemscpu_a_SOURCES += rtems/src/msg.c
librtemscpu_a_SOURCES += rtems/src/msgqbroadcast.c
librtemscpu_a_SOURCES += rtems/src/msgqconstruct.c
librtemscpu_a_SOURCES += rtems/src/msgqcreate.c
librtemscpu_a_SOURCES += rtems/src/msgqdelete.c
librtemscpu_a_SOURCES += rtems/src/msgqflush.c
@@ -839,6 +840,7 @@ librtemscpu_a_SOURCES += score/src/coremsgflushwait.c
librtemscpu_a_SOURCES += score/src/coremsginsert.c
librtemscpu_a_SOURCES += score/src/coremsgseize.c
librtemscpu_a_SOURCES += score/src/coremsgsubmit.c
librtemscpu_a_SOURCES += score/src/coremsgwkspace.c
librtemscpu_a_SOURCES += score/src/coremutexseize.c
librtemscpu_a_SOURCES += score/src/percpu.c
librtemscpu_a_SOURCES += score/src/percpuasm.c

View File

@@ -21,6 +21,7 @@
#include <rtems/rtems/options.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/types.h>
#include <rtems/score/coremsgbuffer.h>
#ifdef __cplusplus
extern "C" {
@@ -36,6 +37,136 @@ extern "C" {
*/
/**@{*/
/**
* @brief This structure defines the configuration of a message queue
* constructed by rtems_message_queue_construct().
*/
typedef struct {
/**
* @brief This member defines the name of the message queue.
*/
rtems_name name;
/**
* @brief This member defines the maximum number of pending messages supported
* by the message queue.
*/
uint32_t maximum_pending_messages;
/**
* @brief This member defines the maximum message size supported by the message
* queue.
*/
size_t maximum_message_size;
/**
* @brief This member shall point to the message buffer storage area begin.
*
* The message buffer storage area for the message queue shall be an array of
* the type defined by RTEMS_MESSAGE_QUEUE_BUFFER() with a maximum message size
* equal to the maximum message size of this configuration.
*/
void *storage_area;
/**
* @brief This member defines size of the message buffer storage area in bytes.
*/
size_t storage_size;
/**
* @brief This member defines the optional handler to free the message buffer
* storage area.
*
* It is called when the message queue is deleted. It is called from task
* context under protection of the object allocator lock. It is allowed to
* call free() in this handler. If handler is NULL, then no action will be
* performed.
*/
void ( *storage_free )( void * );
/**
* @brief This member defines the attributes of the message queue.
*/
rtems_attribute attributes;
} rtems_message_queue_config;
/**
* @brief Defines a structure which can be used as a message queue buffer for
* messages of the specified maximum size.
*
* Use this macro to define the message buffer storage area for
* rtems_message_queue_construct().
*
* @param _maximum_message_size is the maximum message size in bytes.
*/
#define RTEMS_MESSAGE_QUEUE_BUFFER( _maximum_message_size ) \
struct { \
CORE_message_queue_Buffer _buffer; \
char _message[ _maximum_message_size ]; \
}
/**
* @brief Constructs a message queue from the specified the message queue
* configuration.
*
* 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.
*
* This directive is intended for applications which do not want to use the
* RTEMS Workspace and instead statically allocate all operating system
* resources. An application based solely on static allocation can avoid any
* runtime memory allocators. This can simplify the application architecture
* as well as any analysis that may be required.
*
* The value for #CONFIGURE_MESSAGE_BUFFER_MEMORY should not include memory for
* message queues constructed by rtems_message_queue_construct().
*
* @param config is the message queue configuration.
*
* @param[out] id is the pointer to an object identifier variable. The
* identifier of the constructed message queue object will be stored in this
* variable, in case of a successful operation.
*
* @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
*
* @retval ::RTEMS_INVALID_ADDRESS The id parameter was NULL.
*
* @retval ::RTEMS_INVALID_NAME The message queue name in the configuration was
* invalid.
*
* @retval ::RTEMS_INVALID_NUMBER The maximum number of pending messages in the
* configuration was zero.
*
* @retval ::RTEMS_INVALID_SIZE The maximum message size in the configuration
* was zero.
*
* @retval ::RTEMS_TOO_MANY There was no inactive message queue object
* available to construct a message queue.
*
* @retval ::RTEMS_TOO_MANY In multiprocessing configurations, there was no
* inactive global object available to construct a global message queue.
*
* @retval ::RTEMS_INVALID_SIZE The maximum message size in the configuration
* was too big and resulted in integer overflows in calculations carried out
* to determine the size of the message buffer area.
*
* @retval ::RTEMS_INVALID_NUMBER The maximum number of pending messages in the
* configuration was too big and resulted in integer overflows in
* calculations carried out to determine the size of the message buffer area.
*
* @retval ::RTEMS_UNSATISFIED The message queue storage area begin pointer in
* the configuration was NULL.
*
* @retval ::RTEMS_UNSATISFIED The message queue storage area size in the
* configuration was not equal to the size calculated from the maximum number
* of pending messages and the maximum message size.
*/
rtems_status_code rtems_message_queue_construct(
const rtems_message_queue_config *config,
rtems_id *id
);
/**
* @brief RTEMS Create Message Queue
*

View File

@@ -101,6 +101,23 @@ RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void )
_Objects_Allocate( &_Message_queue_Information );
}
/**
* @brief Creates a message queue.
*
* @param config is the message queue configuration.
*
* @param[out] id contains the object identifier if the operation was
* successful.
*
* @param allocate_buffers is the message buffer storage area allocation
* handler.
*/
rtems_status_code _Message_queue_Create(
const rtems_message_queue_config *config,
rtems_id *id,
CORE_message_queue_Allocate_buffers allocate_buffers
);
/**@}*/
#ifdef __cplusplus

View File

@@ -124,6 +124,16 @@ struct CORE_message_queue_Control {
* as part of destroying it.
*/
CORE_message_queue_Buffer *message_buffers;
/**
* @brief This member contains the optional message buffer storage area free
* handler.
*
* It may be NULL. In this case no action is performed to free the message
* buffer storage area.
*/
void ( *free_message_buffers )( void * );
#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
/** This is the routine invoked when the message queue transitions
* from zero (0) messages pending to one (1) message pending.

View File

@@ -68,6 +68,54 @@ extern "C" {
*/
typedef int CORE_message_queue_Submit_types;
/**
* @brief This handler shall allocate the message buffer storage area for a
* message queue.
*
* The handler shall set the CORE_message_queue_Control::free_message_buffers
* member.
*
* @param[out] the_message_queue is the message queue control.
*
* @param size is the message buffer storage area size to allocate.
*
* @param arg is the handler argument.
*
* @retval NULL The allocation failed.
*
* @return Otherwise the pointer to the allocated message buffer storage area
* begin shall be returned.
*/
typedef void *( *CORE_message_queue_Allocate_buffers )(
CORE_message_queue_Control *the_message_queue,
size_t size,
const void *arg
);
/**
* @brief This handler allocates the message buffer storage area for a message
* queue from the RTEMS Workspace.
*
* The handler sets the CORE_message_queue_Control::free_message_buffers
* to _Workspace_Free().
*
* @param[out] the_message_queue is the message queue control.
*
* @param size is the message buffer storage area size to allocate.
*
* @param arg is the unused handler argument.
*
* @retval NULL The allocation failed.
*
* @return Otherwise the pointer to the allocated message buffer storage area
* begin is returned.
*/
void *_CORE_message_queue_Workspace_allocate(
CORE_message_queue_Control *the_message_queue,
size_t size,
const void *arg
);
/**
* @brief Initializes a message queue.
*
@@ -81,19 +129,26 @@ typedef int CORE_message_queue_Submit_types;
* @param maximum_message_size is the size of the largest message that may be
* sent to this message queue instance.
*
* @param allocate_buffers is the message buffer storage area allocation
* handler.
*
* @param arg is the message buffer storage area allocation handler argument.
*
* @retval STATUS_SUCCESSFUL The message queue was initialized.
*
* @retval STATUS_MESSAGE_QUEUE_INVALID_SIZE Calculations with the maximum
* pending messages or maximum message size produced an integer overflow.
*
* @retval STATUS_MESSAGE_QUEUE_NO_MEMORY There was not enough memory to
* allocate the message buffers.
* @retval STATUS_MESSAGE_QUEUE_NO_MEMORY The message buffer storage area
* allocation failed.
*/
Status_Control _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
CORE_message_queue_Disciplines discipline,
uint32_t maximum_pending_messages,
size_t maximum_message_size
CORE_message_queue_Control *the_message_queue,
CORE_message_queue_Disciplines discipline,
uint32_t maximum_pending_messages,
size_t maximum_message_size,
CORE_message_queue_Allocate_buffers allocate_buffers,
const void *arg
);
/**

View File

@@ -102,7 +102,9 @@ static mqd_t _POSIX_Message_queue_Create(
&the_mq->Message_queue,
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
attr->mq_maxmsg,
attr->mq_msgsize
attr->mq_msgsize,
_CORE_message_queue_Workspace_allocate,
NULL
);
if ( status != STATUS_SUCCESSFUL ) {

View File

@@ -0,0 +1,189 @@
/**
* @file
*
* @brief RTEMS Create Message Queue
* @ingroup ClassicMessageQueue
*/
/*
* COPYRIGHT (c) 1989-2014.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/rtems/messageimpl.h>
#include <rtems/rtems/attrimpl.h>
#include <rtems/rtems/support.h>
#include <rtems/score/coremsgimpl.h>
#include <rtems/sysinit.h>
static void *_Message_queue_Get_buffers(
CORE_message_queue_Control *the_message_queue,
size_t size,
const void *arg
)
{
const rtems_message_queue_config *config;
config = arg;
if ( config->storage_size != size ) {
return NULL;
}
the_message_queue->free_message_buffers = config->storage_free;
return config->storage_area;
}
rtems_status_code rtems_message_queue_construct(
const rtems_message_queue_config *config,
rtems_id *id
)
{
return _Message_queue_Create( config, id, _Message_queue_Get_buffers );
}
rtems_status_code _Message_queue_Create(
const rtems_message_queue_config *config,
rtems_id *id,
CORE_message_queue_Allocate_buffers allocate_buffers
)
{
Message_queue_Control *the_message_queue;
CORE_message_queue_Disciplines discipline;
Status_Control status;
#if defined(RTEMS_MULTIPROCESSING)
bool is_global;
#endif
if ( id == NULL ) {
return RTEMS_INVALID_ADDRESS;
}
if ( !rtems_is_name_valid( config->name ) ) {
return RTEMS_INVALID_NAME;
}
if ( config->maximum_pending_messages == 0 ) {
return RTEMS_INVALID_NUMBER;
}
if ( config->maximum_message_size == 0 ) {
return RTEMS_INVALID_SIZE;
}
#if defined(RTEMS_MULTIPROCESSING)
if ( _System_state_Is_multiprocessing ) {
is_global = _Attributes_Is_global( config->attributes );
} else {
is_global = false;
}
#if 1
/*
* I am not 100% sure this should be an error.
* It seems reasonable to create a que with a large max size,
* and then just send smaller msgs from remote (or all) nodes.
*/
if ( is_global ) {
size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
- MESSAGE_QUEUE_MP_PACKET_SIZE;
if ( config->maximum_message_size > max_packet_payload_size ) {
return RTEMS_INVALID_SIZE;
}
}
#endif
#endif
the_message_queue = _Message_queue_Allocate();
if ( !the_message_queue ) {
_Objects_Allocator_unlock();
return RTEMS_TOO_MANY;
}
#if defined(RTEMS_MULTIPROCESSING)
if (
is_global
&& !_Objects_MP_Allocate_and_open(
&_Message_queue_Information,
config->name,
the_message_queue->Object.id,
false
)
) {
_Message_queue_Free( the_message_queue );
_Objects_Allocator_unlock();
return RTEMS_TOO_MANY;
}
the_message_queue->is_global = is_global;
#endif
if ( _Attributes_Is_priority( config->attributes ) ) {
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
} else {
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
}
status = _CORE_message_queue_Initialize(
&the_message_queue->message_queue,
discipline,
config->maximum_pending_messages,
config->maximum_message_size,
allocate_buffers,
config
);
if ( status != STATUS_SUCCESSFUL ) {
#if defined(RTEMS_MULTIPROCESSING)
if ( is_global )
_Objects_MP_Close(
&_Message_queue_Information, the_message_queue->Object.id);
#endif
_Message_queue_Free( the_message_queue );
_Objects_Allocator_unlock();
return STATUS_GET_CLASSIC( status );
}
_Objects_Open(
&_Message_queue_Information,
&the_message_queue->Object,
(Objects_Name) config->name
);
*id = the_message_queue->Object.id;
#if defined(RTEMS_MULTIPROCESSING)
if ( is_global )
_Message_queue_MP_Send_process_packet(
MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
the_message_queue->Object.id,
config->name,
0
);
#endif
_Objects_Allocator_unlock();
return RTEMS_SUCCESSFUL;
}
static void _Message_queue_Manager_initialization( void )
{
_Objects_Initialize_information( &_Message_queue_Information);
}
RTEMS_SYSINIT_ITEM(
_Message_queue_Manager_initialization,
RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
RTEMS_SYSINIT_ORDER_MIDDLE
);

View File

@@ -1,17 +1,37 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
* @file
*
* @brief RTEMS Create Message Queue
* @ingroup ClassicMessageQueue
* @ingroup ClassicMessageQueueImpl
*
* @brief This source file contains the implementation of
* rtems_message_queue_create().
*/
/*
* COPYRIGHT (c) 1989-2014.
* On-Line Applications Research Corporation (OAR).
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
@@ -19,17 +39,9 @@
#endif
#include <rtems/rtems/messageimpl.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/attrimpl.h>
#include <rtems/rtems/options.h>
#include <rtems/rtems/support.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/chain.h>
#include <rtems/score/isr.h>
#include <rtems/score/coremsgimpl.h>
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
#include <rtems/sysinit.h>
#include <string.h>
rtems_status_code rtems_message_queue_create(
rtems_name name,
@@ -39,123 +51,17 @@ rtems_status_code rtems_message_queue_create(
rtems_id *id
)
{
Message_queue_Control *the_message_queue;
CORE_message_queue_Disciplines discipline;
Status_Control status;
#if defined(RTEMS_MULTIPROCESSING)
bool is_global;
#endif
rtems_message_queue_config config;
if ( !rtems_is_name_valid( name ) )
return RTEMS_INVALID_NAME;
memset( &config, 0, sizeof( config ) );
config.name = name;
config.maximum_pending_messages = count;
config.maximum_message_size = max_message_size;
config.attributes = attribute_set;
if ( !id )
return RTEMS_INVALID_ADDRESS;
#if defined(RTEMS_MULTIPROCESSING)
if ( _System_state_Is_multiprocessing ) {
is_global = _Attributes_Is_global( attribute_set );
} else {
is_global = false;
}
#endif
if ( count == 0 )
return RTEMS_INVALID_NUMBER;
if ( max_message_size == 0 )
return RTEMS_INVALID_SIZE;
#if defined(RTEMS_MULTIPROCESSING)
#if 1
/*
* I am not 100% sure this should be an error.
* It seems reasonable to create a que with a large max size,
* and then just send smaller msgs from remote (or all) nodes.
*/
if ( is_global ) {
size_t max_packet_payload_size = _MPCI_table->maximum_packet_size
- MESSAGE_QUEUE_MP_PACKET_SIZE;
if ( max_message_size > max_packet_payload_size ) {
return RTEMS_INVALID_SIZE;
}
}
#endif
#endif
the_message_queue = _Message_queue_Allocate();
if ( !the_message_queue ) {
_Objects_Allocator_unlock();
return RTEMS_TOO_MANY;
}
#if defined(RTEMS_MULTIPROCESSING)
if ( is_global &&
!( _Objects_MP_Allocate_and_open( &_Message_queue_Information,
name, the_message_queue->Object.id, false ) ) ) {
_Message_queue_Free( the_message_queue );
_Objects_Allocator_unlock();
return RTEMS_TOO_MANY;
}
the_message_queue->is_global = is_global;
#endif
if (_Attributes_Is_priority( attribute_set ) )
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
else
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
status = _CORE_message_queue_Initialize(
&the_message_queue->message_queue,
discipline,
count,
max_message_size
return _Message_queue_Create(
&config,
id,
_CORE_message_queue_Workspace_allocate
);
if ( status != STATUS_SUCCESSFUL ) {
#if defined(RTEMS_MULTIPROCESSING)
if ( is_global )
_Objects_MP_Close(
&_Message_queue_Information, the_message_queue->Object.id);
#endif
_Message_queue_Free( the_message_queue );
_Objects_Allocator_unlock();
return STATUS_GET_CLASSIC( status );
}
_Objects_Open(
&_Message_queue_Information,
&the_message_queue->Object,
(Objects_Name) name
);
*id = the_message_queue->Object.id;
#if defined(RTEMS_MULTIPROCESSING)
if ( is_global )
_Message_queue_MP_Send_process_packet(
MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
the_message_queue->Object.id,
name,
0
);
#endif
_Objects_Allocator_unlock();
return RTEMS_SUCCESSFUL;
}
static void _Message_queue_Manager_initialization( void )
{
_Objects_Initialize_information( &_Message_queue_Information);
}
RTEMS_SYSINIT_ITEM(
_Message_queue_Manager_initialization,
RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE,
RTEMS_SYSINIT_ORDER_MIDDLE
);

View File

@@ -20,7 +20,6 @@
#include <rtems/score/coremsgimpl.h>
#include <rtems/score/assert.h>
#include <rtems/score/wkspace.h>
#define MESSAGE_SIZE_LIMIT \
( SIZE_MAX - sizeof( uintptr_t ) + 1 - sizeof( CORE_message_queue_Buffer ) )
@@ -32,10 +31,12 @@ RTEMS_STATIC_ASSERT(
);
Status_Control _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
CORE_message_queue_Disciplines discipline,
uint32_t maximum_pending_messages,
size_t maximum_message_size
CORE_message_queue_Control *the_message_queue,
CORE_message_queue_Disciplines discipline,
uint32_t maximum_pending_messages,
size_t maximum_message_size,
CORE_message_queue_Allocate_buffers allocate_buffers,
const void *arg
)
{
size_t buffer_size;
@@ -56,8 +57,10 @@ Status_Control _CORE_message_queue_Initialize(
return STATUS_MESSAGE_QUEUE_INVALID_NUMBER;
}
the_message_queue->message_buffers = _Workspace_Allocate(
(size_t) maximum_pending_messages * buffer_size
the_message_queue->message_buffers = ( *allocate_buffers )(
the_message_queue,
(size_t) maximum_pending_messages * buffer_size,
arg
);
if ( the_message_queue->message_buffers == NULL ) {

View File

@@ -19,7 +19,6 @@
#endif
#include <rtems/score/coremsgimpl.h>
#include <rtems/score/wkspace.h>
static Thread_Control *_CORE_message_queue_Was_deleted(
Thread_Control *the_thread,
@@ -50,7 +49,11 @@ void _CORE_message_queue_Close(
queue_context
);
(void) _Workspace_Free( the_message_queue->message_buffers );
if ( the_message_queue->free_message_buffers != NULL ) {
( *the_message_queue->free_message_buffers )(
the_message_queue->message_buffers
);
}
_Thread_queue_Destroy( &the_message_queue->Wait_queue );
}

View File

@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSScoreMessageQueue
*
* @brief This source file contains the implementation of
* _CORE_message_queue_Workspace_allocate().
*/
/*
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/coremsgimpl.h>
#include <rtems/score/wkspace.h>
void *_CORE_message_queue_Workspace_allocate(
CORE_message_queue_Control *the_message_queue,
size_t size,
const void *arg
)
{
(void) arg;
the_message_queue->free_message_buffers = _Workspace_Free;
return _Workspace_Allocate( size );
}

View File

@@ -1198,6 +1198,7 @@ source:
- cpukit/rtems/src/modes.c
- cpukit/rtems/src/msg.c
- cpukit/rtems/src/msgqbroadcast.c
- cpukit/rtems/src/msgqconstruct.c
- cpukit/rtems/src/msgqcreate.c
- cpukit/rtems/src/msgqdelete.c
- cpukit/rtems/src/msgqflush.c
@@ -1376,6 +1377,7 @@ source:
- cpukit/score/src/coremsginsert.c
- cpukit/score/src/coremsgseize.c
- cpukit/score/src/coremsgsubmit.c
- cpukit/score/src/coremsgwkspace.c
- cpukit/score/src/coremutexseize.c
- cpukit/score/src/corerwlock.c
- cpukit/score/src/corerwlockobtainread.c

View File

@@ -26,6 +26,23 @@
#define CONFIGURE_INIT
#include "system.h"
#if CONFIGURE_MP_NODE_NUMBER == 1
#define MESSAGE_SIZE 1
static RTEMS_MESSAGE_QUEUE_BUFFER( MESSAGE_SIZE ) buffers[ 1 ];
static const rtems_message_queue_config config = {
.name = rtems_build_name( 'M', 'S', 'G', '2' ),
.maximum_pending_messages = RTEMS_ARRAY_SIZE( buffers ),
.maximum_message_size = MESSAGE_SIZE,
.storage_area = buffers,
.storage_size = sizeof( buffers ),
.attributes = RTEMS_GLOBAL
};
#endif
rtems_task Init(
rtems_task_argument argument
)
@@ -40,10 +57,17 @@ rtems_task Init(
Task_name[ 1 ] = rtems_build_name( '1', '1', '1', ' ' );
Task_name[ 2 ] = rtems_build_name( '2', '2', '2', ' ' );
Queue_name[ 1 ] = rtems_build_name( 'M', 'S', 'G', ' ' );
Queue_name[ 1 ] = rtems_build_name( 'M', 'S', 'G', '1' );
Queue_name[ 2 ] = rtems_build_name( 'M', 'S', 'G', '2' );
if ( rtems_object_get_local_node() == 1 ) {
puts( "Creating Message Queue (Global)" );
#if CONFIGURE_MP_NODE_NUMBER == 1
status = rtems_message_queue_construct( &config, &Queue_id[ 2 ] );
directive_failed( status, "rtems_message_queue_construct" );
#endif
status = rtems_message_queue_create(
Queue_name[ 1 ],
3,

View File

@@ -34,11 +34,14 @@ void Send_messages( void );
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1
#define CONFIGURE_MESSAGE_BUFFER_MEMORY \
CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 3, 16 )
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMER 1
#if CONFIGURE_MP_NODE_NUMBER == 1
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 2
#define CONFIGURE_MESSAGE_BUFFER_MEMORY \
CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 3, 16 )
#endif
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
@@ -49,8 +52,8 @@ void Send_messages( void );
TEST_EXTERN rtems_id Task_id[ 4 ]; /* array of task ids */
TEST_EXTERN rtems_name Task_name[ 4 ]; /* array of task names */
TEST_EXTERN rtems_id Queue_id[ 2 ]; /* array of message queue ids */
TEST_EXTERN rtems_name Queue_name[ 2 ]; /* array of message queue names */
TEST_EXTERN rtems_id Queue_id[ 3 ]; /* array of message queue ids */
TEST_EXTERN rtems_name Queue_name[ 3 ]; /* array of message queue names */
extern char buffer1[16];
extern char buffer2[16];

View File

@@ -49,7 +49,20 @@ rtems_task Test_task(
);
} while ( !rtems_is_status_successful( status ) );
status = rtems_message_queue_ident(
Queue_name[ 2 ],
RTEMS_SEARCH_ALL_NODES,
&Queue_id[ 2 ]
);
directive_failed( status, "rtems_message_queue_ident" );
if ( rtems_object_get_local_node() == 2 ) {
status = rtems_message_queue_delete( Queue_id[ 2 ] );
fatal_directive_status(
status,
RTEMS_ILLEGAL_ON_REMOTE_OBJECT,
"rtems_message_queue_delete"
);
status = rtems_message_queue_delete( Queue_id[ 1 ] );
fatal_directive_status(
status,
@@ -103,6 +116,9 @@ rtems_task Test_task(
puts( "Deleting Message queue" );
status = rtems_message_queue_delete( Queue_id[ 1 ] );
directive_failed( status, "rtems_message_queue_delete" );
status = rtems_message_queue_delete( Queue_id[ 2 ] );
directive_failed( status, "rtems_message_queue_delete" );
}
puts( "*** END OF TEST 9 ***" );

View File

@@ -28,6 +28,17 @@
const char rtems_test_name[] = "SP 13";
static RTEMS_MESSAGE_QUEUE_BUFFER( MESSAGE_SIZE ) Queue_3_buffers[ 100 ];
static const rtems_message_queue_config Queue_3_config = {
.name = rtems_build_name( 'Q', '3', ' ', ' ' ),
.maximum_pending_messages = RTEMS_ARRAY_SIZE( Queue_3_buffers ),
.maximum_message_size = MESSAGE_SIZE,
.storage_area = Queue_3_buffers,
.storage_size = sizeof( Queue_3_buffers ),
.attributes = RTEMS_GLOBAL
};
rtems_task Init(
rtems_task_argument argument
)
@@ -101,14 +112,8 @@ rtems_task Init(
);
directive_failed( status, "rtems_message_queue_create of Q2" );
status = rtems_message_queue_create(
Queue_name[ 3 ],
100,
MESSAGE_SIZE,
RTEMS_GLOBAL,
&Queue_id[ 3 ]
);
directive_failed( status, "rtems_message_queue_create of Q3" );
status = rtems_message_queue_construct( &Queue_3_config, &Queue_id[ 3 ] );
directive_failed( status, "rtems_message_queue_construct of Q3" );
rtems_task_exit();
}

View File

@@ -91,7 +91,7 @@ TEST_EXTERN rtems_name Queue_name[ 4 ]; /* array of queue names */
#define CONFIGURE_MESSAGE_BUFFER_MEMORY \
/* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, MESSAGE_SIZE ) + \
/* Q2 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 10, MESSAGE_SIZE ) + \
/* Q3 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, MESSAGE_SIZE ) + \
/* Q3 is statically allocated */ \
/* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 100, 20 ) + \
/* Q1 */ CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE( 2, 1030 )