mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-09-23 06:54:13 +08:00
Initial commit
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
function(target_sources_if_not_overridden filename)
|
||||
list(FIND TX_SRC_OVERRIDES ${filename} OVERRIDE_FOUND)
|
||||
if( OVERRIDE_FOUND EQUAL -1 )
|
||||
message(STATUS "** Using original ${filename} from common/src **")
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/${filename})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# These files can be overridden by setting them in the variable list named TX_SRC_OVERRIDES
|
||||
target_sources_if_not_overridden("tx_thread_delete.c")
|
||||
target_sources_if_not_overridden("tx_thread_reset.c")
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
# {{BEGIN_TARGET_SOURCES}}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_allocate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_release.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_allocate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_search.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_release.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_set.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_set_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_high_level.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_kernel_enter.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_kernel_setup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_misra.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_priority_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_flush.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_front_send.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_receive.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_send.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_send_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_ceiling_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_cleanup.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_put_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_entry_exit_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_identify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_preemption_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_priority_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_relinquish.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_resume.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_shell_entry.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_sleep.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_analyze.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_error_handler.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_error_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_suspend.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_preempt_check.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_resume.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_suspend.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_terminate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_time_slice.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_time_slice_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_timeout.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_wait_abort.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_time_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_time_set.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_activate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_deactivate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_expiration_process.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_performance_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_performance_system_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_system_activate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_system_deactivate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_thread_entry.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_buffer_full_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_disable.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_enable.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_event_filter.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_event_unfilter.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_initialize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_interrupt_control.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_isr_enter_insert.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_isr_exit_insert.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_object_register.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_object_unregister.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_user_event_insert.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_allocate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_release.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_allocate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_release.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_set.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_set_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_flush.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_front_send.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_receive.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_send.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_send_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_ceiling_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_prioritize.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_put.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_put_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_entry_exit_notify.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_info_get.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_preemption_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_priority_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_relinquish.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_reset.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_resume.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_suspend.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_terminate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_time_slice_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_wait_abort.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_activate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_change.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_create.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_deactivate.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_delete.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_info_get.c
|
||||
|
||||
# {{END_TARGET_SOURCES}}
|
||||
)
|
||||
|
||||
# Add the Common/inc directory to the project include list
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc
|
||||
)
|
||||
|
||||
+2208
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,146 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_block_pool.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX block memory management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_BLOCK_POOL_H
|
||||
#define TX_BLOCK_POOL_H
|
||||
|
||||
|
||||
/* Define block memory control specific data definitions. */
|
||||
|
||||
#define TX_BLOCK_POOL_ID ((ULONG) 0x424C4F43)
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
|
||||
/* Yes, in-line initialization is supported, remap the block memory pool
|
||||
initialization function. */
|
||||
|
||||
#ifndef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_block_pool_initialize() \
|
||||
_tx_block_pool_created_ptr = TX_NULL; \
|
||||
_tx_block_pool_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_block_pool_initialize() \
|
||||
_tx_block_pool_created_ptr = TX_NULL; \
|
||||
_tx_block_pool_created_count = TX_EMPTY; \
|
||||
_tx_block_pool_performance_allocate_count = ((ULONG) 0); \
|
||||
_tx_block_pool_performance_release_count = ((ULONG) 0); \
|
||||
_tx_block_pool_performance_suspension_count = ((ULONG) 0); \
|
||||
_tx_block_pool_performance_timeout_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_BLOCK_POOL_INIT
|
||||
#else
|
||||
|
||||
/* No in-line initialization is supported, use standard function call. */
|
||||
VOID _tx_block_pool_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal block memory pool management function prototypes. */
|
||||
|
||||
VOID _tx_block_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
|
||||
|
||||
/* Block pool management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_BLOCK_POOL_INIT
|
||||
#define BLOCK_POOL_DECLARE
|
||||
#else
|
||||
#define BLOCK_POOL_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created block pool list. */
|
||||
|
||||
BLOCK_POOL_DECLARE TX_BLOCK_POOL * _tx_block_pool_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created block pools. */
|
||||
|
||||
BLOCK_POOL_DECLARE ULONG _tx_block_pool_created_count;
|
||||
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of block allocates. */
|
||||
|
||||
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_allocate_count;
|
||||
|
||||
|
||||
/* Define the total number of block releases. */
|
||||
|
||||
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_release_count;
|
||||
|
||||
|
||||
/* Define the total number of block pool suspensions. */
|
||||
|
||||
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of block pool timeouts. */
|
||||
|
||||
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post block pool delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_BLOCK_POOL_DELETE_PORT_COMPLETION
|
||||
#define TX_BLOCK_POOL_DELETE_PORT_COMPLETION(p)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,177 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_byte_pool.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX byte memory management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_BYTE_POOL_H
|
||||
#define TX_BYTE_POOL_H
|
||||
|
||||
|
||||
/* Define byte memory control specific data definitions. */
|
||||
|
||||
#define TX_BYTE_POOL_ID ((ULONG) 0x42595445)
|
||||
|
||||
#ifndef TX_BYTE_BLOCK_FREE
|
||||
#define TX_BYTE_BLOCK_FREE ((ULONG) 0xFFFFEEEEUL)
|
||||
#endif
|
||||
|
||||
#ifndef TX_BYTE_BLOCK_MIN
|
||||
#define TX_BYTE_BLOCK_MIN ((ULONG) 20)
|
||||
#endif
|
||||
|
||||
#ifndef TX_BYTE_POOL_MIN
|
||||
#define TX_BYTE_POOL_MIN ((ULONG) 100)
|
||||
#endif
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
|
||||
/* Yes, in-line initialization is supported, remap the byte memory pool
|
||||
initialization function. */
|
||||
|
||||
#ifndef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_byte_pool_initialize() \
|
||||
_tx_byte_pool_created_ptr = TX_NULL; \
|
||||
_tx_byte_pool_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_byte_pool_initialize() \
|
||||
_tx_byte_pool_created_ptr = TX_NULL; \
|
||||
_tx_byte_pool_created_count = TX_EMPTY; \
|
||||
_tx_byte_pool_performance_allocate_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_release_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_merge_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_split_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_search_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_suspension_count = ((ULONG) 0); \
|
||||
_tx_byte_pool_performance_timeout_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_BYTE_POOL_INIT
|
||||
#else
|
||||
|
||||
/* No in-line initialization is supported, use standard function call. */
|
||||
VOID _tx_byte_pool_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal byte memory pool management function prototypes. */
|
||||
|
||||
UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size);
|
||||
VOID _tx_byte_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
|
||||
|
||||
/* Byte pool management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_BYTE_POOL_INIT
|
||||
#define BYTE_POOL_DECLARE
|
||||
#else
|
||||
#define BYTE_POOL_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created byte pool list. */
|
||||
|
||||
BYTE_POOL_DECLARE TX_BYTE_POOL * _tx_byte_pool_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created byte pools. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_created_count;
|
||||
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of allocates. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_allocate_count;
|
||||
|
||||
|
||||
/* Define the total number of releases. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_release_count;
|
||||
|
||||
|
||||
/* Define the total number of adjacent memory fragment merges. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_merge_count;
|
||||
|
||||
|
||||
/* Define the total number of memory fragment splits. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_split_count;
|
||||
|
||||
|
||||
/* Define the total number of memory fragments searched during allocation. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_search_count;
|
||||
|
||||
|
||||
/* Define the total number of byte pool suspensions. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of byte pool timeouts. */
|
||||
|
||||
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post byte pool delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_BYTE_POOL_DELETE_PORT_COMPLETION
|
||||
#define TX_BYTE_POOL_DELETE_PORT_COMPLETION(p)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,147 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_event_flags.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX event flags management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_EVENT_FLAGS_H
|
||||
#define TX_EVENT_FLAGS_H
|
||||
|
||||
|
||||
/* Define event flags control specific data definitions. */
|
||||
|
||||
#define TX_EVENT_FLAGS_ID ((ULONG) 0x4456444E)
|
||||
#define TX_EVENT_FLAGS_AND_MASK ((UINT) 0x2)
|
||||
#define TX_EVENT_FLAGS_CLEAR_MASK ((UINT) 0x1)
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
|
||||
/* Yes, in-line initialization is supported, remap the event flag initialization
|
||||
function. */
|
||||
|
||||
#ifndef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_event_flags_initialize() \
|
||||
_tx_event_flags_created_ptr = TX_NULL; \
|
||||
_tx_event_flags_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_event_flags_initialize() \
|
||||
_tx_event_flags_created_ptr = TX_NULL; \
|
||||
_tx_event_flags_created_count = TX_EMPTY; \
|
||||
_tx_event_flags_performance_set_count = ((ULONG) 0); \
|
||||
_tx_event_flags_performance_get_count = ((ULONG) 0); \
|
||||
_tx_event_flags_performance_suspension_count = ((ULONG) 0); \
|
||||
_tx_event_flags_performance_timeout_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_EVENT_FLAGS_INIT
|
||||
#else
|
||||
|
||||
/* No in-line initialization is supported, use standard function call. */
|
||||
VOID _tx_event_flags_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal event flags management function prototypes. */
|
||||
|
||||
VOID _tx_event_flags_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
|
||||
|
||||
/* Event flags management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_INIT
|
||||
#define EVENT_FLAGS_DECLARE
|
||||
#else
|
||||
#define EVENT_FLAGS_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created event flags list. */
|
||||
|
||||
EVENT_FLAGS_DECLARE TX_EVENT_FLAGS_GROUP * _tx_event_flags_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created event flag groups. */
|
||||
|
||||
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_created_count;
|
||||
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of event flag sets. */
|
||||
|
||||
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_set_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag gets. */
|
||||
|
||||
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_get_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag suspensions. */
|
||||
|
||||
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag timeouts. */
|
||||
|
||||
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* Define default post event flag group delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION(g)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_initialize.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX initialization component, including */
|
||||
/* data types and external references. It is assumed that tx_api.h */
|
||||
/* and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_INITIALIZE_H
|
||||
#define TX_INITIALIZE_H
|
||||
|
||||
|
||||
/* Define constants that indicate initialization is in progress. */
|
||||
|
||||
#define TX_INITIALIZE_IN_PROGRESS ((ULONG) 0xF0F0F0F0UL)
|
||||
#define TX_INITIALIZE_ALMOST_DONE ((ULONG) 0xF0F0F0F1UL)
|
||||
#define TX_INITIALIZE_IS_FINISHED ((ULONG) 0x00000000UL)
|
||||
|
||||
|
||||
/* Define internal initialization function prototypes. */
|
||||
|
||||
VOID _tx_initialize_high_level(VOID);
|
||||
VOID _tx_initialize_kernel_setup(VOID);
|
||||
VOID _tx_initialize_low_level(VOID);
|
||||
|
||||
|
||||
/* Define the macro for adding additional port-specific global data. This macro is defined
|
||||
as white space, unless defined by tx_port.h. */
|
||||
|
||||
#ifndef TX_PORT_SPECIFIC_DATA
|
||||
#define TX_PORT_SPECIFIC_DATA
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macro for adding additional port-specific pre and post initialization processing.
|
||||
These macros is defined as white space, unless defined by tx_port.h. */
|
||||
|
||||
#ifndef TX_PORT_SPECIFIC_PRE_INITIALIZATION
|
||||
#define TX_PORT_SPECIFIC_PRE_INITIALIZATION
|
||||
#endif
|
||||
|
||||
#ifndef TX_PORT_SPECIFIC_POST_INITIALIZATION
|
||||
#define TX_PORT_SPECIFIC_POST_INITIALIZATION
|
||||
#endif
|
||||
|
||||
#ifndef TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
|
||||
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
|
||||
#endif
|
||||
|
||||
|
||||
/* Initialization component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_INITIALIZE_INIT
|
||||
#define INITIALIZE_DECLARE
|
||||
#else
|
||||
#define INITIALIZE_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the unused memory pointer. The value of the first available
|
||||
memory address is placed in this variable in the low-level
|
||||
initialization function. The content of this variable is passed
|
||||
to the application's system definition function. */
|
||||
|
||||
INITIALIZE_DECLARE VOID *_tx_initialize_unused_memory;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Mutex */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_mutex.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX mutex management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_MUTEX_H
|
||||
#define TX_MUTEX_H
|
||||
|
||||
|
||||
/* Define mutex control specific data definitions. */
|
||||
|
||||
#define TX_MUTEX_ID ((ULONG) 0x4D555445)
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
|
||||
/* Yes, in-line initialization is supported, remap the mutex initialization
|
||||
function. */
|
||||
|
||||
#ifndef TX_MUTEX_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_mutex_initialize() \
|
||||
_tx_mutex_created_ptr = TX_NULL; \
|
||||
_tx_mutex_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_mutex_initialize() \
|
||||
_tx_mutex_created_ptr = TX_NULL; \
|
||||
_tx_mutex_created_count = TX_EMPTY; \
|
||||
_tx_mutex_performance_put_count = ((ULONG) 0); \
|
||||
_tx_mutex_performance_get_count = ((ULONG) 0); \
|
||||
_tx_mutex_performance_suspension_count = ((ULONG) 0); \
|
||||
_tx_mutex_performance_timeout_count = ((ULONG) 0); \
|
||||
_tx_mutex_performance_priority_inversion_count = ((ULONG) 0); \
|
||||
_tx_mutex_performance__priority_inheritance_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_MUTEX_INIT
|
||||
#else
|
||||
|
||||
/* No in-line initialization is supported, use standard function call. */
|
||||
VOID _tx_mutex_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal mutex management function prototypes. */
|
||||
|
||||
VOID _tx_mutex_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
VOID _tx_mutex_thread_release(TX_THREAD *thread_ptr);
|
||||
VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT new_priority);
|
||||
|
||||
|
||||
/* Mutex management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_MUTEX_INIT
|
||||
#define MUTEX_DECLARE
|
||||
#else
|
||||
#define MUTEX_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created mutex list. */
|
||||
|
||||
MUTEX_DECLARE TX_MUTEX * _tx_mutex_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created mutexes. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_created_count;
|
||||
|
||||
|
||||
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of mutex puts. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance_put_count;
|
||||
|
||||
|
||||
/* Define the total number of mutex gets. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance_get_count;
|
||||
|
||||
|
||||
/* Define the total number of mutex suspensions. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of mutex timeouts. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance_timeout_count;
|
||||
|
||||
|
||||
/* Define the total number of priority inversions. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance_priority_inversion_count;
|
||||
|
||||
|
||||
/* Define the total number of priority inheritance conditions. */
|
||||
|
||||
MUTEX_DECLARE ULONG _tx_mutex_performance__priority_inheritance_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post mutex delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_MUTEX_DELETE_PORT_COMPLETION
|
||||
#define TX_MUTEX_DELETE_PORT_COMPLETION(m)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Queue */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_queue.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX queue management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_QUEUE_H
|
||||
#define TX_QUEUE_H
|
||||
|
||||
|
||||
/* Define queue control specific data definitions. */
|
||||
|
||||
#define TX_QUEUE_ID ((ULONG) 0x51554555)
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
|
||||
/* Yes, in-line initialization is supported, remap the queue initialization
|
||||
function. */
|
||||
|
||||
#ifndef TX_QUEUE_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_queue_initialize() \
|
||||
_tx_queue_created_ptr = TX_NULL; \
|
||||
_tx_queue_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_queue_initialize() \
|
||||
_tx_queue_created_ptr = TX_NULL; \
|
||||
_tx_queue_created_count = TX_EMPTY; \
|
||||
_tx_queue_performance_messages_sent_count = ((ULONG) 0); \
|
||||
_tx_queue_performance__messages_received_count = ((ULONG) 0); \
|
||||
_tx_queue_performance_empty_suspension_count = ((ULONG) 0); \
|
||||
_tx_queue_performance_full_suspension_count = ((ULONG) 0); \
|
||||
_tx_queue_performance_timeout_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_QUEUE_INIT
|
||||
#else
|
||||
|
||||
/* No in-line initialization is supported, use standard function call. */
|
||||
VOID _tx_queue_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the message copy macro. Note that the source and destination
|
||||
pointers must be modified since they are used subsequently. */
|
||||
|
||||
#ifndef TX_QUEUE_MESSAGE_COPY
|
||||
#define TX_QUEUE_MESSAGE_COPY(s, d, z) \
|
||||
*(d)++ = *(s)++; \
|
||||
if ((z) > ((UINT) 1)) \
|
||||
{ \
|
||||
while (--(z)) \
|
||||
{ \
|
||||
*(d)++ = *(s)++; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal queue management function prototypes. */
|
||||
|
||||
VOID _tx_queue_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
|
||||
|
||||
/* Queue management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_QUEUE_INIT
|
||||
#define QUEUE_DECLARE
|
||||
#else
|
||||
#define QUEUE_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created queue list. */
|
||||
|
||||
QUEUE_DECLARE TX_QUEUE * _tx_queue_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created queues. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_created_count;
|
||||
|
||||
|
||||
#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of messages sent. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance_messages_sent_count;
|
||||
|
||||
|
||||
/* Define the total number of messages received. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance__messages_received_count;
|
||||
|
||||
|
||||
/* Define the total number of queue empty suspensions. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance_empty_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of queue full suspensions. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance_full_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of queue full errors. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance_full_error_count;
|
||||
|
||||
|
||||
/* Define the total number of queue timeouts. */
|
||||
|
||||
QUEUE_DECLARE ULONG _tx_queue_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post queue delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_QUEUE_DELETE_PORT_COMPLETION
|
||||
#define TX_QUEUE_DELETE_PORT_COMPLETION(q)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Semaphore */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_semaphore.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX semaphore management component, */
|
||||
/* including all data types and external references. It is assumed */
|
||||
/* that tx_api.h and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_SEMAPHORE_H
|
||||
#define TX_SEMAPHORE_H
|
||||
|
||||
|
||||
/* Define semaphore control specific data definitions. */
|
||||
|
||||
#define TX_SEMAPHORE_ID ((ULONG) 0x53454D41)
|
||||
|
||||
|
||||
/* Determine if in-line component initialization is supported by the
|
||||
caller. */
|
||||
#ifdef TX_INVOKE_INLINE_INITIALIZATION
|
||||
/* Yes, in-line initialization is supported, remap the
|
||||
semaphore initialization function. */
|
||||
#ifndef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
|
||||
#define _tx_semaphore_initialize() \
|
||||
_tx_semaphore_created_ptr = TX_NULL; \
|
||||
_tx_semaphore_created_count = TX_EMPTY
|
||||
#else
|
||||
#define _tx_semaphore_initialize() \
|
||||
_tx_semaphore_created_ptr = TX_NULL; \
|
||||
_tx_semaphore_created_count = TX_EMPTY; \
|
||||
_tx_semaphore_performance_put_count = ((ULONG) 0); \
|
||||
_tx_semaphore_performance_get_count = ((ULONG) 0); \
|
||||
_tx_semaphore_performance_suspension_count = ((ULONG) 0); \
|
||||
_tx_semaphore_performance_timeout_count = ((ULONG) 0)
|
||||
#endif
|
||||
#define TX_SEMAPHORE_INIT
|
||||
#else
|
||||
/* No in-line initialization is supported, use standard
|
||||
function call. */
|
||||
VOID _tx_semaphore_initialize(VOID);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define internal semaphore management function prototypes. */
|
||||
|
||||
VOID _tx_semaphore_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
|
||||
|
||||
|
||||
/* Semaphore management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_SEMAPHORE_INIT
|
||||
#define SEMAPHORE_DECLARE
|
||||
#else
|
||||
#define SEMAPHORE_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the head pointer of the created semaphore list. */
|
||||
|
||||
SEMAPHORE_DECLARE TX_SEMAPHORE * _tx_semaphore_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created semaphores. */
|
||||
|
||||
SEMAPHORE_DECLARE ULONG _tx_semaphore_created_count;
|
||||
|
||||
|
||||
#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of semaphore puts. */
|
||||
|
||||
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_put_count;
|
||||
|
||||
|
||||
/* Define the total number of semaphore gets. */
|
||||
|
||||
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_get_count;
|
||||
|
||||
|
||||
/* Define the total number of semaphore suspensions. */
|
||||
|
||||
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of semaphore timeouts. */
|
||||
|
||||
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post semaphore delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_SEMAPHORE_DELETE_PORT_COMPLETION
|
||||
#define TX_SEMAPHORE_DELETE_PORT_COMPLETION(s)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,213 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Timer */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* COMPONENT DEFINITION RELEASE */
|
||||
/* */
|
||||
/* tx_timer.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the ThreadX timer management component, including */
|
||||
/* data types and external references. It is assumed that tx_api.h */
|
||||
/* and tx_port.h have already been included. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_TIMER_H
|
||||
#define TX_TIMER_H
|
||||
|
||||
|
||||
/* Define timer management specific data definitions. */
|
||||
|
||||
#define TX_TIMER_ID ((ULONG) 0x4154494D)
|
||||
#define TX_TIMER_ENTRIES ((ULONG) 32)
|
||||
|
||||
|
||||
/* Define internal timer management function prototypes. */
|
||||
|
||||
VOID _tx_timer_expiration_process(VOID);
|
||||
VOID _tx_timer_initialize(VOID);
|
||||
VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr);
|
||||
VOID _tx_timer_system_deactivate(TX_TIMER_INTERNAL *timer_ptr);
|
||||
VOID _tx_timer_thread_entry(ULONG timer_thread_input);
|
||||
|
||||
|
||||
/* Timer management component data declarations follow. */
|
||||
|
||||
/* Determine if the initialization function of this component is including
|
||||
this file. If so, make the data definitions really happen. Otherwise,
|
||||
make them extern so other functions in the component can access them. */
|
||||
|
||||
#ifdef TX_TIMER_INIT
|
||||
#define TIMER_DECLARE
|
||||
#else
|
||||
#define TIMER_DECLARE extern
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system clock value that is continually incremented by the
|
||||
periodic timer interrupt processing. */
|
||||
|
||||
TIMER_DECLARE volatile ULONG _tx_timer_system_clock;
|
||||
|
||||
|
||||
/* Define the current time slice value. If non-zero, a time-slice is active.
|
||||
Otherwise, the time_slice is not active. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_time_slice;
|
||||
|
||||
|
||||
/* Define the time-slice expiration flag. This is used to indicate that a time-slice
|
||||
has happened. */
|
||||
|
||||
TIMER_DECLARE UINT _tx_timer_expired_time_slice;
|
||||
|
||||
|
||||
/* Define the thread and application timer entry list. This list provides a direct access
|
||||
method for insertion of times less than TX_TIMER_ENTRIES. */
|
||||
|
||||
TIMER_DECLARE TX_TIMER_INTERNAL *_tx_timer_list[TX_TIMER_ENTRIES];
|
||||
|
||||
|
||||
/* Define the boundary pointers to the list. These are setup to easily manage
|
||||
wrapping the list. */
|
||||
|
||||
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_list_start;
|
||||
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_list_end;
|
||||
|
||||
|
||||
/* Define the current timer pointer in the list. This pointer is moved sequentially
|
||||
through the timer list by the timer interrupt handler. */
|
||||
|
||||
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_current_ptr;
|
||||
|
||||
|
||||
/* Define the timer expiration flag. This is used to indicate that a timer
|
||||
has expired. */
|
||||
|
||||
TIMER_DECLARE UINT _tx_timer_expired;
|
||||
|
||||
|
||||
/* Define the created timer list head pointer. */
|
||||
|
||||
TIMER_DECLARE TX_TIMER *_tx_timer_created_ptr;
|
||||
|
||||
|
||||
/* Define the created timer count. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_created_count;
|
||||
|
||||
|
||||
/* Define the pointer to the timer that has expired and is being processed. */
|
||||
|
||||
TIMER_DECLARE TX_TIMER_INTERNAL *_tx_timer_expired_timer_ptr;
|
||||
|
||||
|
||||
#ifndef TX_TIMER_PROCESS_IN_ISR
|
||||
|
||||
/* Define the timer thread's control block. */
|
||||
|
||||
TIMER_DECLARE TX_THREAD _tx_timer_thread;
|
||||
|
||||
|
||||
/* Define the variable that holds the timer thread's starting stack address. */
|
||||
|
||||
TIMER_DECLARE VOID *_tx_timer_stack_start;
|
||||
|
||||
|
||||
/* Define the variable that holds the timer thread's stack size. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_stack_size;
|
||||
|
||||
|
||||
/* Define the variable that holds the timer thread's priority. */
|
||||
|
||||
TIMER_DECLARE UINT _tx_timer_priority;
|
||||
|
||||
/* Define the system timer thread's stack. The default size is defined
|
||||
in tx_port.h. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_thread_stack_area[(((UINT) TX_TIMER_THREAD_STACK_SIZE)+((sizeof(ULONG)) - ((UINT) 1)))/sizeof(ULONG)];
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/* Define the busy flag that will prevent nested timer ISR processing. */
|
||||
|
||||
TIMER_DECLARE UINT _tx_timer_processing_active;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of timer activations. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_performance_activate_count;
|
||||
|
||||
|
||||
/* Define the total number of timer reactivations. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_performance_reactivate_count;
|
||||
|
||||
|
||||
/* Define the total number of timer deactivations. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_performance_deactivate_count;
|
||||
|
||||
|
||||
/* Define the total number of timer expirations. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_performance_expiration_count;
|
||||
|
||||
|
||||
/* Define the total number of timer expiration adjustments. These are required
|
||||
if the expiration time is greater than the size of the timer list. In such
|
||||
cases, the timer is placed at the end of the list and then reactivated
|
||||
as many times as necessary to finally achieve the resulting timeout. */
|
||||
|
||||
TIMER_DECLARE ULONG _tx_timer_performance__expiration_adjust_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define default post timer delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
|
||||
|
||||
#ifndef TX_TIMER_DELETE_PORT_COMPLETION
|
||||
#define TX_TIMER_DELETE_PORT_COMPLETION(t)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** User Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_user.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains user defines for configuring ThreadX in specific */
|
||||
/* ways. This file will have an effect only if the application and */
|
||||
/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */
|
||||
/* Note that all the defines in this file may also be made on the */
|
||||
/* command line when building ThreadX library and application objects. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_USER_H
|
||||
#define TX_USER_H
|
||||
|
||||
|
||||
/* Define various build options for the ThreadX port. The application should either make changes
|
||||
here by commenting or un-commenting the conditional compilation defined OR supply the defines
|
||||
though the compiler's equivalent of the -D option.
|
||||
|
||||
For maximum speed, the following should be defined:
|
||||
|
||||
TX_MAX_PRIORITIES 32
|
||||
TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
TX_DISABLE_REDUNDANT_CLEARING
|
||||
TX_DISABLE_NOTIFY_CALLBACKS
|
||||
TX_NOT_INTERRUPTABLE
|
||||
TX_TIMER_PROCESS_IN_ISR
|
||||
TX_REACTIVATE_INLINE
|
||||
TX_DISABLE_STACK_FILLING
|
||||
TX_INLINE_THREAD_RESUME_SUSPEND
|
||||
|
||||
For minimum size, the following should be defined:
|
||||
|
||||
TX_MAX_PRIORITIES 32
|
||||
TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
TX_DISABLE_REDUNDANT_CLEARING
|
||||
TX_DISABLE_NOTIFY_CALLBACKS
|
||||
TX_NOT_INTERRUPTABLE
|
||||
TX_TIMER_PROCESS_IN_ISR
|
||||
|
||||
Of course, many of these defines reduce functionality and/or change the behavior of the
|
||||
system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR
|
||||
results in faster and smaller code, however, it increases the amount of processing in the ISR.
|
||||
In addition, some services that are available in timers are not available from ISRs and will
|
||||
therefore return an error if this option is used. This may or may not be desirable for a
|
||||
given application. */
|
||||
|
||||
|
||||
/* Override various options with default values already assigned in tx_port.h. Please also refer
|
||||
to tx_port.h for descriptions on each of these options. */
|
||||
|
||||
/*
|
||||
#define TX_MAX_PRIORITIES 32
|
||||
#define TX_MINIMUM_STACK ????
|
||||
#define TX_THREAD_USER_EXTENSION ????
|
||||
#define TX_TIMER_THREAD_STACK_SIZE ????
|
||||
#define TX_TIMER_THREAD_PRIORITY ????
|
||||
*/
|
||||
|
||||
/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls
|
||||
should be processed within the a system timer thread or directly in the timer ISR.
|
||||
By default, the timer thread is used. When the following is defined, the timer expiration
|
||||
processing is done directly from the timer ISR, thereby eliminating the timer thread control
|
||||
block, stack, and context switching to activate it. */
|
||||
|
||||
/*
|
||||
#define TX_TIMER_PROCESS_IN_ISR
|
||||
*/
|
||||
|
||||
/* Determine if in-line timer reactivation should be used within the timer expiration processing.
|
||||
By default, this is disabled and a function call is used. When the following is defined,
|
||||
reactivating is performed in-line resulting in faster timer processing but slightly larger
|
||||
code size. */
|
||||
|
||||
/*
|
||||
#define TX_REACTIVATE_INLINE
|
||||
*/
|
||||
|
||||
/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled,
|
||||
which places an 0xEF pattern in each byte of each thread's stack. This is used by
|
||||
debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */
|
||||
|
||||
/*
|
||||
#define TX_DISABLE_STACK_FILLING
|
||||
*/
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
logic. */
|
||||
|
||||
/*
|
||||
#define TX_ENABLE_STACK_CHECKING
|
||||
*/
|
||||
|
||||
/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is
|
||||
enabled. If the application does not use preemption-threshold, it may be disabled to reduce
|
||||
code size and improve performance. */
|
||||
|
||||
/*
|
||||
#define TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
*/
|
||||
|
||||
/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears
|
||||
the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary
|
||||
clearing of ThreadX global variables. */
|
||||
|
||||
/*
|
||||
#define TX_DISABLE_REDUNDANT_CLEARING
|
||||
*/
|
||||
|
||||
/* Determine if no timer processing is required. This option will help eliminate the timer
|
||||
processing when not needed. The user will also have to comment out the call to
|
||||
tx_timer_interrupt, which is typically made from assembly language in
|
||||
tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR
|
||||
must also be used. */
|
||||
|
||||
/*
|
||||
#define TX_NO_TIMER
|
||||
#ifndef TX_TIMER_PROCESS_IN_ISR
|
||||
#define TX_TIMER_PROCESS_IN_ISR
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Determine if the notify callback option should be disabled. By default, notify callbacks are
|
||||
enabled. If the application does not use notify callbacks, they may be disabled to reduce
|
||||
code size and improve performance. */
|
||||
|
||||
/*
|
||||
#define TX_DISABLE_NOTIFY_CALLBACKS
|
||||
*/
|
||||
|
||||
|
||||
/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal
|
||||
code in-line. This results in a larger image, but improves the performance of the thread
|
||||
resume and suspend services. */
|
||||
|
||||
/*
|
||||
#define TX_INLINE_THREAD_RESUME_SUSPEND
|
||||
*/
|
||||
|
||||
|
||||
/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code
|
||||
size and less processing overhead, but increases the interrupt lockout time. */
|
||||
|
||||
/*
|
||||
#define TX_NOT_INTERRUPTABLE
|
||||
*/
|
||||
|
||||
|
||||
/* Determine if the trace event logging code should be enabled. This causes slight increases in
|
||||
code size and overhead, but provides the ability to generate system trace information which
|
||||
is available for viewing in TraceX. */
|
||||
|
||||
/*
|
||||
#define TX_ENABLE_EVENT_TRACE
|
||||
*/
|
||||
|
||||
|
||||
/* Determine if block pool performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various block pool performance information. */
|
||||
|
||||
/*
|
||||
#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if byte pool performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various byte pool performance information. */
|
||||
|
||||
/*
|
||||
#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if event flags performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various event flags performance information. */
|
||||
|
||||
/*
|
||||
#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if mutex performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various mutex performance information. */
|
||||
|
||||
/*
|
||||
#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if queue performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various queue performance information. */
|
||||
|
||||
/*
|
||||
#define TX_QUEUE_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if semaphore performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various semaphore performance information. */
|
||||
|
||||
/*
|
||||
#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if thread performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various thread performance information. */
|
||||
|
||||
/*
|
||||
#define TX_THREAD_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
/* Determine if timer performance gathering is required by the application. When the following is
|
||||
defined, ThreadX gathers various timer performance information. */
|
||||
|
||||
/*
|
||||
#define TX_TIMER_ENABLE_PERFORMANCE_INFO
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,372 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
#include "tx_thread.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_allocate PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function allocates a block from the specified memory block */
|
||||
/* pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* block_ptr Pointer to place allocated block */
|
||||
/* pointer */
|
||||
/* wait_option Suspension option */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_suspend Suspend thread */
|
||||
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT status;
|
||||
TX_THREAD *thread_ptr;
|
||||
UCHAR *work_ptr;
|
||||
UCHAR *temp_ptr;
|
||||
UCHAR **next_block_ptr;
|
||||
UCHAR **return_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
TX_TRACE_BUFFER_ENTRY *entry_ptr;
|
||||
ULONG time_stamp = ((ULONG) 0);
|
||||
#endif
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
UCHAR *log_entry_ptr;
|
||||
ULONG upper_tbu;
|
||||
ULONG lower_tbu;
|
||||
#endif
|
||||
|
||||
|
||||
/* Disable interrupts to get a block from the pool. */
|
||||
TX_DISABLE
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total allocations counter. */
|
||||
_tx_block_pool_performance_allocate_count++;
|
||||
|
||||
/* Increment the number of allocations on this pool. */
|
||||
pool_ptr -> tx_block_pool_performance_allocate_count++;
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* If trace is enabled, save the current event pointer. */
|
||||
entry_ptr = _tx_trace_buffer_current_ptr;
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_ALLOCATE, pool_ptr, 0, wait_option, pool_ptr -> tx_block_pool_available, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Save the time stamp for later comparison to verify that
|
||||
the event hasn't been overwritten by the time the allocate
|
||||
call succeeds. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
time_stamp = entry_ptr -> tx_trace_buffer_entry_time_stamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
log_entry_ptr = *(UCHAR **) _tx_el_current_event;
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_ALLOCATE_INSERT
|
||||
|
||||
/* Store -1 in the third event slot. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) -1;
|
||||
|
||||
/* Save the time stamp for later comparison to verify that
|
||||
the event hasn't been overwritten by the time the allocate
|
||||
call succeeds. */
|
||||
lower_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET));
|
||||
upper_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET));
|
||||
#endif
|
||||
|
||||
/* Determine if there is an available block. */
|
||||
if (pool_ptr -> tx_block_pool_available != ((UINT) 0))
|
||||
{
|
||||
|
||||
/* Yes, a block is available. Decrement the available count. */
|
||||
pool_ptr -> tx_block_pool_available--;
|
||||
|
||||
/* Pickup the current block pointer. */
|
||||
work_ptr = pool_ptr -> tx_block_pool_available_list;
|
||||
|
||||
/* Return the first available block to the caller. */
|
||||
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
|
||||
return_ptr = TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*return_ptr = temp_ptr;
|
||||
|
||||
/* Modify the available list to point at the next block in the pool. */
|
||||
next_block_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
|
||||
pool_ptr -> tx_block_pool_available_list = *next_block_ptr;
|
||||
|
||||
/* Save the pool's address in the block for when it is released! */
|
||||
temp_ptr = TX_BLOCK_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
|
||||
*next_block_ptr = temp_ptr;
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Is the time stamp the same? */
|
||||
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
|
||||
{
|
||||
|
||||
/* Timestamp is the same, update the entry with the address. */
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
|
||||
#else
|
||||
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
/* Store the address of the allocated block. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) *block_ptr;
|
||||
#endif
|
||||
|
||||
/* Set status to success. */
|
||||
status = TX_SUCCESS;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Default the return pointer to NULL. */
|
||||
return_ptr = TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*return_ptr = TX_NULL;
|
||||
|
||||
/* Determine if the request specifies suspension. */
|
||||
if (wait_option != TX_NO_WAIT)
|
||||
{
|
||||
|
||||
/* Determine if the preempt disable flag is non-zero. */
|
||||
if (_tx_thread_preempt_disable != ((UINT) 0))
|
||||
{
|
||||
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
|
||||
status = TX_NO_MEMORY;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Prepare for suspension of this thread. */
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total suspensions counter. */
|
||||
_tx_block_pool_performance_suspension_count++;
|
||||
|
||||
/* Increment the number of suspensions on this pool. */
|
||||
pool_ptr -> tx_block_pool_performance_suspension_count++;
|
||||
#endif
|
||||
|
||||
/* Pickup thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr)
|
||||
|
||||
/* Setup cleanup routine pointer. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
|
||||
|
||||
/* Setup cleanup information, i.e. this pool control
|
||||
block. */
|
||||
thread_ptr -> tx_thread_suspend_control_block = (VOID *) pool_ptr;
|
||||
|
||||
/* Save the return block pointer address as well. */
|
||||
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) block_ptr;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Increment the suspension sequence number, which is used to identify
|
||||
this suspension event. */
|
||||
thread_ptr -> tx_thread_suspension_sequence++;
|
||||
#endif
|
||||
|
||||
/* Pickup the number of suspended threads. */
|
||||
suspended_count = (pool_ptr -> tx_block_pool_suspended_count);
|
||||
|
||||
/* Increment the number of suspended threads. */
|
||||
(pool_ptr -> tx_block_pool_suspended_count)++;
|
||||
|
||||
/* Setup suspension list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* No other threads are suspended. Setup the head pointer and
|
||||
just setup this threads pointers to itself. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_next = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add current thread to the end. */
|
||||
next_thread = pool_ptr -> tx_block_pool_suspension_list;
|
||||
thread_ptr -> tx_thread_suspended_next = next_thread;
|
||||
previous_thread = next_thread -> tx_thread_suspended_previous;
|
||||
thread_ptr -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = thread_ptr;
|
||||
next_thread -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
|
||||
/* Set the state to suspended. */
|
||||
thread_ptr -> tx_thread_state = TX_BLOCK_MEMORY;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Call actual non-interruptable thread suspension routine. */
|
||||
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Set the suspending flag. */
|
||||
thread_ptr -> tx_thread_suspending = TX_TRUE;
|
||||
|
||||
/* Setup the timeout period. */
|
||||
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Call actual thread suspension routine. */
|
||||
_tx_thread_system_suspend(thread_ptr);
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Is the time-stamp the same? */
|
||||
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
|
||||
{
|
||||
|
||||
/* Timestamp is the same, update the entry with the address. */
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
|
||||
#else
|
||||
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
/* Check that the event time stamp is unchanged and the call is about
|
||||
to return success. A different timestamp means that a later event
|
||||
wrote over the block allocate event. A return value other than
|
||||
TX_SUCCESS indicates that no block was available. In those cases,
|
||||
do nothing here. */
|
||||
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
|
||||
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) &&
|
||||
((thread_ptr -> tx_thread_suspend_status) == TX_SUCCESS))
|
||||
{
|
||||
|
||||
/* Store the address of the allocated block. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) *block_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the completion status. */
|
||||
status = thread_ptr -> tx_thread_suspend_status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Immediate return, return error completion. */
|
||||
status = TX_NO_MEMORY;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_cleanup PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes block allocate timeout and thread terminate */
|
||||
/* actions that require the block pool data structures to be cleaned */
|
||||
/* up. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to suspended thread's */
|
||||
/* control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_timeout Thread timeout processing */
|
||||
/* _tx_thread_terminate Thread terminate processing */
|
||||
/* _tx_thread_wait_abort Thread wait abort processing */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_block_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
#endif
|
||||
|
||||
TX_BLOCK_POOL *pool_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Disable interrupts to remove the suspended thread from the block pool. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if the cleanup is still required. */
|
||||
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_block_pool_cleanup))
|
||||
{
|
||||
|
||||
/* Check for valid suspension sequence. */
|
||||
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
|
||||
{
|
||||
|
||||
/* Setup pointer to block pool control block. */
|
||||
pool_ptr = TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
|
||||
/* Check for a NULL byte pool pointer. */
|
||||
if (pool_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Check for valid pool ID. */
|
||||
if (pool_ptr -> tx_block_pool_id == TX_BLOCK_POOL_ID)
|
||||
{
|
||||
|
||||
/* Determine if there are any thread suspensions. */
|
||||
if (pool_ptr -> tx_block_pool_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
#else
|
||||
|
||||
/* Setup pointer to block pool control block. */
|
||||
pool_ptr = TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
#endif
|
||||
|
||||
/* Yes, we still have thread suspension! */
|
||||
|
||||
/* Clear the suspension cleanup flag. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Decrement the suspended count. */
|
||||
pool_ptr -> tx_block_pool_suspended_count--;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same suspension list. */
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Determine if we need to update the head pointer. */
|
||||
if (pool_ptr -> tx_block_pool_suspension_list == thread_ptr)
|
||||
{
|
||||
|
||||
/* Update the list head pointer. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = next_thread;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we need to determine if this cleanup is from a terminate, timeout,
|
||||
or from a wait abort. */
|
||||
if (thread_ptr -> tx_thread_state == TX_BLOCK_MEMORY)
|
||||
{
|
||||
|
||||
/* Timeout condition and the thread still suspended on the block pool.
|
||||
Setup return error status and resume the thread. */
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total timeouts counter. */
|
||||
_tx_block_pool_performance_timeout_count++;
|
||||
|
||||
/* Increment the number of timeouts on this block pool. */
|
||||
pool_ptr -> tx_block_pool_performance_timeout_count++;
|
||||
#endif
|
||||
|
||||
/* Setup return status. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_NO_MEMORY;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
#else
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
}
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_create PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function creates a pool of fixed-size memory blocks in the */
|
||||
/* specified memory area. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* name_ptr Pointer to block pool name */
|
||||
/* block_size Number of bytes in each block */
|
||||
/* pool_start Address of beginning of pool area */
|
||||
/* pool_size Number of bytes in the block pool */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
|
||||
VOID *pool_start, ULONG pool_size)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT blocks;
|
||||
UINT status;
|
||||
ULONG total_blocks;
|
||||
UCHAR *block_ptr;
|
||||
UCHAR **block_link_ptr;
|
||||
UCHAR *next_block_ptr;
|
||||
TX_BLOCK_POOL *next_pool;
|
||||
TX_BLOCK_POOL *previous_pool;
|
||||
|
||||
|
||||
/* Initialize block pool control block to all zeros. */
|
||||
TX_MEMSET(pool_ptr, 0, (sizeof(TX_BLOCK_POOL)));
|
||||
|
||||
/* Round the block size up to something that is evenly divisible by
|
||||
an ALIGN_TYPE (typically this is a 32-bit ULONG). This helps guarantee proper alignment. */
|
||||
block_size = (((block_size + (sizeof(ALIGN_TYPE))) - ((ALIGN_TYPE) 1))/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
|
||||
|
||||
/* Round the pool size down to something that is evenly divisible by
|
||||
an ALIGN_TYPE (typically this is a 32-bit ULONG). */
|
||||
pool_size = (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
|
||||
|
||||
/* Setup the basic block pool fields. */
|
||||
pool_ptr -> tx_block_pool_name = name_ptr;
|
||||
pool_ptr -> tx_block_pool_start = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
pool_ptr -> tx_block_pool_size = pool_size;
|
||||
pool_ptr -> tx_block_pool_block_size = (UINT) block_size;
|
||||
|
||||
/* Calculate the total number of blocks. */
|
||||
total_blocks = pool_size/(block_size + (sizeof(UCHAR *)));
|
||||
|
||||
/* Walk through the pool area, setting up the available block list. */
|
||||
blocks = ((UINT) 0);
|
||||
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
next_block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (block_size + (sizeof(UCHAR *))));
|
||||
while(blocks < (UINT) total_blocks)
|
||||
{
|
||||
|
||||
/* Yes, we have another block. Increment the block count. */
|
||||
blocks++;
|
||||
|
||||
/* Setup the link to the next block. */
|
||||
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*block_link_ptr = next_block_ptr;
|
||||
|
||||
/* Advance to the next block. */
|
||||
block_ptr = next_block_ptr;
|
||||
|
||||
/* Update the next block pointer. */
|
||||
next_block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (block_size + (sizeof(UCHAR *))));
|
||||
}
|
||||
|
||||
/* Save the remaining information in the pool control block. */
|
||||
pool_ptr -> tx_block_pool_available = blocks;
|
||||
pool_ptr -> tx_block_pool_total = blocks;
|
||||
|
||||
/* Quickly check to make sure at least one block is in the pool. */
|
||||
if (blocks != ((UINT) 0))
|
||||
{
|
||||
|
||||
/* Backup to the last block in the pool. */
|
||||
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr,(block_size + (sizeof(UCHAR *))));
|
||||
|
||||
/* Set the last block's forward pointer to NULL. */
|
||||
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*block_link_ptr = TX_NULL;
|
||||
|
||||
/* Setup the starting pool address. */
|
||||
pool_ptr -> tx_block_pool_available_list = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
|
||||
/* Disable interrupts to place the block pool on the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Setup the block pool ID to make it valid. */
|
||||
pool_ptr -> tx_block_pool_id = TX_BLOCK_POOL_ID;
|
||||
|
||||
/* Place the block pool on the list of created block pools. First,
|
||||
check for an empty list. */
|
||||
if (_tx_block_pool_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* The created block pool list is empty. Add block pool to empty list. */
|
||||
_tx_block_pool_created_ptr = pool_ptr;
|
||||
pool_ptr -> tx_block_pool_created_next = pool_ptr;
|
||||
pool_ptr -> tx_block_pool_created_previous = pool_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add to the end of the list. */
|
||||
next_pool = _tx_block_pool_created_ptr;
|
||||
previous_pool = next_pool -> tx_block_pool_created_previous;
|
||||
|
||||
/* Place the new block pool in the list. */
|
||||
next_pool -> tx_block_pool_created_previous = pool_ptr;
|
||||
previous_pool -> tx_block_pool_created_next = pool_ptr;
|
||||
|
||||
/* Setup this block pool's created links. */
|
||||
pool_ptr -> tx_block_pool_created_previous = previous_pool;
|
||||
pool_ptr -> tx_block_pool_created_next = next_pool;
|
||||
}
|
||||
|
||||
/* Increment the created count. */
|
||||
_tx_block_pool_created_count++;
|
||||
|
||||
/* Optional block pool create extended processing. */
|
||||
TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
|
||||
/* If trace is enabled, register this object. */
|
||||
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_BLOCK_POOL, pool_ptr, name_ptr, pool_size, block_size)
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_CREATE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(pool_start), blocks, block_size, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_CREATE_INSERT
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return successful status. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enough memory for one block, return appropriate error. */
|
||||
status = TX_SIZE_ERROR;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_delete PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function deletes the specified block pool. All threads */
|
||||
/* suspended on the block pool are resumed with the TX_DELETED status */
|
||||
/* code. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_delete(TX_BLOCK_POOL *pool_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *next_thread;
|
||||
UINT suspended_count;
|
||||
TX_BLOCK_POOL *next_pool;
|
||||
TX_BLOCK_POOL *previous_pool;
|
||||
|
||||
|
||||
/* Disable interrupts to remove the block pool from the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_DELETE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_DELETE_INSERT
|
||||
|
||||
/* Optional block pool delete extended processing. */
|
||||
TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
|
||||
/* If trace is enabled, unregister this object. */
|
||||
TX_TRACE_OBJECT_UNREGISTER(pool_ptr)
|
||||
|
||||
/* Clear the block pool ID to make it invalid. */
|
||||
pool_ptr -> tx_block_pool_id = TX_CLEAR_ID;
|
||||
|
||||
/* Decrement the number of block pools. */
|
||||
_tx_block_pool_created_count--;
|
||||
|
||||
/* See if the block pool is the only one on the list. */
|
||||
if (_tx_block_pool_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* Only created block pool, just set the created list to NULL. */
|
||||
_tx_block_pool_created_ptr = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Link-up the neighbors. */
|
||||
next_pool = pool_ptr -> tx_block_pool_created_next;
|
||||
previous_pool = pool_ptr -> tx_block_pool_created_previous;
|
||||
next_pool -> tx_block_pool_created_previous = previous_pool;
|
||||
previous_pool -> tx_block_pool_created_next = next_pool;
|
||||
|
||||
/* See if we have to update the created list head pointer. */
|
||||
if (_tx_block_pool_created_ptr == pool_ptr)
|
||||
{
|
||||
|
||||
/* Yes, move the head pointer to the next link. */
|
||||
_tx_block_pool_created_ptr = next_pool;
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Pickup the suspension information. */
|
||||
thread_ptr = pool_ptr -> tx_block_pool_suspension_list;
|
||||
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
|
||||
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
|
||||
pool_ptr -> tx_block_pool_suspended_count = TX_NO_SUSPENSIONS;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Walk through the block pool suspension list to resume any and all threads suspended
|
||||
on this block pool. */
|
||||
while (suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
suspended_count--;
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Clear the cleanup pointer, this prevents the timeout from doing
|
||||
anything. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Set the return status in the thread to TX_DELETED. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
|
||||
|
||||
/* Move the thread pointer ahead. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption again. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
#endif
|
||||
|
||||
/* Move to next thread. */
|
||||
thread_ptr = next_thread;
|
||||
}
|
||||
|
||||
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
|
||||
TX_BLOCK_POOL_DELETE_PORT_COMPLETION(pool_ptr)
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Release previous preempt disable. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves information from the specified block pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to block pool control blk */
|
||||
/* name Destination for the pool name */
|
||||
/* available_blocks Number of free blocks in pool */
|
||||
/* total_blocks Total number of blocks in pool */
|
||||
/* first_suspended Destination for pointer of first */
|
||||
/* thread suspended on block pool */
|
||||
/* suspended_count Destination for suspended count */
|
||||
/* next_pool Destination for pointer to next */
|
||||
/* block pool on the created list */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
|
||||
ULONG *total_blocks, TX_THREAD **first_suspended,
|
||||
ULONG *suspended_count, TX_BLOCK_POOL **next_pool)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the name of the block pool. */
|
||||
if (name != TX_NULL)
|
||||
{
|
||||
|
||||
*name = pool_ptr -> tx_block_pool_name;
|
||||
}
|
||||
|
||||
/* Retrieve the number of available blocks in the block pool. */
|
||||
if (available_blocks != TX_NULL)
|
||||
{
|
||||
|
||||
*available_blocks = (ULONG) pool_ptr -> tx_block_pool_available;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of blocks in the block pool. */
|
||||
if (total_blocks != TX_NULL)
|
||||
{
|
||||
|
||||
*total_blocks = (ULONG) pool_ptr -> tx_block_pool_total;
|
||||
}
|
||||
|
||||
/* Retrieve the first thread suspended on this block pool. */
|
||||
if (first_suspended != TX_NULL)
|
||||
{
|
||||
|
||||
*first_suspended = pool_ptr -> tx_block_pool_suspension_list;
|
||||
}
|
||||
|
||||
/* Retrieve the number of threads suspended on this block pool. */
|
||||
if (suspended_count != TX_NULL)
|
||||
{
|
||||
|
||||
*suspended_count = (ULONG) pool_ptr -> tx_block_pool_suspended_count;
|
||||
}
|
||||
|
||||
/* Retrieve the pointer to the next block pool created. */
|
||||
if (next_pool != TX_NULL)
|
||||
{
|
||||
|
||||
*next_pool = pool_ptr -> tx_block_pool_created_next;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
#ifndef TX_INLINE_INITIALIZATION
|
||||
|
||||
/* Locate block pool component data in this file. */
|
||||
|
||||
/* Define the head pointer of the created block pool list. */
|
||||
|
||||
TX_BLOCK_POOL * _tx_block_pool_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created block pools. */
|
||||
|
||||
ULONG _tx_block_pool_created_count;
|
||||
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of block allocates. */
|
||||
|
||||
ULONG _tx_block_pool_performance_allocate_count;
|
||||
|
||||
|
||||
/* Define the total number of block releases. */
|
||||
|
||||
ULONG _tx_block_pool_performance_release_count;
|
||||
|
||||
|
||||
/* Define the total number of block pool suspensions. */
|
||||
|
||||
ULONG _tx_block_pool_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of block pool timeouts. */
|
||||
|
||||
ULONG _tx_block_pool_performance_timeout_count;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block pool_initialize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function initializes the various control data structures for */
|
||||
/* the block pool component. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_high_level High level initialization */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_block_pool_initialize(VOID)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_REDUNDANT_CLEARING
|
||||
|
||||
/* Initialize the head pointer of the created block pools list and the
|
||||
number of block pools created. */
|
||||
_tx_block_pool_created_ptr = TX_NULL;
|
||||
_tx_block_pool_created_count = TX_EMPTY;
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Initialize block pool performance counters. */
|
||||
_tx_block_pool_performance_allocate_count = ((ULONG) 0);
|
||||
_tx_block_pool_performance_release_count = ((ULONG) 0);
|
||||
_tx_block_pool_performance_suspension_count = ((ULONG) 0);
|
||||
_tx_block_pool_performance_timeout_count = ((ULONG) 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_block_pool.h"
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_performance_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves performance information from the specified */
|
||||
/* block pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to block pool control blk */
|
||||
/* allocates Destination for the number of */
|
||||
/* allocations from this pool */
|
||||
/* releases Destination for the number of */
|
||||
/* blocks released back to pool */
|
||||
/* suspensions Destination for number of */
|
||||
/* suspensions on this pool */
|
||||
/* timeouts Destination for number of timeouts*/
|
||||
/* on this pool */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_performance_info_get(TX_BLOCK_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
|
||||
ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine if this is a legal request. */
|
||||
if (pool_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Block pool pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
|
||||
/* Determine if the pool ID is invalid. */
|
||||
else if (pool_ptr -> tx_block_pool_id != TX_BLOCK_POOL_ID)
|
||||
{
|
||||
|
||||
/* Block pool pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_PERFORMANCE_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the number of allocations from this block pool. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
*allocates = pool_ptr -> tx_block_pool_performance_allocate_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of blocks released to this block pool. */
|
||||
if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
*releases = pool_ptr -> tx_block_pool_performance_release_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of thread suspensions on this block pool. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = pool_ptr -> tx_block_pool_performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of thread timeouts on this block pool. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = pool_ptr -> tx_block_pool_performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return successful completion. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
#else
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (pool_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_block_pool.h"
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_performance_system_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves block pool performance information. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* allocates Destination for the total number */
|
||||
/* of block allocations */
|
||||
/* releases Destination for the total number */
|
||||
/* of blocks released */
|
||||
/* suspensions Destination for the total number */
|
||||
/* of suspensions */
|
||||
/* timeouts Destination for total number of */
|
||||
/* timeouts */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the total number of block allocations. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
*allocates = _tx_block_pool_performance_allocate_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of blocks released. */
|
||||
if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
*releases = _tx_block_pool_performance_release_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of block pool thread suspensions. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = _tx_block_pool_performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of block pool thread timeouts. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = _tx_block_pool_performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
|
||||
#else
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_pool_prioritize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function places the highest priority suspended thread at the */
|
||||
/* front of the suspension list. All other threads remain in the same */
|
||||
/* FIFO suspension order. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *priority_thread_ptr;
|
||||
TX_THREAD *head_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
UINT list_changed;
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_PRIORITIZE, pool_ptr, pool_ptr -> tx_block_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&suspended_count), 0, TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_POOL_PRIORITIZE_INSERT
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
|
||||
|
||||
/* Determine if there are fewer than 2 suspended threads. */
|
||||
if (suspended_count < ((UINT) 2))
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
|
||||
/* Determine if there how many threads are suspended on this block memory pool. */
|
||||
else if (suspended_count == ((UINT) 2))
|
||||
{
|
||||
|
||||
/* Pickup the head pointer and the next pointer. */
|
||||
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
|
||||
next_thread = head_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Determine if the next suspended thread has a higher priority. */
|
||||
if ((next_thread -> tx_thread_priority) < (head_ptr -> tx_thread_priority))
|
||||
{
|
||||
|
||||
/* Yes, move the list head to the next thread. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = next_thread;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Remember the suspension count and head pointer. */
|
||||
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
|
||||
|
||||
/* Default the highest priority thread to the thread at the front of the list. */
|
||||
priority_thread_ptr = head_ptr;
|
||||
|
||||
/* Setup search pointer. */
|
||||
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Set the list changed flag to false. */
|
||||
list_changed = TX_FALSE;
|
||||
|
||||
/* Search through the list to find the highest priority thread. */
|
||||
do
|
||||
{
|
||||
|
||||
/* Is the current thread higher priority? */
|
||||
if (thread_ptr -> tx_thread_priority < priority_thread_ptr -> tx_thread_priority)
|
||||
{
|
||||
|
||||
/* Yes, remember that this thread is the highest priority. */
|
||||
priority_thread_ptr = thread_ptr;
|
||||
}
|
||||
|
||||
/* Restore interrupts temporarily. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Disable interrupts again. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if any changes to the list have occurred while
|
||||
interrupts were enabled. */
|
||||
|
||||
/* Is the list head the same? */
|
||||
if (head_ptr != pool_ptr -> tx_block_pool_suspension_list)
|
||||
{
|
||||
|
||||
/* The list head has changed, set the list changed flag. */
|
||||
list_changed = TX_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Is the suspended count the same? */
|
||||
if (suspended_count != pool_ptr -> tx_block_pool_suspended_count)
|
||||
{
|
||||
|
||||
/* The list head has changed, set the list changed flag. */
|
||||
list_changed = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if the list has changed. */
|
||||
if (list_changed == TX_FALSE)
|
||||
{
|
||||
|
||||
/* Move the thread pointer to the next thread. */
|
||||
thread_ptr = thread_ptr -> tx_thread_suspended_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Remember the suspension count and head pointer. */
|
||||
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
|
||||
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
|
||||
|
||||
/* Default the highest priority thread to the thread at the front of the list. */
|
||||
priority_thread_ptr = head_ptr;
|
||||
|
||||
/* Setup search pointer. */
|
||||
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Reset the list changed flag. */
|
||||
list_changed = TX_FALSE;
|
||||
}
|
||||
|
||||
} while (thread_ptr != head_ptr);
|
||||
|
||||
/* Release preemption. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Now determine if the highest priority thread is at the front
|
||||
of the list. */
|
||||
if (priority_thread_ptr != head_ptr)
|
||||
{
|
||||
|
||||
/* No, we need to move the highest priority suspended thread to the
|
||||
front of the list. */
|
||||
|
||||
/* First, remove the highest priority thread by updating the
|
||||
adjacent suspended threads. */
|
||||
next_thread = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = priority_thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Now, link the highest priority thread at the front of the list. */
|
||||
previous_thread = head_ptr -> tx_thread_suspended_previous;
|
||||
priority_thread_ptr -> tx_thread_suspended_next = head_ptr;
|
||||
priority_thread_ptr -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = priority_thread_ptr;
|
||||
head_ptr -> tx_thread_suspended_previous = priority_thread_ptr;
|
||||
|
||||
/* Move the list head pointer to the highest priority suspended thread. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = priority_thread_ptr;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
}
|
||||
|
||||
/* Return successful status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Block Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_block_release PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function returns a previously allocated block to its */
|
||||
/* associated memory block pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* block_ptr Pointer to memory block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_block_release(VOID *block_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_BLOCK_POOL *pool_ptr;
|
||||
TX_THREAD *thread_ptr;
|
||||
UCHAR *work_ptr;
|
||||
UCHAR **return_block_ptr;
|
||||
UCHAR **next_block_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
|
||||
|
||||
/* Disable interrupts to put this block back in the pool. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Pickup the pool pointer which is just previous to the starting
|
||||
address of the block that the caller sees. */
|
||||
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, (sizeof(UCHAR *)));
|
||||
next_block_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
|
||||
pool_ptr = TX_UCHAR_TO_BLOCK_POOL_POINTER_CONVERT((*next_block_ptr));
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total releases counter. */
|
||||
_tx_block_pool_performance_release_count++;
|
||||
|
||||
/* Increment the number of releases on this pool. */
|
||||
pool_ptr -> tx_block_pool_performance_release_count++;
|
||||
#endif
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_RELEASE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(block_ptr), pool_ptr -> tx_block_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&work_ptr), TX_TRACE_BLOCK_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BLOCK_RELEASE_INSERT
|
||||
|
||||
/* Determine if there are any threads suspended on the block pool. */
|
||||
thread_ptr = pool_ptr -> tx_block_pool_suspension_list;
|
||||
if (thread_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* Decrement the number of threads suspended. */
|
||||
(pool_ptr -> tx_block_pool_suspended_count)--;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = (pool_ptr -> tx_block_pool_suspended_count);
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same expiration list. */
|
||||
|
||||
/* Update the list head pointer. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
pool_ptr -> tx_block_pool_suspension_list = next_thread;
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
}
|
||||
|
||||
/* Prepare for resumption of the first thread. */
|
||||
|
||||
/* Clear cleanup routine to avoid timeout. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Return this block pointer to the suspended thread waiting for
|
||||
a block. */
|
||||
return_block_ptr = TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
|
||||
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*return_block_ptr = work_ptr;
|
||||
|
||||
/* Put return status into the thread control block. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* No thread is suspended for a memory block. */
|
||||
|
||||
/* Put the block back in the available list. */
|
||||
*next_block_ptr = pool_ptr -> tx_block_pool_available_list;
|
||||
|
||||
/* Adjust the head pointer. */
|
||||
pool_ptr -> tx_block_pool_available_list = work_ptr;
|
||||
|
||||
/* Increment the count of available blocks. */
|
||||
pool_ptr -> tx_block_pool_available++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
|
||||
/* Return successful completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_allocate PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function allocates bytes from the specified memory byte */
|
||||
/* pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* memory_ptr Pointer to place allocated bytes */
|
||||
/* pointer */
|
||||
/* memory_size Number of bytes to allocate */
|
||||
/* wait_option Suspension option */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_suspend Suspend thread service */
|
||||
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
|
||||
/* _tx_byte_pool_search Search byte pool for memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, ULONG wait_option)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT status;
|
||||
TX_THREAD *thread_ptr;
|
||||
UCHAR *work_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
UINT finished;
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
TX_TRACE_BUFFER_ENTRY *entry_ptr;
|
||||
ULONG time_stamp = ((ULONG) 0);
|
||||
#endif
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
UCHAR *log_entry_ptr;
|
||||
ULONG upper_tbu;
|
||||
ULONG lower_tbu;
|
||||
#endif
|
||||
|
||||
|
||||
/* Round the memory size up to the next size that is evenly divisible by
|
||||
an ALIGN_TYPE (this is typically a 32-bit ULONG). This guarantees proper alignment. */
|
||||
memory_size = (((memory_size + (sizeof(ALIGN_TYPE)))-((ALIGN_TYPE) 1))/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Pickup thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr)
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total allocations counter. */
|
||||
_tx_byte_pool_performance_allocate_count++;
|
||||
|
||||
/* Increment the number of allocations on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_allocate_count++;
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* If trace is enabled, save the current event pointer. */
|
||||
entry_ptr = _tx_trace_buffer_current_ptr;
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_ALLOCATE, pool_ptr, 0, memory_size, wait_option, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Save the time stamp for later comparison to verify that
|
||||
the event hasn't been overwritten by the time the allocate
|
||||
call succeeds. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
time_stamp = entry_ptr -> tx_trace_buffer_entry_time_stamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
log_entry_ptr = *(UCHAR **) _tx_el_current_event;
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_ALLOCATE_INSERT
|
||||
|
||||
/* Store -1 in the fourth event slot. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) -1;
|
||||
|
||||
/* Save the time stamp for later comparison to verify that
|
||||
the event hasn't been overwritten by the time the allocate
|
||||
call succeeds. */
|
||||
lower_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET));
|
||||
upper_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET));
|
||||
#endif
|
||||
|
||||
/* Set the search finished flag to false. */
|
||||
finished = TX_FALSE;
|
||||
|
||||
/* Loop to handle cases where the owner of the pool changed. */
|
||||
do
|
||||
{
|
||||
|
||||
/* Indicate that this thread is the current owner. */
|
||||
pool_ptr -> tx_byte_pool_owner = thread_ptr;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* At this point, the executing thread owns the pool and can perform a search
|
||||
for free memory. */
|
||||
work_ptr = _tx_byte_pool_search(pool_ptr, memory_size);
|
||||
|
||||
/* Optional processing extension. */
|
||||
TX_BYTE_ALLOCATE_EXTENSION
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if we are finished. */
|
||||
if (work_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Yes, we have found a block the search is finished. */
|
||||
finished = TX_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* No block was found, does this thread still own the pool? */
|
||||
if (pool_ptr -> tx_byte_pool_owner == thread_ptr)
|
||||
{
|
||||
|
||||
/* Yes, then we have looked through the entire pool and haven't found the memory. */
|
||||
finished = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
} while (finished == TX_FALSE);
|
||||
|
||||
/* Copy the pointer into the return destination. */
|
||||
*memory_ptr = (VOID *) work_ptr;
|
||||
|
||||
/* Determine if memory was found. */
|
||||
if (work_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Is the timestamp the same? */
|
||||
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
|
||||
{
|
||||
|
||||
/* Timestamp is the same, update the entry with the address. */
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
|
||||
#else
|
||||
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
|
||||
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)))
|
||||
{
|
||||
/* Store the address of the allocated fragment. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) *memory_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Set the status to success. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* No memory of sufficient size was found... */
|
||||
|
||||
/* Determine if the request specifies suspension. */
|
||||
if (wait_option != TX_NO_WAIT)
|
||||
{
|
||||
|
||||
/* Determine if the preempt disable flag is non-zero. */
|
||||
if (_tx_thread_preempt_disable != ((UINT) 0))
|
||||
{
|
||||
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point - return error completion. */
|
||||
status = TX_NO_MEMORY;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Prepare for suspension of this thread. */
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total suspensions counter. */
|
||||
_tx_byte_pool_performance_suspension_count++;
|
||||
|
||||
/* Increment the number of suspensions on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_suspension_count++;
|
||||
#endif
|
||||
|
||||
/* Setup cleanup routine pointer. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
|
||||
|
||||
/* Setup cleanup information, i.e. this pool control
|
||||
block. */
|
||||
thread_ptr -> tx_thread_suspend_control_block = (VOID *) pool_ptr;
|
||||
|
||||
/* Save the return memory pointer address as well. */
|
||||
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) memory_ptr;
|
||||
|
||||
/* Save the byte size requested. */
|
||||
thread_ptr -> tx_thread_suspend_info = memory_size;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Increment the suspension sequence number, which is used to identify
|
||||
this suspension event. */
|
||||
thread_ptr -> tx_thread_suspension_sequence++;
|
||||
#endif
|
||||
|
||||
/* Pickup the number of suspended threads. */
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
|
||||
/* Increment the suspension count. */
|
||||
(pool_ptr -> tx_byte_pool_suspended_count)++;
|
||||
|
||||
/* Setup suspension list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* No other threads are suspended. Setup the head pointer and
|
||||
just setup this threads pointers to itself. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_next = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add current thread to the end. */
|
||||
next_thread = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
thread_ptr -> tx_thread_suspended_next = next_thread;
|
||||
previous_thread = next_thread -> tx_thread_suspended_previous;
|
||||
thread_ptr -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = thread_ptr;
|
||||
next_thread -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
|
||||
/* Set the state to suspended. */
|
||||
thread_ptr -> tx_thread_state = TX_BYTE_MEMORY;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Call actual non-interruptable thread suspension routine. */
|
||||
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Set the suspending flag. */
|
||||
thread_ptr -> tx_thread_suspending = TX_TRUE;
|
||||
|
||||
/* Setup the timeout period. */
|
||||
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Call actual thread suspension routine. */
|
||||
_tx_thread_system_suspend(thread_ptr);
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_TRACE
|
||||
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (entry_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Is the timestamp the same? */
|
||||
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
|
||||
{
|
||||
|
||||
/* Timestamp is the same, update the entry with the address. */
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
|
||||
#else
|
||||
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EVENT_LOGGING
|
||||
/* Check that the event time stamp is unchanged. A different
|
||||
timestamp means that a later event wrote over the byte
|
||||
allocate event. In that case, do nothing here. */
|
||||
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
|
||||
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)))
|
||||
{
|
||||
|
||||
/* Store the address of the allocated fragment. */
|
||||
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) *memory_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the completion status. */
|
||||
status = thread_ptr -> tx_thread_suspend_status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Immediate return, return error completion. */
|
||||
status = TX_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_cleanup PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes byte allocate timeout and thread terminate */
|
||||
/* actions that require the byte pool data structures to be cleaned */
|
||||
/* up. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to suspended thread's */
|
||||
/* control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_timeout Thread timeout processing */
|
||||
/* _tx_thread_terminate Thread terminate processing */
|
||||
/* _tx_thread_wait_abort Thread wait abort processing */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_byte_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
#endif
|
||||
|
||||
TX_BYTE_POOL *pool_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Disable interrupts to remove the suspended thread from the byte pool. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if the cleanup is still required. */
|
||||
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_byte_pool_cleanup))
|
||||
{
|
||||
|
||||
/* Check for valid suspension sequence. */
|
||||
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
|
||||
{
|
||||
|
||||
/* Setup pointer to byte pool control block. */
|
||||
pool_ptr = TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
|
||||
/* Check for a NULL byte pool pointer. */
|
||||
if (pool_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Check for valid pool ID. */
|
||||
if (pool_ptr -> tx_byte_pool_id == TX_BYTE_POOL_ID)
|
||||
{
|
||||
|
||||
/* Determine if there are any thread suspensions. */
|
||||
if (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
#else
|
||||
|
||||
/* Setup pointer to byte pool control block. */
|
||||
pool_ptr = TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
#endif
|
||||
|
||||
/* Thread suspended for memory... Clear the suspension cleanup flag. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
pool_ptr -> tx_byte_pool_suspended_count--;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same suspension list. */
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Determine if we need to update the head pointer. */
|
||||
if (pool_ptr -> tx_byte_pool_suspension_list == thread_ptr)
|
||||
{
|
||||
|
||||
/* Update the list head pointer. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we need to determine if this cleanup is from a terminate, timeout,
|
||||
or from a wait abort. */
|
||||
if (thread_ptr -> tx_thread_state == TX_BYTE_MEMORY)
|
||||
{
|
||||
|
||||
/* Timeout condition and the thread still suspended on the byte pool.
|
||||
Setup return error status and resume the thread. */
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total timeouts counter. */
|
||||
_tx_byte_pool_performance_timeout_count++;
|
||||
|
||||
/* Increment the number of timeouts on this byte pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_timeout_count++;
|
||||
#endif
|
||||
|
||||
/* Setup return status. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_NO_MEMORY;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
}
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_create PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function creates a pool of memory bytes in the specified */
|
||||
/* memory area. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* name_ptr Pointer to byte pool name */
|
||||
/* pool_start Address of beginning of pool area */
|
||||
/* pool_size Number of bytes in the byte pool */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, ULONG pool_size)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UCHAR *block_ptr;
|
||||
UCHAR **block_indirect_ptr;
|
||||
UCHAR *temp_ptr;
|
||||
TX_BYTE_POOL *next_pool;
|
||||
TX_BYTE_POOL *previous_pool;
|
||||
ALIGN_TYPE *free_ptr;
|
||||
|
||||
|
||||
/* Initialize the byte pool control block to all zeros. */
|
||||
TX_MEMSET(pool_ptr, 0, (sizeof(TX_BYTE_POOL)));
|
||||
|
||||
/* Round the pool size down to something that is evenly divisible by
|
||||
an ULONG. */
|
||||
pool_size = (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
|
||||
|
||||
/* Setup the basic byte pool fields. */
|
||||
pool_ptr -> tx_byte_pool_name = name_ptr;
|
||||
|
||||
/* Save the start and size of the pool. */
|
||||
pool_ptr -> tx_byte_pool_start = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
pool_ptr -> tx_byte_pool_size = pool_size;
|
||||
|
||||
/* Setup memory list to the beginning as well as the search pointer. */
|
||||
pool_ptr -> tx_byte_pool_list = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
pool_ptr -> tx_byte_pool_search = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
|
||||
/* Initially, the pool will have two blocks. One large block at the
|
||||
beginning that is available and a small allocated block at the end
|
||||
of the pool that is there just for the algorithm. Be sure to count
|
||||
the available block's header in the available bytes count. */
|
||||
pool_ptr -> tx_byte_pool_available = pool_size - ((sizeof(VOID *)) + (sizeof(ALIGN_TYPE)));
|
||||
pool_ptr -> tx_byte_pool_fragments = ((UINT) 2);
|
||||
|
||||
/* Each block contains a "next" pointer that points to the next block in the pool followed by a ALIGN_TYPE
|
||||
field that contains either the constant TX_BYTE_BLOCK_FREE (if the block is free) or a pointer to the
|
||||
owning pool (if the block is allocated). */
|
||||
|
||||
/* Calculate the end of the pool's memory area. */
|
||||
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, pool_size);
|
||||
|
||||
/* Backup the end of the pool pointer and build the pre-allocated block. */
|
||||
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(ALIGN_TYPE)));
|
||||
|
||||
/* Cast the pool pointer into a ULONG. */
|
||||
temp_ptr = TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
|
||||
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*block_indirect_ptr = temp_ptr;
|
||||
|
||||
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(UCHAR *)));
|
||||
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
|
||||
*block_indirect_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
|
||||
/* Now setup the large available block in the pool. */
|
||||
temp_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(temp_ptr);
|
||||
*block_indirect_ptr = block_ptr;
|
||||
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
|
||||
block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(block_ptr);
|
||||
*free_ptr = TX_BYTE_BLOCK_FREE;
|
||||
|
||||
/* Clear the owner id. */
|
||||
pool_ptr -> tx_byte_pool_owner = TX_NULL;
|
||||
|
||||
/* Disable interrupts to place the byte pool on the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Setup the byte pool ID to make it valid. */
|
||||
pool_ptr -> tx_byte_pool_id = TX_BYTE_POOL_ID;
|
||||
|
||||
/* Place the byte pool on the list of created byte pools. First,
|
||||
check for an empty list. */
|
||||
if (_tx_byte_pool_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* The created byte pool list is empty. Add byte pool to empty list. */
|
||||
_tx_byte_pool_created_ptr = pool_ptr;
|
||||
pool_ptr -> tx_byte_pool_created_next = pool_ptr;
|
||||
pool_ptr -> tx_byte_pool_created_previous = pool_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add to the end of the list. */
|
||||
next_pool = _tx_byte_pool_created_ptr;
|
||||
previous_pool = next_pool -> tx_byte_pool_created_previous;
|
||||
|
||||
/* Place the new byte pool in the list. */
|
||||
next_pool -> tx_byte_pool_created_previous = pool_ptr;
|
||||
previous_pool -> tx_byte_pool_created_next = pool_ptr;
|
||||
|
||||
/* Setup this byte pool's created links. */
|
||||
pool_ptr -> tx_byte_pool_created_previous = previous_pool;
|
||||
pool_ptr -> tx_byte_pool_created_next = next_pool;
|
||||
}
|
||||
|
||||
/* Increment the number of created byte pools. */
|
||||
_tx_byte_pool_created_count++;
|
||||
|
||||
/* Optional byte pool create extended processing. */
|
||||
TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
|
||||
/* If trace is enabled, register this object. */
|
||||
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_BYTE_POOL, pool_ptr, name_ptr, pool_size, 0)
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_CREATE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(pool_start), pool_size, TX_POINTER_TO_ULONG_CONVERT(&block_ptr), TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_CREATE_INSERT
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_delete PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function deletes the specified byte pool. All threads */
|
||||
/* suspended on the byte pool are resumed with the TX_DELETED status */
|
||||
/* code. */
|
||||
/* */
|
||||
/* It is important to note that the byte pool being deleted, or the */
|
||||
/* memory associated with it should not be in use when this function */
|
||||
/* is called. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_delete(TX_BYTE_POOL *pool_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *next_thread;
|
||||
UINT suspended_count;
|
||||
TX_BYTE_POOL *next_pool;
|
||||
TX_BYTE_POOL *previous_pool;
|
||||
|
||||
|
||||
/* Disable interrupts to remove the byte pool from the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_DELETE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Optional byte pool delete extended processing. */
|
||||
TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
|
||||
/* If trace is enabled, unregister this object. */
|
||||
TX_TRACE_OBJECT_UNREGISTER(pool_ptr)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_DELETE_INSERT
|
||||
|
||||
/* Clear the byte pool ID to make it invalid. */
|
||||
pool_ptr -> tx_byte_pool_id = TX_CLEAR_ID;
|
||||
|
||||
/* Decrement the number of byte pools created. */
|
||||
_tx_byte_pool_created_count--;
|
||||
|
||||
/* See if the byte pool is the only one on the list. */
|
||||
if (_tx_byte_pool_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* Only created byte pool, just set the created list to NULL. */
|
||||
_tx_byte_pool_created_ptr = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Link-up the neighbors. */
|
||||
next_pool = pool_ptr -> tx_byte_pool_created_next;
|
||||
previous_pool = pool_ptr -> tx_byte_pool_created_previous;
|
||||
next_pool -> tx_byte_pool_created_previous = previous_pool;
|
||||
previous_pool -> tx_byte_pool_created_next = next_pool;
|
||||
|
||||
/* See if we have to update the created list head pointer. */
|
||||
if (_tx_byte_pool_created_ptr == pool_ptr)
|
||||
{
|
||||
|
||||
/* Yes, move the head pointer to the next link. */
|
||||
_tx_byte_pool_created_ptr = next_pool;
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Pickup the suspension information. */
|
||||
thread_ptr = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
pool_ptr -> tx_byte_pool_suspended_count = TX_NO_SUSPENSIONS;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Walk through the byte pool list to resume any and all threads suspended
|
||||
on this byte pool. */
|
||||
while (suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
suspended_count--;
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Clear the cleanup pointer, this prevents the timeout from doing
|
||||
anything. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Set the return status in the thread to TX_DELETED. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
|
||||
|
||||
/* Move the thread pointer ahead. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption again. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
#endif
|
||||
|
||||
/* Move to next thread. */
|
||||
thread_ptr = next_thread;
|
||||
}
|
||||
|
||||
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
|
||||
TX_BYTE_POOL_DELETE_PORT_COMPLETION(pool_ptr)
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Release previous preempt disable. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves information from the specified byte pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to byte pool control block*/
|
||||
/* name Destination for the pool name */
|
||||
/* available_bytes Number of free bytes in byte pool */
|
||||
/* fragments Number of fragments in byte pool */
|
||||
/* first_suspended Destination for pointer of first */
|
||||
/* thread suspended on byte pool */
|
||||
/* suspended_count Destination for suspended count */
|
||||
/* next_pool Destination for pointer to next */
|
||||
/* byte pool on the created list */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes,
|
||||
ULONG *fragments, TX_THREAD **first_suspended,
|
||||
ULONG *suspended_count, TX_BYTE_POOL **next_pool)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the name of the byte pool. */
|
||||
if (name != TX_NULL)
|
||||
{
|
||||
|
||||
*name = pool_ptr -> tx_byte_pool_name;
|
||||
}
|
||||
|
||||
/* Retrieve the number of available bytes in the byte pool. */
|
||||
if (available_bytes != TX_NULL)
|
||||
{
|
||||
|
||||
*available_bytes = pool_ptr -> tx_byte_pool_available;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of bytes in the byte pool. */
|
||||
if (fragments != TX_NULL)
|
||||
{
|
||||
|
||||
*fragments = (ULONG) pool_ptr -> tx_byte_pool_fragments;
|
||||
}
|
||||
|
||||
/* Retrieve the first thread suspended on this byte pool. */
|
||||
if (first_suspended != TX_NULL)
|
||||
{
|
||||
|
||||
*first_suspended = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
}
|
||||
|
||||
/* Retrieve the number of threads suspended on this byte pool. */
|
||||
if (suspended_count != TX_NULL)
|
||||
{
|
||||
|
||||
*suspended_count = (ULONG) pool_ptr -> tx_byte_pool_suspended_count;
|
||||
}
|
||||
|
||||
/* Retrieve the pointer to the next byte pool created. */
|
||||
if (next_pool != TX_NULL)
|
||||
{
|
||||
|
||||
*next_pool = pool_ptr -> tx_byte_pool_created_next;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
#ifndef TX_INLINE_INITIALIZATION
|
||||
|
||||
/* Locate byte pool component data in this file. */
|
||||
|
||||
/* Define the head pointer of the created byte pool list. */
|
||||
|
||||
TX_BYTE_POOL * _tx_byte_pool_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created byte pools. */
|
||||
|
||||
ULONG _tx_byte_pool_created_count;
|
||||
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of allocates. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_allocate_count;
|
||||
|
||||
|
||||
/* Define the total number of releases. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_release_count;
|
||||
|
||||
|
||||
/* Define the total number of adjacent memory fragment merges. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_merge_count;
|
||||
|
||||
|
||||
/* Define the total number of memory fragment splits. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_split_count;
|
||||
|
||||
|
||||
/* Define the total number of memory fragments searched during allocation. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_search_count;
|
||||
|
||||
|
||||
/* Define the total number of byte pool suspensions. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of byte pool timeouts. */
|
||||
|
||||
ULONG _tx_byte_pool_performance_timeout_count;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_initialize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function initializes the various control data structures for */
|
||||
/* the byte pool component. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_high_level High level initialization */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_byte_pool_initialize(VOID)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_REDUNDANT_CLEARING
|
||||
|
||||
/* Initialize the head pointer of the created byte pools list and the
|
||||
number of byte pools created. */
|
||||
_tx_byte_pool_created_ptr = TX_NULL;
|
||||
_tx_byte_pool_created_count = TX_EMPTY;
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Initialize byte pool performance counters. */
|
||||
_tx_byte_pool_performance_allocate_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_release_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_merge_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_split_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_search_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_suspension_count = ((ULONG) 0);
|
||||
_tx_byte_pool_performance_timeout_count = ((ULONG) 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_byte_pool.h"
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_performance_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves performance information from the specified */
|
||||
/* byte pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to byte pool control block*/
|
||||
/* allocates Destination for number of */
|
||||
/* allocates on this pool */
|
||||
/* releases Destination for number of */
|
||||
/* releases on this pool */
|
||||
/* fragments_searched Destination for number of */
|
||||
/* fragments searched during */
|
||||
/* allocation */
|
||||
/* merges Destination for number of adjacent*/
|
||||
/* free fragments merged */
|
||||
/* splits Destination for number of */
|
||||
/* fragments split during */
|
||||
/* allocation */
|
||||
/* suspensions Destination for number of */
|
||||
/* suspensions on this pool */
|
||||
/* timeouts Destination for number of timeouts*/
|
||||
/* on this byte pool */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
|
||||
ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine if this is a legal request. */
|
||||
if (pool_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Byte pool pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
|
||||
/* Determine if the pool ID is invalid. */
|
||||
else if (pool_ptr -> tx_byte_pool_id != TX_BYTE_POOL_ID)
|
||||
{
|
||||
|
||||
/* Byte pool pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_PERFORMANCE_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the number of allocates on this byte pool. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
*allocates = pool_ptr -> tx_byte_pool_performance_allocate_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of releases on this byte pool. */
|
||||
if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
*releases = pool_ptr -> tx_byte_pool_performance_release_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of fragments searched in this byte pool. */
|
||||
if (fragments_searched != TX_NULL)
|
||||
{
|
||||
|
||||
*fragments_searched = pool_ptr -> tx_byte_pool_performance_search_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of fragments merged on this byte pool. */
|
||||
if (merges != TX_NULL)
|
||||
{
|
||||
|
||||
*merges = pool_ptr -> tx_byte_pool_performance_merge_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of fragment splits on this byte pool. */
|
||||
if (splits != TX_NULL)
|
||||
{
|
||||
|
||||
*splits = pool_ptr -> tx_byte_pool_performance_split_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of suspensions on this byte pool. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = pool_ptr -> tx_byte_pool_performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of timeouts on this byte pool. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = pool_ptr -> tx_byte_pool_performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
#else
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (pool_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (fragments_searched != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (merges != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (splits != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_byte_pool.h"
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_performance_system_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves byte pool performance information. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* allocates Destination for total number of */
|
||||
/* allocates */
|
||||
/* releases Destination for total number of */
|
||||
/* releases */
|
||||
/* fragments_searched Destination for total number of */
|
||||
/* fragments searched during */
|
||||
/* allocation */
|
||||
/* merges Destination for total number of */
|
||||
/* adjacent free fragments merged */
|
||||
/* splits Destination for total number of */
|
||||
/* fragments split during */
|
||||
/* allocation */
|
||||
/* suspensions Destination for total number of */
|
||||
/* suspensions */
|
||||
/* timeouts Destination for total number of */
|
||||
/* timeouts */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_performance_system_info_get(ULONG *allocates, ULONG *releases,
|
||||
ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the total number of byte pool allocates. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
*allocates = _tx_byte_pool_performance_allocate_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool releases. */
|
||||
if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
*releases = _tx_byte_pool_performance_release_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool fragments searched. */
|
||||
if (fragments_searched != TX_NULL)
|
||||
{
|
||||
|
||||
*fragments_searched = _tx_byte_pool_performance_search_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool fragments merged. */
|
||||
if (merges != TX_NULL)
|
||||
{
|
||||
|
||||
*merges = _tx_byte_pool_performance_merge_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool fragment splits. */
|
||||
if (splits != TX_NULL)
|
||||
{
|
||||
|
||||
*splits = _tx_byte_pool_performance_split_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool suspensions. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = _tx_byte_pool_performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of byte pool timeouts. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = _tx_byte_pool_performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
|
||||
#else
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (allocates != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (releases != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (fragments_searched != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (merges != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (splits != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_prioritize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function places the highest priority suspended thread at the */
|
||||
/* front of the suspension list. All other threads remain in the same */
|
||||
/* FIFO suspension order. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *priority_thread_ptr;
|
||||
TX_THREAD *head_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
UINT list_changed;
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_PRIORITIZE, pool_ptr, pool_ptr -> tx_byte_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&suspended_count), 0, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_POOL_PRIORITIZE_INSERT
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
|
||||
/* Determine if there are fewer than 2 suspended threads. */
|
||||
if (suspended_count < ((UINT) 2))
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
|
||||
/* Determine if there how many threads are suspended on this byte memory pool. */
|
||||
else if (suspended_count == ((UINT) 2))
|
||||
{
|
||||
|
||||
/* Pickup the head pointer and the next pointer. */
|
||||
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
next_thread = head_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Determine if the next suspended thread has a higher priority. */
|
||||
if ((next_thread -> tx_thread_priority) < (head_ptr -> tx_thread_priority))
|
||||
{
|
||||
|
||||
/* Yes, move the list head to the next thread. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Remember the suspension count and head pointer. */
|
||||
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
|
||||
/* Default the highest priority thread to the thread at the front of the list. */
|
||||
priority_thread_ptr = head_ptr;
|
||||
|
||||
/* Setup search pointer. */
|
||||
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Set the list changed flag to false. */
|
||||
list_changed = TX_FALSE;
|
||||
|
||||
/* Search through the list to find the highest priority thread. */
|
||||
do
|
||||
{
|
||||
|
||||
/* Is the current thread higher priority? */
|
||||
if (thread_ptr -> tx_thread_priority < priority_thread_ptr -> tx_thread_priority)
|
||||
{
|
||||
|
||||
/* Yes, remember that this thread is the highest priority. */
|
||||
priority_thread_ptr = thread_ptr;
|
||||
}
|
||||
|
||||
/* Restore interrupts temporarily. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Disable interrupts again. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if any changes to the list have occurred while
|
||||
interrupts were enabled. */
|
||||
|
||||
/* Is the list head the same? */
|
||||
if (head_ptr != pool_ptr -> tx_byte_pool_suspension_list)
|
||||
{
|
||||
|
||||
/* The list head has changed, set the list changed flag. */
|
||||
list_changed = TX_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Is the suspended count the same? */
|
||||
if (suspended_count != pool_ptr -> tx_byte_pool_suspended_count)
|
||||
{
|
||||
|
||||
/* The list head has changed, set the list changed flag. */
|
||||
list_changed = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if the list has changed. */
|
||||
if (list_changed == TX_FALSE)
|
||||
{
|
||||
|
||||
/* Move the thread pointer to the next thread. */
|
||||
thread_ptr = thread_ptr -> tx_thread_suspended_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Remember the suspension count and head pointer. */
|
||||
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
|
||||
/* Default the highest priority thread to the thread at the front of the list. */
|
||||
priority_thread_ptr = head_ptr;
|
||||
|
||||
/* Setup search pointer. */
|
||||
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Reset the list changed flag. */
|
||||
list_changed = TX_FALSE;
|
||||
}
|
||||
|
||||
} while (thread_ptr != head_ptr);
|
||||
|
||||
/* Release preemption. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Now determine if the highest priority thread is at the front
|
||||
of the list. */
|
||||
if (priority_thread_ptr != head_ptr)
|
||||
{
|
||||
|
||||
/* No, we need to move the highest priority suspended thread to the
|
||||
front of the list. */
|
||||
|
||||
/* First, remove the highest priority thread by updating the
|
||||
adjacent suspended threads. */
|
||||
next_thread = priority_thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = priority_thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Now, link the highest priority thread at the front of the list. */
|
||||
previous_thread = head_ptr -> tx_thread_suspended_previous;
|
||||
priority_thread_ptr -> tx_thread_suspended_next = head_ptr;
|
||||
priority_thread_ptr -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = priority_thread_ptr;
|
||||
head_ptr -> tx_thread_suspended_previous = priority_thread_ptr;
|
||||
|
||||
/* Move the list head pointer to the highest priority suspended thread. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = priority_thread_ptr;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Pool */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_pool_search PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function searches a byte pool for a memory block to satisfy */
|
||||
/* the requested number of bytes. Merging of adjacent free blocks */
|
||||
/* takes place during the search and a split of the block that */
|
||||
/* satisfies the request may occur before this function returns. */
|
||||
/* */
|
||||
/* It is assumed that this function is called with interrupts enabled */
|
||||
/* and with the tx_pool_owner field set to the thread performing the */
|
||||
/* search. Also note that the search can occur during allocation and */
|
||||
/* release of a memory block. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pool_ptr Pointer to pool control block */
|
||||
/* memory_size Number of bytes required */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* UCHAR * Pointer to the allocated memory, */
|
||||
/* if successful. Otherwise, a */
|
||||
/* NULL is returned */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_byte_allocate Allocate bytes of memory */
|
||||
/* _tx_byte_release Release bytes of memory */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UCHAR *current_ptr;
|
||||
UCHAR *next_ptr;
|
||||
UCHAR **this_block_link_ptr;
|
||||
UCHAR **next_block_link_ptr;
|
||||
ULONG available_bytes;
|
||||
UINT examine_blocks;
|
||||
UINT first_free_block_found = TX_FALSE;
|
||||
TX_THREAD *thread_ptr;
|
||||
ALIGN_TYPE *free_ptr;
|
||||
UCHAR *work_ptr;
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* First, determine if there are enough bytes in the pool. */
|
||||
if (memory_size >= pool_ptr -> tx_byte_pool_available)
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Not enough memory, return a NULL pointer. */
|
||||
current_ptr = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Pickup thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr)
|
||||
|
||||
/* Setup ownership of the byte pool. */
|
||||
pool_ptr -> tx_byte_pool_owner = thread_ptr;
|
||||
|
||||
/* Walk through the memory pool in search for a large enough block. */
|
||||
current_ptr = pool_ptr -> tx_byte_pool_search;
|
||||
examine_blocks = pool_ptr -> tx_byte_pool_fragments + ((UINT) 1);
|
||||
available_bytes = ((ULONG) 0);
|
||||
do
|
||||
{
|
||||
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total fragment search counter. */
|
||||
_tx_byte_pool_performance_search_count++;
|
||||
|
||||
/* Increment the number of fragments searched on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_search_count++;
|
||||
#endif
|
||||
|
||||
/* Check to see if this block is free. */
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
|
||||
if ((*free_ptr) == TX_BYTE_BLOCK_FREE)
|
||||
{
|
||||
|
||||
/* Determine if this is the first free block. */
|
||||
if (first_free_block_found == TX_FALSE)
|
||||
{
|
||||
|
||||
/* This is the first free block. */
|
||||
pool_ptr->tx_byte_pool_search = current_ptr;
|
||||
|
||||
/* Set the flag to indicate we have found the first free
|
||||
block. */
|
||||
first_free_block_found = TX_TRUE;
|
||||
}
|
||||
|
||||
/* Block is free, see if it is large enough. */
|
||||
|
||||
/* Pickup the next block's pointer. */
|
||||
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
|
||||
next_ptr = *this_block_link_ptr;
|
||||
|
||||
/* Calculate the number of bytes available in this block. */
|
||||
available_bytes = TX_UCHAR_POINTER_DIF(next_ptr, current_ptr);
|
||||
available_bytes = available_bytes - ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)));
|
||||
|
||||
/* If this is large enough, we are done because our first-fit algorithm
|
||||
has been satisfied! */
|
||||
if (available_bytes >= memory_size)
|
||||
{
|
||||
/* Get out of the search loop! */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Clear the available bytes variable. */
|
||||
available_bytes = ((ULONG) 0);
|
||||
|
||||
/* Not enough memory, check to see if the neighbor is
|
||||
free and can be merged. */
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
|
||||
if ((*free_ptr) == TX_BYTE_BLOCK_FREE)
|
||||
{
|
||||
|
||||
/* Yes, neighbor block can be merged! This is quickly accomplished
|
||||
by updating the current block with the next blocks pointer. */
|
||||
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
|
||||
*this_block_link_ptr = *next_block_link_ptr;
|
||||
|
||||
/* Reduce the fragment total. We don't need to increase the bytes
|
||||
available because all free headers are also included in the available
|
||||
count. */
|
||||
pool_ptr -> tx_byte_pool_fragments--;
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total merge counter. */
|
||||
_tx_byte_pool_performance_merge_count++;
|
||||
|
||||
/* Increment the number of blocks merged on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_merge_count++;
|
||||
#endif
|
||||
|
||||
/* See if the search pointer is affected. */
|
||||
if (pool_ptr -> tx_byte_pool_search == next_ptr)
|
||||
{
|
||||
|
||||
/* Yes, update the search pointer. */
|
||||
pool_ptr -> tx_byte_pool_search = current_ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Neighbor is not free so we can skip over it! */
|
||||
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
|
||||
current_ptr = *next_block_link_ptr;
|
||||
|
||||
/* Decrement the examined block count to account for this one. */
|
||||
if (examine_blocks != ((UINT) 0))
|
||||
{
|
||||
|
||||
examine_blocks--;
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total fragment search counter. */
|
||||
_tx_byte_pool_performance_search_count++;
|
||||
|
||||
/* Increment the number of fragments searched on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_search_count++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Block is not free, move to next block. */
|
||||
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
|
||||
current_ptr = *this_block_link_ptr;
|
||||
}
|
||||
|
||||
/* Another block has been searched... decrement counter. */
|
||||
if (examine_blocks != ((UINT) 0))
|
||||
{
|
||||
|
||||
examine_blocks--;
|
||||
}
|
||||
|
||||
/* Restore interrupts temporarily. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if anything has changed in terms of pool ownership. */
|
||||
if (pool_ptr -> tx_byte_pool_owner != thread_ptr)
|
||||
{
|
||||
|
||||
/* Pool changed ownership in the brief period interrupts were
|
||||
enabled. Reset the search. */
|
||||
current_ptr = pool_ptr -> tx_byte_pool_search;
|
||||
examine_blocks = pool_ptr -> tx_byte_pool_fragments + ((UINT) 1);
|
||||
|
||||
/* Setup our ownership again. */
|
||||
pool_ptr -> tx_byte_pool_owner = thread_ptr;
|
||||
}
|
||||
} while(examine_blocks != ((UINT) 0));
|
||||
|
||||
/* Determine if a block was found. If so, determine if it needs to be
|
||||
split. */
|
||||
if (available_bytes != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Determine if we need to split this block. */
|
||||
if ((available_bytes - memory_size) >= ((ULONG) TX_BYTE_BLOCK_MIN))
|
||||
{
|
||||
|
||||
/* Split the block. */
|
||||
next_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (memory_size + ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
|
||||
|
||||
/* Setup the new free block. */
|
||||
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
|
||||
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
|
||||
*next_block_link_ptr = *this_block_link_ptr;
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
|
||||
*free_ptr = TX_BYTE_BLOCK_FREE;
|
||||
|
||||
/* Increase the total fragment counter. */
|
||||
pool_ptr -> tx_byte_pool_fragments++;
|
||||
|
||||
/* Update the current pointer to point at the newly created block. */
|
||||
*this_block_link_ptr = next_ptr;
|
||||
|
||||
/* Set available equal to memory size for subsequent calculation. */
|
||||
available_bytes = memory_size;
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total split counter. */
|
||||
_tx_byte_pool_performance_split_count++;
|
||||
|
||||
/* Increment the number of blocks split on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_split_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* In any case, mark the current block as allocated. */
|
||||
work_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (sizeof(UCHAR *)));
|
||||
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
|
||||
*this_block_link_ptr = TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
|
||||
|
||||
/* Reduce the number of available bytes in the pool. */
|
||||
pool_ptr -> tx_byte_pool_available = (pool_ptr -> tx_byte_pool_available - available_bytes) - ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)));
|
||||
|
||||
/* Determine if the search pointer needs to be updated. This is only done
|
||||
if the search pointer matches the block to be returned. */
|
||||
if (current_ptr == pool_ptr -> tx_byte_pool_search)
|
||||
{
|
||||
|
||||
/* Yes, update the search pointer to the next block. */
|
||||
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
|
||||
pool_ptr -> tx_byte_pool_search = *this_block_link_ptr;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Adjust the pointer for the application. */
|
||||
current_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Set current pointer to NULL to indicate nothing was found. */
|
||||
current_ptr = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the search pointer. */
|
||||
return(current_ptr);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Byte Memory */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_byte_release PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function returns previously allocated memory to its */
|
||||
/* associated memory byte pool. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* memory_ptr Pointer to allocated memory */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* [TX_PTR_ERROR | TX_SUCCESS] Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* _tx_byte_pool_search Search the byte pool for memory */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_byte_release(VOID *memory_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT status;
|
||||
TX_BYTE_POOL *pool_ptr;
|
||||
TX_THREAD *thread_ptr;
|
||||
UCHAR *work_ptr;
|
||||
UCHAR *temp_ptr;
|
||||
UCHAR *next_block_ptr;
|
||||
TX_THREAD *susp_thread_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
ULONG memory_size;
|
||||
ALIGN_TYPE *free_ptr;
|
||||
TX_BYTE_POOL **byte_pool_ptr;
|
||||
UCHAR **block_link_ptr;
|
||||
UCHAR **suspend_info_ptr;
|
||||
|
||||
|
||||
/* Default to successful status. */
|
||||
status = TX_SUCCESS;
|
||||
|
||||
/* Set the pool pointer to NULL. */
|
||||
pool_ptr = TX_NULL;
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if the memory pointer is valid. */
|
||||
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(memory_ptr);
|
||||
if (work_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Back off the memory pointer to pickup its header. */
|
||||
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE))));
|
||||
|
||||
/* There is a pointer, pickup the pool pointer address. */
|
||||
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
|
||||
if ((*free_ptr) != TX_BYTE_BLOCK_FREE)
|
||||
{
|
||||
|
||||
/* Pickup the pool pointer. */
|
||||
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
|
||||
byte_pool_ptr = TX_UCHAR_TO_INDIRECT_BYTE_POOL_POINTER(temp_ptr);
|
||||
pool_ptr = *byte_pool_ptr;
|
||||
|
||||
/* See if we have a valid pool pointer. */
|
||||
if (pool_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Return pointer error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* See if we have a valid pool. */
|
||||
if (pool_ptr -> tx_byte_pool_id != TX_BYTE_POOL_ID)
|
||||
{
|
||||
|
||||
/* Return pointer error. */
|
||||
status = TX_PTR_ERROR;
|
||||
|
||||
/* Reset the pool pointer is NULL. */
|
||||
pool_ptr = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Return pointer error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Return pointer error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
|
||||
/* Determine if the pointer is valid. */
|
||||
if (pool_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At this point, we know that the pointer is valid. */
|
||||
|
||||
/* Pickup thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr)
|
||||
|
||||
/* Indicate that this thread is the current owner. */
|
||||
pool_ptr -> tx_byte_pool_owner = thread_ptr;
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total release counter. */
|
||||
_tx_byte_pool_performance_release_count++;
|
||||
|
||||
/* Increment the number of releases on this pool. */
|
||||
pool_ptr -> tx_byte_pool_performance_release_count++;
|
||||
#endif
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_RELEASE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(memory_ptr), pool_ptr -> tx_byte_pool_suspended_count, pool_ptr -> tx_byte_pool_available, TX_TRACE_BYTE_POOL_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_BYTE_RELEASE_INSERT
|
||||
|
||||
/* Release the memory. */
|
||||
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
|
||||
*free_ptr = TX_BYTE_BLOCK_FREE;
|
||||
|
||||
/* Update the number of available bytes in the pool. */
|
||||
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
|
||||
next_block_ptr = *block_link_ptr;
|
||||
pool_ptr -> tx_byte_pool_available =
|
||||
pool_ptr -> tx_byte_pool_available + TX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
|
||||
|
||||
/* Determine if the free block is prior to current search pointer. */
|
||||
if (work_ptr < (pool_ptr -> tx_byte_pool_search))
|
||||
{
|
||||
|
||||
/* Yes, update the search pointer to the released block. */
|
||||
pool_ptr -> tx_byte_pool_search = work_ptr;
|
||||
}
|
||||
|
||||
/* Determine if there are threads suspended on this byte pool. */
|
||||
if (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Now examine the suspension list to find threads waiting for
|
||||
memory. Maybe it is now available! */
|
||||
while (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Pickup the first suspended thread pointer. */
|
||||
susp_thread_ptr = pool_ptr -> tx_byte_pool_suspension_list;
|
||||
|
||||
/* Pickup the size of the memory the thread is requesting. */
|
||||
memory_size = susp_thread_ptr -> tx_thread_suspend_info;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* See if the request can be satisfied. */
|
||||
work_ptr = _tx_byte_pool_search(pool_ptr, memory_size);
|
||||
|
||||
/* Optional processing extension. */
|
||||
TX_BYTE_RELEASE_EXTENSION
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Indicate that this thread is the current owner. */
|
||||
pool_ptr -> tx_byte_pool_owner = thread_ptr;
|
||||
|
||||
/* If there is not enough memory, break this loop! */
|
||||
if (work_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Break out of the loop. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to make sure the thread is still suspended. */
|
||||
if (susp_thread_ptr == pool_ptr -> tx_byte_pool_suspension_list)
|
||||
{
|
||||
|
||||
/* Also, makes sure the memory size is the same. */
|
||||
if (susp_thread_ptr -> tx_thread_suspend_info == memory_size)
|
||||
{
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* Decrement the number of threads suspended. */
|
||||
pool_ptr -> tx_byte_pool_suspended_count--;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same expiration list. */
|
||||
|
||||
/* Update the list head pointer. */
|
||||
next_thread = susp_thread_ptr -> tx_thread_suspended_next;
|
||||
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
previous_thread = susp_thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
}
|
||||
|
||||
/* Prepare for resumption of the thread. */
|
||||
|
||||
/* Clear cleanup routine to avoid timeout. */
|
||||
susp_thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Return this block pointer to the suspended thread waiting for
|
||||
a block. */
|
||||
suspend_info_ptr = TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(susp_thread_ptr -> tx_thread_additional_suspend_info);
|
||||
*suspend_info_ptr = work_ptr;
|
||||
|
||||
/* Clear the memory pointer to indicate that it was given to the suspended thread. */
|
||||
work_ptr = TX_NULL;
|
||||
|
||||
/* Put return status into the thread control block. */
|
||||
susp_thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(susp_thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume thread. */
|
||||
_tx_thread_system_resume(susp_thread_ptr);
|
||||
#endif
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if the memory was given to the suspended thread. */
|
||||
if (work_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* No, it wasn't given to the suspended thread. */
|
||||
|
||||
/* Put the memory back on the available list since this thread is no longer
|
||||
suspended. */
|
||||
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, (((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
|
||||
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
|
||||
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
|
||||
*free_ptr = TX_BYTE_BLOCK_FREE;
|
||||
|
||||
/* Update the number of available bytes in the pool. */
|
||||
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
|
||||
next_block_ptr = *block_link_ptr;
|
||||
pool_ptr -> tx_byte_pool_available =
|
||||
pool_ptr -> tx_byte_pool_available + TX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
|
||||
|
||||
/* Determine if the current pointer is before the search pointer. */
|
||||
if (work_ptr < (pool_ptr -> tx_byte_pool_search))
|
||||
{
|
||||
|
||||
/* Yes, update the search pointer. */
|
||||
pool_ptr -> tx_byte_pool_search = work_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* No, threads suspended, restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_cleanup PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes event flags timeout and thread terminate */
|
||||
/* actions that require the event flags data structures to be cleaned */
|
||||
/* up. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to suspended thread's */
|
||||
/* control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_timeout Thread timeout processing */
|
||||
/* _tx_thread_terminate Thread terminate processing */
|
||||
/* _tx_thread_wait_abort Thread wait abort processing */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_event_flags_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
#endif
|
||||
|
||||
TX_EVENT_FLAGS_GROUP *group_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *suspension_head;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Disable interrupts to remove the suspended thread from the event flags group. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if the cleanup is still required. */
|
||||
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_event_flags_cleanup))
|
||||
{
|
||||
|
||||
/* Check for valid suspension sequence. */
|
||||
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
|
||||
{
|
||||
|
||||
/* Setup pointer to event flags control block. */
|
||||
group_ptr = TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
|
||||
/* Check for a NULL event flags control block pointer. */
|
||||
if (group_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Is the group pointer ID valid? */
|
||||
if (group_ptr -> tx_event_flags_group_id == TX_EVENT_FLAGS_ID)
|
||||
{
|
||||
|
||||
/* Determine if there are any thread suspensions. */
|
||||
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
#else
|
||||
|
||||
/* Setup pointer to event flags control block. */
|
||||
group_ptr = TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
#endif
|
||||
|
||||
/* Yes, we still have thread suspension! */
|
||||
|
||||
/* Clear the suspension cleanup flag. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
|
||||
|
||||
/* Pickup the suspension head. */
|
||||
suspension_head = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
|
||||
/* Determine if the cleanup is being done while a set operation was interrupted. If the
|
||||
suspended count is non-zero and the suspension head is NULL, the list is being processed
|
||||
and cannot be touched from here. The suspension list removal will instead take place
|
||||
inside the event flag set code. */
|
||||
if (suspension_head != TX_NULL)
|
||||
{
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* Decrement the local suspension count. */
|
||||
suspended_count--;
|
||||
|
||||
/* Store the updated suspended count. */
|
||||
group_ptr -> tx_event_flags_group_suspended_count = suspended_count;
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same suspension list. */
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Determine if we need to update the head pointer. */
|
||||
if (suspension_head == thread_ptr)
|
||||
{
|
||||
|
||||
/* Update the list head pointer. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = next_thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* In this case, the search pointer in an interrupted event flag set must be reset. */
|
||||
group_ptr -> tx_event_flags_group_reset_search = TX_TRUE;
|
||||
}
|
||||
|
||||
/* Now we need to determine if this cleanup is from a terminate, timeout,
|
||||
or from a wait abort. */
|
||||
if (thread_ptr -> tx_thread_state == TX_EVENT_FLAG)
|
||||
{
|
||||
|
||||
/* Timeout condition and the thread still suspended on the event flags group.
|
||||
Setup return error status and resume the thread. */
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total timeouts counter. */
|
||||
_tx_event_flags_performance_timeout_count++;
|
||||
|
||||
/* Increment the number of timeouts on this event flags group. */
|
||||
group_ptr -> tx_event_flags_group____performance_timeout_count++;
|
||||
#endif
|
||||
|
||||
/* Setup return status. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_NO_EVENTS;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread! Check for preemption even though we are executing
|
||||
from the system timer thread right now which normally executes at the
|
||||
highest priority. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
}
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_create PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function creates a group of 32 event flags. All the flags are */
|
||||
/* initially in a cleared state. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to event flags group */
|
||||
/* control block */
|
||||
/* name_ptr Pointer to event flags name */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_EVENT_FLAGS_GROUP *next_group;
|
||||
TX_EVENT_FLAGS_GROUP *previous_group;
|
||||
|
||||
|
||||
/* Initialize event flags control block to all zeros. */
|
||||
TX_MEMSET(group_ptr, 0, (sizeof(TX_EVENT_FLAGS_GROUP)));
|
||||
|
||||
/* Setup the basic event flags group fields. */
|
||||
group_ptr -> tx_event_flags_group_name = name_ptr;
|
||||
|
||||
/* Disable interrupts to put the event flags group on the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Setup the event flags ID to make it valid. */
|
||||
group_ptr -> tx_event_flags_group_id = TX_EVENT_FLAGS_ID;
|
||||
|
||||
/* Place the group on the list of created event flag groups. First,
|
||||
check for an empty list. */
|
||||
if (_tx_event_flags_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* The created event flags list is empty. Add event flag group to empty list. */
|
||||
_tx_event_flags_created_ptr = group_ptr;
|
||||
group_ptr -> tx_event_flags_group_created_next = group_ptr;
|
||||
group_ptr -> tx_event_flags_group_created_previous = group_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add to the end of the list. */
|
||||
next_group = _tx_event_flags_created_ptr;
|
||||
previous_group = next_group -> tx_event_flags_group_created_previous;
|
||||
|
||||
/* Place the new event flag group in the list. */
|
||||
next_group -> tx_event_flags_group_created_previous = group_ptr;
|
||||
previous_group -> tx_event_flags_group_created_next = group_ptr;
|
||||
|
||||
/* Setup this group's created links. */
|
||||
group_ptr -> tx_event_flags_group_created_previous = previous_group;
|
||||
group_ptr -> tx_event_flags_group_created_next = next_group;
|
||||
}
|
||||
|
||||
/* Increment the number of created event flag groups. */
|
||||
_tx_event_flags_created_count++;
|
||||
|
||||
/* Optional event flag group create extended processing. */
|
||||
TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
|
||||
/* If trace is enabled, register this object. */
|
||||
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_EVENT_FLAGS, group_ptr, name_ptr, 0, 0)
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_CREATE, group_ptr, TX_POINTER_TO_ULONG_CONVERT(&next_group), 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_CREATE_INSERT
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_delete PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function deletes the specified event flag group. All threads */
|
||||
/* suspended on the group are resumed with the TX_DELETED status */
|
||||
/* code. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to group control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *next_thread;
|
||||
UINT suspended_count;
|
||||
TX_EVENT_FLAGS_GROUP *next_group;
|
||||
TX_EVENT_FLAGS_GROUP *previous_group;
|
||||
|
||||
|
||||
/* Disable interrupts to remove the group from the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_DELETE, group_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Optional event flags group delete extended processing. */
|
||||
TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
|
||||
/* If trace is enabled, unregister this object. */
|
||||
TX_TRACE_OBJECT_UNREGISTER(group_ptr)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_DELETE_INSERT
|
||||
|
||||
/* Clear the event flag group ID to make it invalid. */
|
||||
group_ptr -> tx_event_flags_group_id = TX_CLEAR_ID;
|
||||
|
||||
/* Decrement the number of created event flag groups. */
|
||||
_tx_event_flags_created_count--;
|
||||
|
||||
/* See if this group is the only one on the list. */
|
||||
if (_tx_event_flags_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* Only created event flag group, just set the created list to NULL. */
|
||||
_tx_event_flags_created_ptr = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Link-up the neighbors. */
|
||||
next_group = group_ptr -> tx_event_flags_group_created_next;
|
||||
previous_group = group_ptr -> tx_event_flags_group_created_previous;
|
||||
next_group -> tx_event_flags_group_created_previous = previous_group;
|
||||
previous_group -> tx_event_flags_group_created_next = next_group;
|
||||
|
||||
/* See if we have to update the created list head pointer. */
|
||||
if (_tx_event_flags_created_ptr == group_ptr)
|
||||
{
|
||||
|
||||
/* Yes, move the head pointer to the next link. */
|
||||
_tx_event_flags_created_ptr = next_group;
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Pickup the suspension information. */
|
||||
thread_ptr = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
|
||||
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
|
||||
group_ptr -> tx_event_flags_group_suspended_count = TX_NO_SUSPENSIONS;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Walk through the event flag suspension list to resume any and all threads
|
||||
suspended on this group. */
|
||||
while (suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Decrement the number of suspended threads. */
|
||||
suspended_count--;
|
||||
|
||||
/* Lockout interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Clear the cleanup pointer, this prevents the timeout from doing
|
||||
anything. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Set the return status in the thread to TX_DELETED. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
|
||||
|
||||
/* Move the thread pointer ahead. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption again. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
#endif
|
||||
|
||||
/* Move to next thread. */
|
||||
thread_ptr = next_thread;
|
||||
}
|
||||
|
||||
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
|
||||
TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION(group_ptr)
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Release previous preempt disable. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function gets the specified event flags from the group, */
|
||||
/* according to the get option. The get option also specifies whether */
|
||||
/* or not the retrieved flags are cleared. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to group control block */
|
||||
/* requested_event_flags Event flags requested */
|
||||
/* get_option Specifies and/or and clear options*/
|
||||
/* actual_flags_ptr Pointer to place the actual flags */
|
||||
/* the service retrieved */
|
||||
/* wait_option Suspension option */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_suspend Suspend thread service */
|
||||
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
|
||||
UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
UINT status;
|
||||
UINT and_request;
|
||||
UINT clear_request;
|
||||
ULONG current_flags;
|
||||
ULONG flags_satisfied;
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
ULONG delayed_clear_flags;
|
||||
#endif
|
||||
UINT suspended_count;
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
UINT interrupted_set_request;
|
||||
#endif
|
||||
|
||||
|
||||
/* Disable interrupts to examine the event flags group. */
|
||||
TX_DISABLE
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total event flags get counter. */
|
||||
_tx_event_flags_performance_get_count++;
|
||||
|
||||
/* Increment the number of event flags gets on this semaphore. */
|
||||
group_ptr -> tx_event_flags_group__performance_get_count++;
|
||||
#endif
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_GET, group_ptr, requested_flags, group_ptr -> tx_event_flags_group_current, get_option, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_GET_INSERT
|
||||
|
||||
/* Pickup current flags. */
|
||||
current_flags = group_ptr -> tx_event_flags_group_current;
|
||||
|
||||
/* Apply the event flag option mask. */
|
||||
and_request = (get_option & TX_AND);
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Check for AND condition. All flags must be present to satisfy request. */
|
||||
if (and_request == TX_AND)
|
||||
{
|
||||
|
||||
/* AND request is present. */
|
||||
|
||||
/* Calculate the flags present. */
|
||||
flags_satisfied = (current_flags & requested_flags);
|
||||
|
||||
/* Determine if they satisfy the AND request. */
|
||||
if (flags_satisfied != requested_flags)
|
||||
{
|
||||
|
||||
/* No, not all the requested flags are present. Clear the flags present variable. */
|
||||
flags_satisfied = ((ULONG) 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* OR request is present. Simply or the requested flags and the current flags. */
|
||||
flags_satisfied = (current_flags & requested_flags);
|
||||
}
|
||||
|
||||
/* Determine if the request is satisfied. */
|
||||
if (flags_satisfied != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
*actual_flags_ptr = current_flags;
|
||||
|
||||
/* Pickup the clear bit. */
|
||||
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
|
||||
|
||||
/* Determine whether or not clearing needs to take place. */
|
||||
if (clear_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* Yes, clear the flags that satisfied this request. */
|
||||
group_ptr -> tx_event_flags_group_current =
|
||||
group_ptr -> tx_event_flags_group_current & (~requested_flags);
|
||||
}
|
||||
|
||||
/* Return success. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Pickup delayed clear flags. */
|
||||
delayed_clear_flags = group_ptr -> tx_event_flags_group_delayed_clear;
|
||||
|
||||
/* Determine if there are any delayed clear operations pending. */
|
||||
if (delayed_clear_flags != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Yes, apply them to the current flags. */
|
||||
current_flags = current_flags & (~delayed_clear_flags);
|
||||
}
|
||||
|
||||
/* Check for AND condition. All flags must be present to satisfy request. */
|
||||
if (and_request == TX_AND)
|
||||
{
|
||||
|
||||
/* AND request is present. */
|
||||
|
||||
/* Calculate the flags present. */
|
||||
flags_satisfied = (current_flags & requested_flags);
|
||||
|
||||
/* Determine if they satisfy the AND request. */
|
||||
if (flags_satisfied != requested_flags)
|
||||
{
|
||||
|
||||
/* No, not all the requested flags are present. Clear the flags present variable. */
|
||||
flags_satisfied = ((ULONG) 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* OR request is present. Simply AND together the requested flags and the current flags
|
||||
to see if any are present. */
|
||||
flags_satisfied = (current_flags & requested_flags);
|
||||
}
|
||||
|
||||
/* Determine if the request is satisfied. */
|
||||
if (flags_satisfied != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Yes, this request can be handled immediately. */
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
*actual_flags_ptr = current_flags;
|
||||
|
||||
/* Pickup the clear bit. */
|
||||
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
|
||||
|
||||
/* Determine whether or not clearing needs to take place. */
|
||||
if (clear_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* Set interrupted set request flag to false. */
|
||||
interrupted_set_request = TX_FALSE;
|
||||
|
||||
/* Determine if the suspension list is being processed by an interrupted
|
||||
set request. */
|
||||
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
if (group_ptr -> tx_event_flags_group_suspension_list == TX_NULL)
|
||||
{
|
||||
|
||||
/* Set the interrupted set request flag. */
|
||||
interrupted_set_request = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Was a set request interrupted? */
|
||||
if (interrupted_set_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* A previous set operation is was interrupted, we need to defer the
|
||||
event clearing until the set operation is complete. */
|
||||
|
||||
/* Remember the events to clear. */
|
||||
group_ptr -> tx_event_flags_group_delayed_clear =
|
||||
group_ptr -> tx_event_flags_group_delayed_clear | requested_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Yes, clear the flags that satisfied this request. */
|
||||
group_ptr -> tx_event_flags_group_current =
|
||||
group_ptr -> tx_event_flags_group_current & ~requested_flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set status to success. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
else
|
||||
{
|
||||
|
||||
/* Determine if the request specifies suspension. */
|
||||
if (wait_option != TX_NO_WAIT)
|
||||
{
|
||||
|
||||
/* Determine if the preempt disable flag is non-zero. */
|
||||
if (_tx_thread_preempt_disable != ((UINT) 0))
|
||||
{
|
||||
|
||||
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
|
||||
status = TX_NO_EVENTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Prepare for suspension of this thread. */
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total event flags suspensions counter. */
|
||||
_tx_event_flags_performance_suspension_count++;
|
||||
|
||||
/* Increment the number of event flags suspensions on this semaphore. */
|
||||
group_ptr -> tx_event_flags_group___performance_suspension_count++;
|
||||
#endif
|
||||
|
||||
/* Pickup thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr)
|
||||
|
||||
/* Setup cleanup routine pointer. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
|
||||
|
||||
/* Remember which event flags we are looking for. */
|
||||
thread_ptr -> tx_thread_suspend_info = requested_flags;
|
||||
|
||||
/* Save the get option as well. */
|
||||
thread_ptr -> tx_thread_suspend_option = get_option;
|
||||
|
||||
/* Save the destination for the current events. */
|
||||
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) actual_flags_ptr;
|
||||
|
||||
/* Setup cleanup information, i.e. this event flags group control
|
||||
block. */
|
||||
thread_ptr -> tx_thread_suspend_control_block = (VOID *) group_ptr;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Increment the suspension sequence number, which is used to identify
|
||||
this suspension event. */
|
||||
thread_ptr -> tx_thread_suspension_sequence++;
|
||||
#endif
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
|
||||
|
||||
/* Setup suspension list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* No other threads are suspended. Setup the head pointer and
|
||||
just setup this threads pointers to itself. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_next = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add current thread to the end. */
|
||||
next_thread = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
thread_ptr -> tx_thread_suspended_next = next_thread;
|
||||
previous_thread = next_thread -> tx_thread_suspended_previous;
|
||||
thread_ptr -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = thread_ptr;
|
||||
next_thread -> tx_thread_suspended_previous = thread_ptr;
|
||||
}
|
||||
|
||||
/* Increment the number of threads suspended. */
|
||||
group_ptr -> tx_event_flags_group_suspended_count++;
|
||||
|
||||
/* Set the state to suspended. */
|
||||
thread_ptr -> tx_thread_state = TX_EVENT_FLAG;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Call actual non-interruptable thread suspension routine. */
|
||||
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
|
||||
|
||||
/* Return the completion status. */
|
||||
status = thread_ptr -> tx_thread_suspend_status;
|
||||
#else
|
||||
|
||||
/* Set the suspending flag. */
|
||||
thread_ptr -> tx_thread_suspending = TX_TRUE;
|
||||
|
||||
/* Setup the timeout period. */
|
||||
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Call actual thread suspension routine. */
|
||||
_tx_thread_system_suspend(thread_ptr);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Return the completion status. */
|
||||
status = thread_ptr -> tx_thread_suspend_status;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Immediate return, return error completion. */
|
||||
status = TX_NO_EVENTS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves information from the specified event flag */
|
||||
/* group. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to event flag group */
|
||||
/* name Destination for the event flag */
|
||||
/* group name */
|
||||
/* current_flags Current event flags */
|
||||
/* first_suspended Destination for pointer of first */
|
||||
/* thread suspended on event flags */
|
||||
/* suspended_count Destination for suspended count */
|
||||
/* next_group Destination for pointer to next */
|
||||
/* event flag group on the created */
|
||||
/* list */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags,
|
||||
TX_THREAD **first_suspended, ULONG *suspended_count,
|
||||
TX_EVENT_FLAGS_GROUP **next_group)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_INFO_GET, group_ptr, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the name of the event flag group. */
|
||||
if (name != TX_NULL)
|
||||
{
|
||||
|
||||
*name = group_ptr -> tx_event_flags_group_name;
|
||||
}
|
||||
|
||||
/* Retrieve the current event flags in the event flag group. */
|
||||
if (current_flags != TX_NULL)
|
||||
{
|
||||
|
||||
/* Pickup the current flags and apply delayed clearing. */
|
||||
*current_flags = group_ptr -> tx_event_flags_group_current &
|
||||
~group_ptr -> tx_event_flags_group_delayed_clear;
|
||||
}
|
||||
|
||||
/* Retrieve the first thread suspended on this event flag group. */
|
||||
if (first_suspended != TX_NULL)
|
||||
{
|
||||
|
||||
*first_suspended = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
}
|
||||
|
||||
/* Retrieve the number of threads suspended on this event flag group. */
|
||||
if (suspended_count != TX_NULL)
|
||||
{
|
||||
|
||||
*suspended_count = (ULONG) group_ptr -> tx_event_flags_group_suspended_count;
|
||||
}
|
||||
|
||||
/* Retrieve the pointer to the next event flag group created. */
|
||||
if (next_group != TX_NULL)
|
||||
{
|
||||
|
||||
*next_group = group_ptr -> tx_event_flags_group_created_next;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
#ifndef TX_INLINE_INITIALIZATION
|
||||
|
||||
/* Locate event flags component data in this file. */
|
||||
/* Define the head pointer of the created event flags list. */
|
||||
|
||||
TX_EVENT_FLAGS_GROUP * _tx_event_flags_created_ptr;
|
||||
|
||||
|
||||
/* Define the variable that holds the number of created event flag groups. */
|
||||
|
||||
ULONG _tx_event_flags_created_count;
|
||||
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Define the total number of event flag sets. */
|
||||
|
||||
ULONG _tx_event_flags_performance_set_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag gets. */
|
||||
|
||||
ULONG _tx_event_flags_performance_get_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag suspensions. */
|
||||
|
||||
ULONG _tx_event_flags_performance_suspension_count;
|
||||
|
||||
|
||||
/* Define the total number of event flag timeouts. */
|
||||
|
||||
ULONG _tx_event_flags_performance_timeout_count;
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_initialize PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function initializes the various control data structures for */
|
||||
/* the event flags component. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_high_level High level initialization */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_event_flags_initialize(VOID)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_REDUNDANT_CLEARING
|
||||
|
||||
/* Initialize the head pointer of the created event flags list and the
|
||||
number of event flags created. */
|
||||
_tx_event_flags_created_ptr = TX_NULL;
|
||||
_tx_event_flags_created_count = TX_EMPTY;
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Initialize event flags performance counters. */
|
||||
_tx_event_flags_performance_set_count = ((ULONG) 0);
|
||||
_tx_event_flags_performance_get_count = ((ULONG) 0);
|
||||
_tx_event_flags_performance_suspension_count = ((ULONG) 0);
|
||||
_tx_event_flags_performance_timeout_count = ((ULONG) 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_event_flags.h"
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_performance_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves performance information from the specified */
|
||||
/* event flag group. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to event flag group */
|
||||
/* sets Destination for the number of */
|
||||
/* event flag sets on this group */
|
||||
/* gets Destination for the number of */
|
||||
/* event flag gets on this group */
|
||||
/* suspensions Destination for the number of */
|
||||
/* event flag suspensions on this */
|
||||
/* group */
|
||||
/* timeouts Destination for number of timeouts*/
|
||||
/* on this event flag group */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets,
|
||||
ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine if this is a legal request. */
|
||||
if (group_ptr == TX_NULL)
|
||||
{
|
||||
|
||||
/* Event flags group pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
|
||||
/* Determine if the event group ID is invalid. */
|
||||
else if (group_ptr -> tx_event_flags_group_id != TX_EVENT_FLAGS_ID)
|
||||
{
|
||||
|
||||
/* Event flags group pointer is illegal, return error. */
|
||||
status = TX_PTR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_PERFORMANCE_INFO_GET, group_ptr, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the number of set operations on this event flag group. */
|
||||
if (sets != TX_NULL)
|
||||
{
|
||||
|
||||
*sets = group_ptr -> tx_event_flags_group_performance_set_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of get operations on this event flag group. */
|
||||
if (gets != TX_NULL)
|
||||
{
|
||||
|
||||
*gets = group_ptr -> tx_event_flags_group__performance_get_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of thread suspensions on this event flag group. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = group_ptr -> tx_event_flags_group___performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the number of thread timeouts on this event flag group. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = group_ptr -> tx_event_flags_group____performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return successful completion. */
|
||||
status = TX_SUCCESS;
|
||||
}
|
||||
#else
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (group_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (sets != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (gets != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_event_flags.h"
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
#include "tx_trace.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_performance_system_info_get PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function retrieves system event flag performance information. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* sets Destination for total number of */
|
||||
/* event flag sets */
|
||||
/* gets Destination for total number of */
|
||||
/* event flag gets */
|
||||
/* suspensions Destination for total number of */
|
||||
/* event flag suspensions */
|
||||
/* timeouts Destination for total number of */
|
||||
/* timeouts */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_performance_system_info_get(ULONG *sets, ULONG *gets, ULONG *suspensions, ULONG *timeouts)
|
||||
{
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET_INSERT
|
||||
|
||||
/* Retrieve all the pertinent information and return it in the supplied
|
||||
destinations. */
|
||||
|
||||
/* Retrieve the total number of event flag set operations. */
|
||||
if (sets != TX_NULL)
|
||||
{
|
||||
|
||||
*sets = _tx_event_flags_performance_set_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of event flag get operations. */
|
||||
if (gets != TX_NULL)
|
||||
{
|
||||
|
||||
*gets = _tx_event_flags_performance_get_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of event flag thread suspensions. */
|
||||
if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
*suspensions = _tx_event_flags_performance_suspension_count;
|
||||
}
|
||||
|
||||
/* Retrieve the total number of event flag thread timeouts. */
|
||||
if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
*timeouts = _tx_event_flags_performance_timeout_count;
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
|
||||
#else
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Access input arguments just for the sake of lint, MISRA, etc. */
|
||||
if (sets != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (gets != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (suspensions != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else if (timeouts != TX_NULL)
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not enabled, return error. */
|
||||
status = TX_FEATURE_NOT_ENABLED;
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(status);
|
||||
#endif
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_set_notify PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function registers an application callback function that is */
|
||||
/* called whenever an event flag is set in this group. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to group control block*/
|
||||
/* group_put_notify Application callback function */
|
||||
/* (TX_NULL disables notify) */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* status Service return status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_set_notify(TX_EVENT_FLAGS_GROUP *group_ptr, VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr))
|
||||
{
|
||||
|
||||
#ifdef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
TX_EVENT_FLAGS_GROUP_NOT_USED(group_ptr);
|
||||
TX_EVENT_FLAGS_SET_NOTIFY_NOT_USED(events_set_notify);
|
||||
|
||||
/* Feature is not enabled, return error. */
|
||||
return(TX_FEATURE_NOT_ENABLED);
|
||||
#else
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Make entry in event log. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_SET_NOTIFY, group_ptr, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Make entry in event log. */
|
||||
TX_EL_EVENT_FLAGS_SET_NOTIFY_INSERT
|
||||
|
||||
/* Setup event flag group set notification callback function. */
|
||||
group_ptr -> tx_event_flags_group_set_notify = events_set_notify;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return success to caller. */
|
||||
return(TX_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
|
||||
/* Determine if in-line initialization is required. */
|
||||
#ifdef TX_INLINE_INITIALIZATION
|
||||
#define TX_INVOKE_INLINE_INITIALIZATION
|
||||
#endif
|
||||
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
#include "tx_semaphore.h"
|
||||
#include "tx_queue.h"
|
||||
#include "tx_event_flags.h"
|
||||
#include "tx_mutex.h"
|
||||
#include "tx_block_pool.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/* Define the unused memory pointer. The value of the first available
|
||||
memory address is placed in this variable in the low-level
|
||||
initialization function. The content of this variable is passed
|
||||
to the application's system definition function. */
|
||||
|
||||
VOID *_tx_initialize_unused_memory;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_high_level PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for initializing all of the other */
|
||||
/* components in the ThreadX real-time kernel. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_initialize Initialize the thread control */
|
||||
/* component */
|
||||
/* _tx_timer_initialize Initialize the timer control */
|
||||
/* component */
|
||||
/* _tx_semaphore_initialize Initialize the semaphore control */
|
||||
/* component */
|
||||
/* _tx_queue_initialize Initialize the queue control */
|
||||
/* component */
|
||||
/* _tx_event_flags_initialize Initialize the event flags control*/
|
||||
/* component */
|
||||
/* _tx_block_pool_initialize Initialize the block pool control */
|
||||
/* component */
|
||||
/* _tx_byte_pool_initialize Initialize the byte pool control */
|
||||
/* component */
|
||||
/* _tx_mutex_initialize Initialize the mutex control */
|
||||
/* component */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter Kernel entry function */
|
||||
/* _tx_initialize_kernel_setup Early kernel setup function that */
|
||||
/* is optionally called by */
|
||||
/* compiler's startup code. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_initialize_high_level(VOID)
|
||||
{
|
||||
|
||||
/* Initialize event tracing, if enabled. */
|
||||
TX_TRACE_INITIALIZE
|
||||
|
||||
/* Initialize the event log, if enabled. */
|
||||
TX_EL_INITIALIZE
|
||||
|
||||
/* Call the thread control initialization function. */
|
||||
_tx_thread_initialize();
|
||||
|
||||
#ifndef TX_NO_TIMER
|
||||
|
||||
/* Call the timer control initialization function. */
|
||||
_tx_timer_initialize();
|
||||
#endif
|
||||
|
||||
#ifndef TX_DISABLE_REDUNDANT_CLEARING
|
||||
|
||||
/* Call the semaphore initialization function. */
|
||||
_tx_semaphore_initialize();
|
||||
|
||||
/* Call the queue initialization function. */
|
||||
_tx_queue_initialize();
|
||||
|
||||
/* Call the event flag initialization function. */
|
||||
_tx_event_flags_initialize();
|
||||
|
||||
/* Call the block pool initialization function. */
|
||||
_tx_block_pool_initialize();
|
||||
|
||||
/* Call the byte pool initialization function. */
|
||||
_tx_byte_pool_initialize();
|
||||
|
||||
/* Call the mutex initialization function. */
|
||||
_tx_mutex_initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
|
||||
|
||||
/* Define any port-specific scheduling data structures. */
|
||||
|
||||
TX_PORT_SPECIFIC_DATA
|
||||
|
||||
|
||||
#ifdef TX_SAFETY_CRITICAL
|
||||
TX_SAFETY_CRITICAL_EXCEPTION_HANDLER
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is the first ThreadX function called during */
|
||||
/* initialization. It is called from the application's "main()" */
|
||||
/* function. It is important to note that this routine never */
|
||||
/* returns. The processing of this function is relatively simple: */
|
||||
/* it calls several ThreadX initialization functions (if needed), */
|
||||
/* calls the application define function, and then invokes the */
|
||||
/* scheduler. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_initialize_low_level Low-level initialization */
|
||||
/* _tx_initialize_high_level High-level initialization */
|
||||
/* tx_application_define Application define function */
|
||||
/* _tx_thread_scheduler ThreadX scheduling loop */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* main Application main program */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_initialize_kernel_enter(VOID)
|
||||
{
|
||||
|
||||
/* Determine if the compiler has pre-initialized ThreadX. */
|
||||
if (_tx_thread_system_state != TX_INITIALIZE_ALMOST_DONE)
|
||||
{
|
||||
|
||||
/* No, the initialization still needs to take place. */
|
||||
|
||||
/* Ensure that the system state variable is set to indicate
|
||||
initialization is in progress. Note that this variable is
|
||||
later used to represent interrupt nesting. */
|
||||
_tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;
|
||||
|
||||
/* Call any port specific preprocessing. */
|
||||
TX_PORT_SPECIFIC_PRE_INITIALIZATION
|
||||
|
||||
/* Invoke the low-level initialization to handle all processor specific
|
||||
initialization issues. */
|
||||
_tx_initialize_low_level();
|
||||
|
||||
/* Invoke the high-level initialization to exercise all of the
|
||||
ThreadX components and the application's initialization
|
||||
function. */
|
||||
_tx_initialize_high_level();
|
||||
|
||||
/* Call any port specific post-processing. */
|
||||
TX_PORT_SPECIFIC_POST_INITIALIZATION
|
||||
}
|
||||
|
||||
/* Optional processing extension. */
|
||||
TX_INITIALIZE_KERNEL_ENTER_EXTENSION
|
||||
|
||||
/* Ensure that the system state variable is set to indicate
|
||||
initialization is in progress. Note that this variable is
|
||||
later used to represent interrupt nesting. */
|
||||
_tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;
|
||||
|
||||
/* Call the application provided initialization function. Pass the
|
||||
first available memory address to it. */
|
||||
tx_application_define(_tx_initialize_unused_memory);
|
||||
|
||||
/* Set the system state in preparation for entering the thread
|
||||
scheduler. */
|
||||
_tx_thread_system_state = TX_INITIALIZE_IS_FINISHED;
|
||||
|
||||
/* Call any port specific pre-scheduler processing. */
|
||||
TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
|
||||
|
||||
/* Enter the scheduling loop to start executing threads! */
|
||||
_tx_thread_schedule();
|
||||
|
||||
#ifdef TX_SAFETY_CRITICAL
|
||||
|
||||
/* If we ever get here, raise safety critical exception. */
|
||||
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_setup PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is called by the compiler's startup code to make */
|
||||
/* ThreadX objects accessible to the compiler's library. If this */
|
||||
/* function is not called by the compiler, all ThreadX initialization */
|
||||
/* takes place from the kernel enter function defined previously. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_initialize_low_level Low-level initialization */
|
||||
/* _tx_initialize_high_level High-level initialization */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* startup code Compiler startup code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_initialize_kernel_setup(VOID)
|
||||
{
|
||||
|
||||
/* Ensure that the system state variable is set to indicate
|
||||
initialization is in progress. Note that this variable is
|
||||
later used to represent interrupt nesting. */
|
||||
_tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;
|
||||
|
||||
/* Call any port specific preprocessing. */
|
||||
TX_PORT_SPECIFIC_PRE_INITIALIZATION
|
||||
|
||||
/* Invoke the low-level initialization to handle all processor specific
|
||||
initialization issues. */
|
||||
_tx_initialize_low_level();
|
||||
|
||||
/* Invoke the high-level initialization to exercise all of the
|
||||
ThreadX components and the application's initialization
|
||||
function. */
|
||||
_tx_initialize_high_level();
|
||||
|
||||
/* Call any port specific post-processing. */
|
||||
TX_PORT_SPECIFIC_POST_INITIALIZATION
|
||||
|
||||
/* Set the system state to indicate initialization is almost done. */
|
||||
_tx_thread_system_state = TX_INITIALIZE_ALMOST_DONE;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,313 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Mutex */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_mutex_cleanup PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes mutex timeout and thread terminate */
|
||||
/* actions that require the mutex data structures to be cleaned */
|
||||
/* up. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to suspended thread's */
|
||||
/* control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_timeout Thread timeout processing */
|
||||
/* _tx_thread_terminate Thread terminate processing */
|
||||
/* _tx_thread_wait_abort Thread wait abort processing */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_mutex_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
#endif
|
||||
|
||||
TX_MUTEX *mutex_ptr;
|
||||
UINT suspended_count;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Disable interrupts to remove the suspended thread from the mutex. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Determine if the cleanup is still required. */
|
||||
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_mutex_cleanup))
|
||||
{
|
||||
|
||||
/* Check for valid suspension sequence. */
|
||||
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
|
||||
{
|
||||
|
||||
/* Setup pointer to mutex control block. */
|
||||
mutex_ptr = TX_VOID_TO_MUTEX_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
|
||||
/* Check for NULL mutex pointer. */
|
||||
if (mutex_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Determine if the mutex ID is valid. */
|
||||
if (mutex_ptr -> tx_mutex_id == TX_MUTEX_ID)
|
||||
{
|
||||
|
||||
/* Determine if there are any thread suspensions. */
|
||||
if (mutex_ptr -> tx_mutex_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
#else
|
||||
|
||||
/* Setup pointer to mutex control block. */
|
||||
mutex_ptr = TX_VOID_TO_MUTEX_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
|
||||
#endif
|
||||
|
||||
/* Yes, we still have thread suspension! */
|
||||
|
||||
/* Clear the suspension cleanup flag. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
mutex_ptr -> tx_mutex_suspended_count--;
|
||||
|
||||
/* Pickup the suspended count. */
|
||||
suspended_count = mutex_ptr -> tx_mutex_suspended_count;
|
||||
|
||||
/* Remove the suspended thread from the list. */
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (suspended_count == TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
mutex_ptr -> tx_mutex_suspension_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same suspension list. */
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Determine if we need to update the head pointer. */
|
||||
if (mutex_ptr -> tx_mutex_suspension_list == thread_ptr)
|
||||
{
|
||||
|
||||
/* Update the list head pointer. */
|
||||
mutex_ptr -> tx_mutex_suspension_list = next_thread;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we need to determine if this cleanup is from a terminate, timeout,
|
||||
or from a wait abort. */
|
||||
if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP)
|
||||
{
|
||||
|
||||
/* Timeout condition and the thread still suspended on the mutex.
|
||||
Setup return error status and resume the thread. */
|
||||
|
||||
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total timeouts counter. */
|
||||
_tx_mutex_performance_timeout_count++;
|
||||
|
||||
/* Increment the number of timeouts on this semaphore. */
|
||||
mutex_ptr -> tx_mutex_performance_timeout_count++;
|
||||
#endif
|
||||
|
||||
/* Setup return status. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_NOT_AVAILABLE;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
}
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_mutex_thread_release PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function releases all mutexes owned by the thread. This */
|
||||
/* function is called when the thread completes or is terminated. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to thread's control block */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_mutex_put Release the mutex */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_shell_entry Thread completion processing */
|
||||
/* _tx_thread_terminate Thread terminate processing */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_mutex_thread_release(TX_THREAD *thread_ptr)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_MUTEX *mutex_ptr;
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
UINT status;
|
||||
#endif
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Loop to look at all the mutexes. */
|
||||
do
|
||||
{
|
||||
|
||||
/* Pickup the mutex head pointer. */
|
||||
mutex_ptr = thread_ptr -> tx_thread_owned_mutex_list;
|
||||
|
||||
/* Determine if there is a mutex. */
|
||||
if (mutex_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Yes, set the ownership count to 1. */
|
||||
mutex_ptr -> tx_mutex_ownership_count = ((UINT) 1);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
#ifdef TX_MISRA_ENABLE
|
||||
/* Release the mutex. */
|
||||
do
|
||||
{
|
||||
status = _tx_mutex_put(mutex_ptr);
|
||||
} while (status != TX_SUCCESS);
|
||||
#else
|
||||
_tx_mutex_put(mutex_ptr);
|
||||
#endif
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Move to the next mutex. */
|
||||
mutex_ptr = thread_ptr -> tx_thread_owned_mutex_list;
|
||||
}
|
||||
} while (mutex_ptr != TX_NULL);
|
||||
|
||||
/* Restore preemption. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Mutex */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_mutex_create PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function creates a mutex with optional priority inheritance as */
|
||||
/* specified in this call. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* mutex_ptr Pointer to mutex control block*/
|
||||
/* name_ptr Pointer to mutex name */
|
||||
/* inherit Priority inheritance option */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Successful completion status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_MUTEX *next_mutex;
|
||||
TX_MUTEX *previous_mutex;
|
||||
|
||||
|
||||
/* Initialize mutex control block to all zeros. */
|
||||
TX_MEMSET(mutex_ptr, 0, (sizeof(TX_MUTEX)));
|
||||
|
||||
/* Setup the basic mutex fields. */
|
||||
mutex_ptr -> tx_mutex_name = name_ptr;
|
||||
mutex_ptr -> tx_mutex_inherit = inherit;
|
||||
|
||||
/* Disable interrupts to place the mutex on the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Setup the mutex ID to make it valid. */
|
||||
mutex_ptr -> tx_mutex_id = TX_MUTEX_ID;
|
||||
|
||||
/* Setup the thread mutex release function pointer. */
|
||||
_tx_thread_mutex_release = &(_tx_mutex_thread_release);
|
||||
|
||||
/* Place the mutex on the list of created mutexes. First,
|
||||
check for an empty list. */
|
||||
if (_tx_mutex_created_count == TX_EMPTY)
|
||||
{
|
||||
|
||||
/* The created mutex list is empty. Add mutex to empty list. */
|
||||
_tx_mutex_created_ptr = mutex_ptr;
|
||||
mutex_ptr -> tx_mutex_created_next = mutex_ptr;
|
||||
mutex_ptr -> tx_mutex_created_previous = mutex_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* This list is not NULL, add to the end of the list. */
|
||||
next_mutex = _tx_mutex_created_ptr;
|
||||
previous_mutex = next_mutex -> tx_mutex_created_previous;
|
||||
|
||||
/* Place the new mutex in the list. */
|
||||
next_mutex -> tx_mutex_created_previous = mutex_ptr;
|
||||
previous_mutex -> tx_mutex_created_next = mutex_ptr;
|
||||
|
||||
/* Setup this mutex's next and previous created links. */
|
||||
mutex_ptr -> tx_mutex_created_previous = previous_mutex;
|
||||
mutex_ptr -> tx_mutex_created_next = next_mutex;
|
||||
}
|
||||
|
||||
/* Increment the ownership count. */
|
||||
_tx_mutex_created_count++;
|
||||
|
||||
/* Optional mutex create extended processing. */
|
||||
TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
|
||||
/* If trace is enabled, register this object. */
|
||||
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_MUTEX, mutex_ptr, name_ptr, inherit, 0)
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_MUTEX_CREATE, mutex_ptr, inherit, TX_POINTER_TO_ULONG_CONVERT(&next_mutex), 0, TX_TRACE_MUTEX_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_MUTEX_CREATE_INSERT
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Return TX_SUCCESS. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user