Initial commit

This commit is contained in:
PProvost
2020-05-11 08:55:07 -06:00
commit 852421fda0
264 changed files with 54459 additions and 0 deletions
+208
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+146
View File
@@ -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
+177
View File
@@ -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
+147
View File
@@ -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
+111
View File
@@ -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
+160
View File
@@ -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
+173
View File
@@ -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
+144
View File
@@ -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
+213
View File
@@ -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
+257
View File
@@ -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
+372
View File
@@ -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);
}
+213
View File
@@ -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
}
+213
View File
@@ -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);
}
+207
View File
@@ -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);
}
+146
View File
@@ -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);
}
+129
View File
@@ -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
}
+249
View File
@@ -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);
}
+204
View File
@@ -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);
}
+409
View File
@@ -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);
}
+212
View File
@@ -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
}
+197
View File
@@ -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);
}
+211
View File
@@ -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);
}
+146
View File
@@ -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);
}
+147
View File
@@ -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
}
+249
View File
@@ -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);
}
+350
View File
@@ -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);
}
+376
View File
@@ -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);
}
+237
View File
@@ -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
}
+141
View File
@@ -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);
}
+207
View File
@@ -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);
}
+401
View File
@@ -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);
}
+143
View File
@@ -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);
}
+130
View File
@@ -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
+107
View File
@@ -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
}
+150
View File
@@ -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
}
+148
View File
@@ -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
}
+100
View File
@@ -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
+313
View File
@@ -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
}
+146
View File
@@ -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