mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
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>
245 lines
9.7 KiB
C
245 lines
9.7 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 */
|
|
/** */
|
|
/** Timer */
|
|
/** */
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
#define TX_SOURCE_CODE
|
|
|
|
|
|
/* Include necessary system files. */
|
|
|
|
#include "tx_api.h"
|
|
#include "tx_trace.h"
|
|
#include "tx_timer.h"
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _tx_timer_info_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* William E. Lamie, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function retrieves information from the specified timer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* timer_ptr Pointer to timer control block */
|
|
/* name Destination for the timer name */
|
|
/* active Destination for active flag */
|
|
/* remaining_ticks Destination for remaining ticks */
|
|
/* before expiration */
|
|
/* reschedule_ticks Destination for reschedule ticks */
|
|
/* next_timer Destination for next timer on the */
|
|
/* created list */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _tx_timer_info_get(TX_TIMER *timer_ptr, TX_NAME_CONST CHAR **name, UINT *active, ULONG *remaining_ticks,
|
|
ULONG *reschedule_ticks, TX_TIMER **next_timer)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
TX_TIMER_INTERNAL *internal_ptr;
|
|
TX_TIMER_INTERNAL **list_head;
|
|
ULONG ticks_left;
|
|
UINT timer_active;
|
|
UINT active_timer_list;
|
|
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* If trace is enabled, insert this event into the trace buffer. */
|
|
TX_TRACE_IN_LINE_INSERT(TX_TRACE_TIMER_INFO_GET, timer_ptr, TX_POINTER_TO_ULONG_CONVERT(&ticks_left), 0, 0, TX_TRACE_TIMER_EVENTS)
|
|
|
|
/* Log this kernel call. */
|
|
TX_EL_TIMER_INFO_GET_INSERT
|
|
|
|
/* Retrieve the name of the timer. */
|
|
if (name != TX_NULL)
|
|
{
|
|
|
|
*name = timer_ptr -> tx_timer_name;
|
|
}
|
|
|
|
/* Pickup address of internal timer structure. */
|
|
internal_ptr = &(timer_ptr -> tx_timer_internal);
|
|
|
|
/* Retrieve all the pertinent information and return it in the supplied
|
|
destinations. */
|
|
|
|
/* Default active to false. */
|
|
timer_active = TX_FALSE;
|
|
|
|
/* Default the ticks left to the remaining ticks. */
|
|
ticks_left = internal_ptr -> tx_timer_internal_remaining_ticks;
|
|
|
|
/* Determine if the timer is still active. */
|
|
if (internal_ptr -> tx_timer_internal_list_head != TX_NULL)
|
|
{
|
|
|
|
/* Indicate this timer is active. */
|
|
timer_active = TX_TRUE;
|
|
|
|
/* Default the active timer list flag to false. */
|
|
active_timer_list = TX_FALSE;
|
|
|
|
/* Determine if the timer is still active. */
|
|
if (internal_ptr -> tx_timer_internal_list_head >= _tx_timer_list_start)
|
|
{
|
|
|
|
/* Determine if the list head is before the end of the list. */
|
|
if (internal_ptr -> tx_timer_internal_list_head < _tx_timer_list_end)
|
|
{
|
|
|
|
/* This timer is active and has not yet expired. */
|
|
active_timer_list = TX_TRUE;
|
|
}
|
|
}
|
|
|
|
/* Determine if the timer is on the active timer list. */
|
|
if (active_timer_list == TX_TRUE)
|
|
{
|
|
|
|
/* Calculate the amount of time that has elapsed since the timer
|
|
was activated. */
|
|
|
|
/* Setup the list head pointer. */
|
|
list_head = internal_ptr -> tx_timer_internal_list_head;
|
|
|
|
/* Is this timer's entry after the current timer pointer? */
|
|
if (internal_ptr -> tx_timer_internal_list_head >= _tx_timer_current_ptr)
|
|
{
|
|
|
|
/* Calculate ticks left to expiration - just the difference between this
|
|
timer's entry and the current timer pointer. */
|
|
ticks_left = ((TX_TIMER_POINTER_DIF(list_head, _tx_timer_current_ptr)) + ((ULONG) 1));
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Calculate the ticks left with a wrapped list condition. */
|
|
ticks_left = ((TX_TIMER_POINTER_DIF(list_head, _tx_timer_list_start)));
|
|
|
|
ticks_left = ticks_left + ((TX_TIMER_POINTER_DIF(_tx_timer_list_end, _tx_timer_current_ptr)) + ((ULONG) 1));
|
|
}
|
|
|
|
/* Adjust the remaining ticks accordingly. */
|
|
if (internal_ptr -> tx_timer_internal_remaining_ticks > TX_TIMER_ENTRIES)
|
|
{
|
|
|
|
/* Subtract off the last full pass through the timer list and add the
|
|
time left. */
|
|
ticks_left = (internal_ptr -> tx_timer_internal_remaining_ticks - TX_TIMER_ENTRIES) + ticks_left;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
/* The timer is not on the actual timer list so it must either be being processed
|
|
or on a temporary list to be processed. */
|
|
|
|
/* Check to see if this timer is the timer currently being processed. */
|
|
if (_tx_timer_expired_timer_ptr == internal_ptr)
|
|
{
|
|
|
|
/* Timer dispatch routine is executing, waiting to execute, or just finishing. No more remaining ticks for this expiration. */
|
|
ticks_left = ((ULONG) 0);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Timer is not the one being processed, which means it must be on the temporary expiration list
|
|
waiting to be processed. */
|
|
|
|
/* Calculate the remaining ticks for a timer in the process of expiring. */
|
|
if (ticks_left > TX_TIMER_ENTRIES)
|
|
{
|
|
|
|
/* Calculate the number of ticks remaining. */
|
|
ticks_left = internal_ptr -> tx_timer_internal_remaining_ticks - TX_TIMER_ENTRIES;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Timer dispatch routine is waiting to execute, no more remaining ticks for this expiration. */
|
|
ticks_left = ((ULONG) 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Setup return values for an inactive timer. */
|
|
if (active != TX_NULL)
|
|
{
|
|
|
|
/* Setup the timer active indication. */
|
|
*active = timer_active;
|
|
}
|
|
if (remaining_ticks != TX_NULL)
|
|
{
|
|
|
|
/* Setup the default remaining ticks value. */
|
|
*remaining_ticks = ticks_left;
|
|
}
|
|
|
|
/* Pickup the reschedule ticks value. */
|
|
if (reschedule_ticks != TX_NULL)
|
|
{
|
|
|
|
*reschedule_ticks = internal_ptr -> tx_timer_internal_re_initialize_ticks;
|
|
}
|
|
|
|
/* Pickup the next created application timer. */
|
|
if (next_timer != TX_NULL)
|
|
{
|
|
|
|
*next_timer = timer_ptr -> tx_timer_created_next;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Return completion status. */
|
|
return(TX_SUCCESS);
|
|
}
|
|
|