Files
threadx/common_smp/src/tx_queue_create.c
T
Frédéric DesbiensandTilen Majerle cf577c7137 Made ThreadX object names const-qualifiable behind an option (#761)
Fixes #61

Object names are exposed as writable pointers throughout the kernel API, which
rejects string literals in C++ and lets a caller modify a name an object still
holds. Information services return those names through writable double
pointers.

Create services, control blocks, information services, the module manager and
trace registration now preserve const qualification, behind
TX_ENABLE_CONST_NAMES. The option defaults to off, so a build that says nothing
gets exactly the types it got before. It is opt-in rather than opt-out because
it changes the type of a public struct field: application code that copies a
name into a writable CHAR * stops compiling, which is a reasonable thing to ask
of a minor release and not of a patch one. Issue #780 tracks making it the
default in 6.6.

Two things the option reaches that its own call sites do not.
TX_CHAR_TO_UCHAR_POINTER_CONVERT has exactly two users, both of them reading an
object name in _tx_trace_object_register, and every form of that macro but the
MISRA one casts the qualifier away without saying so; the conversion is now
const in and const out, so nothing launders const to make the build pass. The
FreeRTOS adapter holds the name pcTaskGetName retrieves in a TX_NAME_CONST
pointer so that it tracks whichever declaration tx_thread_info_get has, and
keeps its writable return type through an explicit MISRA C:2012 Rule 11.8 cast,
because that signature is part of the FreeRTOS API.

Default build: all seven host configurations and all five SMP configurations
build with zero warnings and pass -- 113/113 on five host configurations,
100/100 on the two MISRA builds, 118/118 on SMP, 3/3 FreeRTOS. With
TX_ENABLE_CONST_NAMES set, the host default and both MISRA configurations, the
SMP trace configuration and the FreeRTOS adapter build with zero warnings and
pass.

Co-authored-by: Tilen Majerle <tilen@majerle.eu>
Assisted-by: Codex (gpt-6-astra) <noreply@openai.com>
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
2026-09-28 14:08:13 -04:00

167 lines
7.5 KiB
C

/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/* Portions of this file were generated with AI assistance. */
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Queue */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_queue.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_queue_create PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates a message queue. The message size and depth */
/* of the queue is specified by the caller. */
/* */
/* INPUT */
/* */
/* queue_ptr Pointer to queue control block */
/* name_ptr Pointer to queue name */
/* message_size Size of each queue message */
/* queue_start Starting address of the queue area*/
/* queue_size Number of bytes in the queue */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/**************************************************************************/
UINT _tx_queue_create(TX_QUEUE *queue_ptr, TX_NAME_CONST CHAR *name_ptr, UINT message_size,
VOID *queue_start, ULONG queue_size)
{
TX_INTERRUPT_SAVE_AREA
UINT capacity;
UINT used_words;
TX_QUEUE *next_queue;
TX_QUEUE *previous_queue;
/* Initialize queue control block to all zeros. */
TX_MEMSET(queue_ptr, 0, (sizeof(TX_QUEUE)));
/* Setup the basic queue fields. */
queue_ptr -> tx_queue_name = name_ptr;
/* Save the message size in the control block. */
queue_ptr -> tx_queue_message_size = message_size;
/* Determine how many messages will fit in the queue area and the number
of ULONGs used. */
capacity = (UINT) (queue_size / ((ULONG) (((ULONG) message_size) * (sizeof(ULONG)))));
used_words = capacity * message_size;
/* Save the starting address and calculate the ending address of
the queue. Note that the ending address is really one past the
end! */
queue_ptr -> tx_queue_start = TX_VOID_TO_ULONG_POINTER_CONVERT(queue_start);
queue_ptr -> tx_queue_end = TX_ULONG_POINTER_ADD(queue_ptr -> tx_queue_start, used_words);
/* Set the read and write pointers to the beginning of the queue
area. */
queue_ptr -> tx_queue_read = TX_VOID_TO_ULONG_POINTER_CONVERT(queue_start);
queue_ptr -> tx_queue_write = TX_VOID_TO_ULONG_POINTER_CONVERT(queue_start);
/* Setup the number of enqueued messages and the number of message
slots available in the queue. */
queue_ptr -> tx_queue_available_storage = (UINT) capacity;
queue_ptr -> tx_queue_capacity = (UINT) capacity;
/* Disable interrupts to put the queue on the created list. */
TX_DISABLE
/* Setup the queue ID to make it valid. */
queue_ptr -> tx_queue_id = TX_QUEUE_ID;
/* Place the queue on the list of created queues. First,
check for an empty list. */
if (_tx_queue_created_count == TX_EMPTY)
{
/* The created queue list is empty. Add queue to empty list. */
_tx_queue_created_ptr = queue_ptr;
queue_ptr -> tx_queue_created_next = queue_ptr;
queue_ptr -> tx_queue_created_previous = queue_ptr;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_queue = _tx_queue_created_ptr;
previous_queue = next_queue -> tx_queue_created_previous;
/* Place the new queue in the list. */
next_queue -> tx_queue_created_previous = queue_ptr;
previous_queue -> tx_queue_created_next = queue_ptr;
/* Setup this queues's created links. */
queue_ptr -> tx_queue_created_previous = previous_queue;
queue_ptr -> tx_queue_created_next = next_queue;
}
/* Increment the created queue count. */
_tx_queue_created_count++;
/* Optional queue create extended processing. */
TX_QUEUE_CREATE_EXTENSION(queue_ptr)
/* If trace is enabled, register this object. */
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_QUEUE, queue_ptr, name_ptr, queue_size, message_size)
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_QUEUE_CREATE, queue_ptr, message_size, TX_POINTER_TO_ULONG_CONVERT(queue_start), queue_size, TX_TRACE_QUEUE_EVENTS)
/* Log this kernel call. */
TX_EL_QUEUE_CREATE_INSERT
/* Restore interrupts. */
TX_RESTORE
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}