Files
Frédéric Desbiens 9e4c57138d
cortex_m / Cortex M0 build (push) Canceled after 0s
cortex_m / Cortex M3 build (push) Canceled after 0s
cortex_m / Cortex M4 build (push) Canceled after 0s
cortex_m / Cortex M7 build (push) Canceled after 0s
gcc_check / gnu (push) Canceled after 0s
r52_fvp / r52 (push) Canceled after 0s
regression_test / tx (push) Canceled after 0s
regression_test / smp (push) Canceled after 0s
regression_test / freertos (push) Canceled after 0s
regression_test / riscv (push) Canceled after 0s
regression_test / deploy (push) Canceled after 0s
regression_template / run_tests (push) Canceled after 0s
regression_template / deploy_code_coverage (push) Canceled after 0s
Normalized the AI disclosure comment to one fixed line per file (#740)
The per-edit disclosure named the product and model, so every agent and every
model version appended another line. 74 files carried two to four of them, and
the same five products had accumulated 13 spellings -- Copilot against GitHub
Copilot, Claude Sonnet 4.6 against claude-sonnet-4.6, four spellings of Codex.
Twenty assembly lines carried a doubled comment marker, `; //` or `@ //`.

Every file now carries exactly one line, fixed text naming no product:

    Portions of this file were generated with AI assistance.

It is written with the comment character that file already uses, so the `;`
and `@` assembly files keep theirs and the doubled markers are gone. Precise
attribution stays on the commit, where the Assisted-by trailer is per-change,
dated and attached to the diff it describes. A header line cannot hold that
record honestly, because the code it names gets rewritten and the line stays.
A file-level flag answers whether; the history answers who.

Comment-only. 455 files, 455 insertions and 574 deletions: every removed line
was a disclosure line, every added line is the fixed text, and no file is left
with zero or with more than one. `scripts/check_ports.sh` passes, including the
reproducibility check that would catch a ports_arch master and its generated
copies drifting apart. Recompiled against dev, every file that builds without a
vendor toolchain gives a byte-identical object: 19 of 19 C files under common,
100 of 100 GNU assembly files, and all 16 assemblable files whose comment
marker changed. The 10 remaining marker changes are ac5 and IAR sources where
`;` already started the comment and only the redundant `//` was removed.

Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
2026-09-15 17:17:26 -04:00

1438 lines
60 KiB
C

/***************************************************************************/
/* Copyright (c) 2024 Microsoft Corporation */
/* Copyright (c) 2026 Eclipse ThreadX contributors */
/* */
/* This program and the accompanying materials are made available under */
/* the terms of the MIT License which is available at */
/* https://opensource.org/licenses/MIT. */
/* */
/* SPDX-License-Identifier: MIT */
/***************************************************************************/
/* This is the test control routine of the ThreadX kernel. All tests are dispatched from this routine. */
// Portions of this file were generated with AI assistance.
#include "tx_api.h"
#include <stdio.h>
#include "tx_initialize.h"
#include "tx_timer.h"
#include "tx_thread.h"
#include "tx_semaphore.h"
#include "tx_queue.h"
#include "tx_mutex.h"
#include "tx_block_pool.h"
#include "tx_byte_pool.h"
#include "tx_event_flags.h"
/* Version check. */
#ifndef EL_PRODUCT_THREADX
#error "EL_PRODUCT_THREADX is not defined."
#endif
#if defined(EXPECTED_MAJOR_VERSION) && ( !defined(THREADX_MAJOR_VERSION) || THREADX_MAJOR_VERSION != EXPECTED_MAJOR_VERSION)
#error "THREADX_MAJOR_VERSION"
#endif /* Check THREADX_MAJOR_VERSION */
#if defined(EXPECTED_MINOR_VERSION) && ( !defined(THREADX_MINOR_VERSION) || THREADX_MINOR_VERSION != EXPECTED_MINOR_VERSION)
#error "THREADX_MINOR_VERSION"
#endif /* Check THREADX_MINOR_VERSION */
#define TEST_STACK_SIZE 6144
/* Define the test control ThreadX objects... */
TX_THREAD test_control_thread;
TX_THREAD test_thread;
TX_THREAD test_thread1;
TX_THREAD test_thread2;
TX_THREAD test_thread3;
ULONG test_thread3_stack[256];
TX_QUEUE test_queue;
ULONG test_thread2_stack[256];
TX_TIMER test_timer;
TX_MUTEX init_mutex;
TX_MUTEX init_mutex_inherit;
TX_MUTEX cleanup_mutex;
TX_EVENT_FLAGS_GROUP cleanup_event_flags;
TX_BLOCK_POOL cleanup_block_pool;
TX_BYTE_POOL cleanup_byte_pool;
TX_QUEUE cleanup_queue;
TX_SEMAPHORE cleanup_semaphore;
TX_SEMAPHORE init_semaphore;
ULONG init_queue_area[20];
TX_QUEUE init_queue;
TX_BYTE_POOL init_byte_pool;
ULONG init_byte_pool_area[50];
TX_BLOCK_POOL init_block_pool;
ULONG init_block_pool_area[50];
TX_EVENT_FLAGS_GROUP init_event_flags;
TX_TIMER init_timer;
TX_TIMER init_timer_change;
TX_THREAD init_test_thread;
TX_THREAD second_test_thread;
#ifndef TX_TIMER_PROCESS_IN_ISR
TEST_FLAG threadx_delete_timer_thread;
#endif
TX_TIMER_INTERNAL **_timer_list_start_backup;
TEST_FLAG test_stack_analyze_flag;
TEST_FLAG test_initialize_flag;
TX_BLOCK_POOL fake_block_pool;
TX_BYTE_POOL fake_byte_pool;
TX_EVENT_FLAGS_GROUP fake_event_flags;
TX_MUTEX fake_mutex;
TX_QUEUE fake_queue;
TX_SEMAPHORE fake_semaphore;
TEST_FLAG test_forced_mutex_timeout;
TEST_FLAG threadx_mutex_suspension_put_test;
TEST_FLAG threadx_mutex_suspension_priority_test;
TEST_FLAG threadx_byte_allocate_loop_test;
TEST_FLAG threadx_byte_release_loop_test;
/* Define the test control global variables. */
ULONG test_control_return_status;
ULONG test_control_successful_tests;
ULONG test_control_failed_tests;
ULONG test_control_system_errors;
UINT test_mutex_from_init;
UINT test_semaphore_from_init;
UINT test_queue_from_init;
UINT test_event_flags_from_init;
UINT test_byte_pool_create_init;
UINT test_block_pool_create_init;
UINT test_timer_create_init;
/* Remember the start of free memory. */
UCHAR *test_free_memory_ptr;
/* Define the function pointer for ISR dispatch. */
VOID (*test_isr_dispatch)(void);
UCHAR test_control_memory[0x60000];
UCHAR tests_memory[0x60000];
/* Define the external reference for the preempt disable flag. */
extern volatile UINT _tx_thread_preempt_disable;
extern volatile ULONG _tx_thread_system_state;
/* Define test entry pointer type. */
typedef struct TEST_ENTRY_STRUCT
{
VOID (*test_entry)(void *);
} TEST_ENTRY;
/* Define the prototypes for the test entry points. */
void threadx_block_memory_basic_application_define(void *);
void threadx_block_memory_error_detection_application_define(void *);
void threadx_block_memory_suspension_application_define(void *);
void threadx_block_memory_suspension_timeout_application_define(void *);
void threadx_block_memory_thread_terminate_application_define(void *);
void threadx_block_memory_prioritize_application_define(void *);
void threadx_block_memory_information_application_define(void *);
void threadx_byte_memory_basic_application_define(void *);
void threadx_byte_memory_thread_contention_application_define(void *);
void threadx_byte_memory_suspension_application_define(void *);
void threadx_byte_memory_suspension_timeout_application_define(void *);
void threadx_byte_memory_thread_terminate_application_define(void *);
void threadx_byte_memory_prioritize_application_define(void *);
void threadx_byte_memory_information_application_define(void *);
void threadx_event_flag_basic_application_define(void *);
void threadx_event_flag_suspension_application_define(void *);
void threadx_event_flag_suspension_consume_application_define(void *);
void threadx_event_flag_suspension_different_bits_application_define(void *);
void threadx_event_flag_suspension_different_bits_consume_application_define(void *);
void threadx_event_flag_suspension_timeout_application_define(void *);
void threadx_event_flag_thread_terminate_application_define(void *);
void threadx_event_flag_single_thread_terminate_application_define(void *);
void threadx_event_flag_isr_set_clear_application_define(void *);
void threadx_event_flag_isr_wait_abort_application_define(void *);
void threadx_event_flag_information_application_define(void *);
void threadx_interrupt_control_application_define(void *);
void threadx_mutex_basic_application_define(void *);
void threadx_mutex_delete_application_define(void *);
void threadx_mutex_preemption_application_define(void *);
void threadx_mutext_no_preemption_application_define(void *);
void threadx_mutex_suspension_timeout_application_define(void *);
void threadx_mutex_thread_terminate_application_define(void *);
void threadx_mutex_priority_inheritance_application_define(void *);
void threadx_mutex_nested_priority_inheritance_application_define(void *);
void threadx_mutex_prioritize_application_define(void *);
void threadx_mutex_information_application_define(void *);
void threadx_queue_basic_application_define(void *);
void threadx_queue_basic_two_word_application_define(void *);
void threadx_queue_basic_four_word_application_define(void *);
void threadx_queue_basic_eight_word_application_define(void *);
void threadx_queue_basic_sixteen_word_application_define(void *);
void threadx_queue_basic_max_message_size_application_define(void *);
void threadx_queue_empty_suspension_application_define(void *);
void threadx_queue_full_suspension_application_define(void *);
void threadx_queue_suspension_timeout_application_define(void *);
void threadx_queue_thread_terminate_application_define(void *);
void threadx_queue_flush_application_define(void *);
void threadx_queue_flush_no_suspension_application_define(void *);
void threadx_queue_front_send_application_define(void *);
void threadx_queue_prioritize_application_define(void *);
void threadx_queue_information_application_define(void *);
void threadx_semaphore_basic_application_define(void *);
void threadx_semaphore_delete_application_define(void *);
void threadx_semaphore_preemption_application_define(void *);
void threadx_semaphore_non_preemption_application_define(void *);
void threadx_semaphore_timeout_application_define(void *);
void threadx_semaphore_thread_terminate_application_define(void *);
void threadx_semaphore_prioritize_application_define(void *);
void threadx_semaphore_ceiling_put_application_define(void *);
void threadx_semaphore_information_application_define(void *);
void threadx_thread_basic_execution_application_define(void *);
void threadx_thread_completed_application_define(void *);
void threadx_thread_relinquish_application_define(void *);
void threadx_thread_simple_suspend_application_define(void *);
void threadx_thread_multiple_suspension_application_define(void *);
void threadx_thread_multiple_non_current_suspension_application_define(void *);
void threadx_thread_multi_level_preemption_threshold_application_define(void *);
void threadx_thread_preemptable_suspension_application_define(void *);
void threadx_thread_basic_time_slice_application_define(void *);
void threadx_thread_multiple_time_slice_application_define(void *);
void threadx_thread_simple_sleep_application_define(void *);
void threadx_thread_simple_sleep_non_clear_application_define(void *);
void threadx_thread_sleep_for_100ticks_application_define(void *);
void threadx_thread_multiple_sleep_application_define(void *);
void threadx_thread_terminate_delete_application_define(void *);
void threadx_thread_exit_callback_transition_application_define(void *);
void threadx_thread_preemption_change_application_define(void *);
void threadx_thread_priority_change_application_define(void *);
void threadx_thread_time_slice_change_application_define(void *);
void threadx_thread_sleep_terminate_application_define(void *);
void threadx_thread_delayed_suspension_application_define(void *);
void threadx_thread_wait_abort_application_define(void *);
void threadx_thread_wait_abort_and_isr_application_define(void *);
void threadx_thread_create_preemption_threshold_application_define(void *);
void threadx_thread_information_application_define(void *);
void threadx_thread_reset_application_define(void *);
void threadx_thread_stack_checking_application_define(void *);
void threadx_thread_stack_fill_value_application_define(void *);
void threadx_time_get_set_application_define(void *);
void threadx_timer_simple_application_define(void *);
void threadx_timer_activate_deactivate_application_define(void *);
void threadx_timer_deactivate_accuracy_application_define(void *);
void threadx_timer_large_timer_accuracy_application_define(void *);
void threadx_timer_multiple_application_define(void *);
void threadx_timer_multiple_accuracy_application_define(void *);
void threadx_timer_information_application_define(void *);
void threadx_trace_basic_application_define(void *);
void test_application_define(void *first_unused_memory);
/* Define the array of test entry points. */
TEST_ENTRY test_control_tests[] =
{
#if CTEST
test_application_define,
#else
threadx_block_memory_basic_application_define,
threadx_block_memory_error_detection_application_define,
threadx_block_memory_prioritize_application_define,
threadx_block_memory_suspension_application_define,
threadx_block_memory_suspension_timeout_application_define,
threadx_block_memory_thread_terminate_application_define,
threadx_block_memory_information_application_define,
threadx_byte_memory_basic_application_define,
threadx_byte_memory_suspension_application_define,
threadx_byte_memory_suspension_timeout_application_define,
threadx_byte_memory_thread_terminate_application_define,
threadx_byte_memory_prioritize_application_define,
threadx_byte_memory_thread_contention_application_define,
threadx_byte_memory_information_application_define,
threadx_event_flag_basic_application_define,
threadx_event_flag_suspension_application_define,
threadx_event_flag_suspension_consume_application_define,
threadx_event_flag_suspension_different_bits_application_define,
threadx_event_flag_suspension_different_bits_consume_application_define,
threadx_event_flag_suspension_timeout_application_define,
threadx_event_flag_thread_terminate_application_define,
threadx_event_flag_single_thread_terminate_application_define,
threadx_event_flag_isr_set_clear_application_define,
threadx_event_flag_isr_wait_abort_application_define,
threadx_event_flag_information_application_define,
threadx_interrupt_control_application_define,
threadx_mutex_basic_application_define,
threadx_mutex_delete_application_define,
threadx_mutex_preemption_application_define,
threadx_mutext_no_preemption_application_define,
threadx_mutex_suspension_timeout_application_define,
threadx_mutex_thread_terminate_application_define,
threadx_mutex_priority_inheritance_application_define,
threadx_mutex_prioritize_application_define,
threadx_mutex_nested_priority_inheritance_application_define,
threadx_mutex_information_application_define,
threadx_queue_basic_application_define,
threadx_queue_basic_two_word_application_define,
threadx_queue_basic_four_word_application_define,
threadx_queue_basic_eight_word_application_define,
threadx_queue_basic_sixteen_word_application_define,
threadx_queue_basic_max_message_size_application_define,
threadx_queue_empty_suspension_application_define,
threadx_queue_full_suspension_application_define,
threadx_queue_suspension_timeout_application_define,
threadx_queue_thread_terminate_application_define,
threadx_queue_flush_application_define,
threadx_queue_flush_no_suspension_application_define,
threadx_queue_front_send_application_define,
threadx_queue_prioritize_application_define,
threadx_queue_information_application_define,
threadx_semaphore_basic_application_define,
threadx_semaphore_delete_application_define,
threadx_semaphore_preemption_application_define,
threadx_semaphore_non_preemption_application_define,
threadx_semaphore_timeout_application_define,
threadx_semaphore_thread_terminate_application_define,
threadx_semaphore_prioritize_application_define,
threadx_semaphore_ceiling_put_application_define,
threadx_semaphore_information_application_define,
threadx_thread_basic_execution_application_define,
threadx_thread_completed_application_define,
threadx_thread_relinquish_application_define,
threadx_thread_simple_suspend_application_define,
threadx_thread_multiple_suspension_application_define,
threadx_thread_multiple_non_current_suspension_application_define,
threadx_thread_multi_level_preemption_threshold_application_define,
threadx_thread_preemptable_suspension_application_define,
threadx_thread_basic_time_slice_application_define,
threadx_thread_multiple_time_slice_application_define,
threadx_thread_simple_sleep_application_define,
threadx_thread_simple_sleep_non_clear_application_define,
threadx_thread_sleep_for_100ticks_application_define,
threadx_thread_multiple_sleep_application_define,
threadx_thread_terminate_delete_application_define,
threadx_thread_exit_callback_transition_application_define,
threadx_thread_priority_change_application_define,
threadx_thread_time_slice_change_application_define,
threadx_thread_sleep_terminate_application_define,
threadx_thread_delayed_suspension_application_define,
threadx_thread_wait_abort_application_define,
threadx_thread_wait_abort_and_isr_application_define,
threadx_thread_create_preemption_threshold_application_define,
threadx_thread_preemption_change_application_define,
threadx_thread_information_application_define,
threadx_thread_reset_application_define,
threadx_thread_stack_checking_application_define,
threadx_thread_stack_fill_value_application_define,
threadx_time_get_set_application_define,
threadx_timer_simple_application_define,
threadx_timer_activate_deactivate_application_define,
threadx_timer_deactivate_accuracy_application_define,
threadx_timer_large_timer_accuracy_application_define,
threadx_timer_multiple_application_define,
threadx_timer_multiple_accuracy_application_define,
threadx_timer_information_application_define,
threadx_trace_basic_application_define,
#endif
TX_NULL,
};
/* Define thread prototypes. */
void test_control_thread_entry(ULONG thread_input);
void test_thread_entry(ULONG thread_input);
void test_thread_entry1(ULONG thread_input);
void test_control_return(UINT status);
void test_control_cleanup(void);
void test_exit_notify(TX_THREAD *thread_ptr, UINT type);
/* Define necessary exernal references. */
#ifdef __ghs
extern TX_MUTEX __ghLockMutex;
#endif
extern TX_TIMER *_tx_timer_created_ptr;
extern ULONG _tx_timer_created_count;
#ifndef TX_TIMER_PROCESS_IN_ISR
extern TX_THREAD _tx_timer_thread;
#endif
extern TX_THREAD *_tx_thread_created_ptr;
extern ULONG _tx_thread_created_count;
extern TX_SEMAPHORE *_tx_semaphore_created_ptr;
extern ULONG _tx_semaphore_created_count;
extern TX_QUEUE *_tx_queue_created_ptr;
extern ULONG _tx_queue_created_count;
extern TX_MUTEX *_tx_mutex_created_ptr;
extern ULONG _tx_mutex_created_count;
extern TX_EVENT_FLAGS_GROUP *_tx_event_flags_created_ptr;
extern ULONG _tx_event_flags_created_count;
extern TX_BYTE_POOL *_tx_byte_pool_created_ptr;
extern ULONG _tx_byte_pool_created_count;
extern TX_BLOCK_POOL *_tx_block_pool_created_ptr;
extern ULONG _tx_block_pool_created_count;
#ifdef EXTERNAL_EXIT
void external_exit(UINT code);
#endif
/* Define the interrupt processing dispatcher. The individual tests will set this up when they desire
asynchrouns processing for testing purposes. */
void test_interrupt_dispatch(void)
{
#ifndef TX_DISABLE_ERROR_CHECKING
/* Test calling tx_thread_relinquish from ISR to see if the error checking throws it out. */
tx_thread_relinquish();
#endif
/* Check for something to run... */
if (test_isr_dispatch)
{
(test_isr_dispatch)();
}
}
/* Define init timer entry. */
static void init_timer_entry(ULONG timer_input)
{
}
#ifndef TX_TIMER_PROCESS_IN_ISR
/* Define the deletion of the system timer thread. */
void delete_timer_thread(void)
{
_tx_thread_terminate(&_tx_timer_thread);
_tx_thread_delete(&_tx_timer_thread);
}
#endif
/* Define main entry point. */
#ifndef EXTERNAL_MAIN
void main()
{
#ifndef TX_MISRA_ENABLE
#ifndef TX_MANUAL_TEST
/* Test the pre-initialize path through _tx_initialize_kernel_enter. */
_tx_thread_system_state = TX_INITIALIZE_ALMOST_DONE;
test_initialize_flag = 1;
/* Call the internal kernel enter function to exercise two paths. */
_tx_initialize_kernel_enter();
_tx_thread_system_state = 0;
#ifndef TX_TIMER_PROCESS_IN_ISR
threadx_delete_timer_thread = 1;
#endif
#endif
#endif
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
#endif
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
UCHAR *pointer;
VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
TX_THREAD *temp_thread;
UINT old_preemption;
UINT status;
ULONG flags;
ULONG temp;
UINT i, j;
#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING)
TX_THREAD *thread_ptr;
#endif
/* Initialize the test error/success counters. */
test_control_successful_tests = 0;
test_control_failed_tests = 0;
test_control_system_errors = 0;
/* Setup a pointer to the first unused memory. */
pointer = (UCHAR *) &test_control_memory[0]; //first_unused_memory;
/* Create the test control thread. */
tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0,
pointer, TEST_STACK_SIZE,
17, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + TEST_STACK_SIZE;
/* Create the test thread. */
tx_thread_create(&test_thread, "test thread", test_thread_entry, 0,
pointer, TEST_STACK_SIZE,
15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + TEST_STACK_SIZE;
/* Create the second test thread. */
tx_thread_create(&test_thread1, "test thread 1", test_thread_entry1, 0,
pointer, TEST_STACK_SIZE,
15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
pointer = pointer + TEST_STACK_SIZE;
/* Suspend the test thread temporarily. */
tx_thread_suspend(&test_thread);
/* Resume the test thread again to exercise the resume code fully. */
tx_thread_resume(&test_thread);
/* Timer change just to exercise the code... an error from initialization! */
test_timer.tx_timer_id = TX_TIMER_ID;
tx_timer_change(&test_timer, 1, 1);
/* Test mutex created and used in initialization. */
test_mutex_from_init = tx_mutex_create(&init_mutex, "init mutex", TX_INHERIT);
test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
test_mutex_from_init += tx_mutex_put(&init_mutex);
test_mutex_from_init += tx_mutex_put(&init_mutex);
test_mutex_from_init = tx_mutex_create(&init_mutex_inherit, "init mutex", TX_INHERIT);
test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
#ifndef TX_DISABLE_ERROR_CHECKING
/* Test timer create from initialization. */
test_block_pool_create_init = tx_block_pool_create(&init_block_pool, "init block pool", 10, init_block_pool_area, sizeof(init_block_pool_area));
/* Test byte pool create from initialization. */
test_byte_pool_create_init = tx_byte_pool_create(&init_byte_pool, "init byte pool", init_byte_pool_area, sizeof(init_byte_pool_area));
test_byte_pool_create_init += tx_byte_allocate(&init_byte_pool, (VOID **) &pointer, 20, TX_NO_WAIT);
test_byte_pool_create_init += tx_byte_release(pointer);
/* Test event flag create from initialization. */
test_event_flags_from_init = tx_event_flags_create(&init_event_flags, "init events");
/* Test queue create from initialization. */
test_queue_from_init = tx_queue_create(&init_queue, "init queue", TX_1_ULONG, init_queue_area, sizeof(init_queue_area));
/* Test semaphore create from initialization. */
test_semaphore_from_init = tx_semaphore_create(&init_semaphore, "init semaphore", 0);
/* Test timer creat from initialization. */
test_timer_create_init = tx_timer_create(&init_timer, "init timer", init_timer_entry, 0x5678,
100, 200, TX_AUTO_ACTIVATE);
/* Test timer change from initialization. */
test_timer_create_init += tx_timer_create(&init_timer_change, "init timer change", init_timer_entry, 0x5678,
100, 200, TX_NO_ACTIVATE);
test_timer_create_init += tx_timer_change(&init_timer_change, 50, 100);
/* Test calling tx_thread_relinquish to see if the error checking throws it out. */
tx_thread_relinquish();
#endif
/* Remember the free memory pointer. */
test_free_memory_ptr = &tests_memory[0]; //pointer;
/* Clear the ISR dispatch. */
test_isr_dispatch = TX_NULL;
/* Ensure that _tx_thread_time_slice can handle NULL thread, note that current thread pointer is NULL at this point. */
_tx_thread_time_slice();
/* Test to make sure _tx_thread_time_slice can handle a none-ready thread. */
init_test_thread.tx_thread_state = TX_IO_DRIVER;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_TRUE;
_tx_thread_current_ptr = &init_test_thread;
_tx_thread_time_slice();
/* Test to make sure _tx_thread_time_slice can handle preemption-threshold set. */
init_test_thread.tx_thread_state = TX_READY;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_priority = 10;
init_test_thread.tx_thread_preempt_threshold = 9;
init_test_thread.tx_thread_ready_next = &init_test_thread;
init_test_thread.tx_thread_ready_previous = &init_test_thread;
_tx_thread_time_slice();
_tx_thread_current_ptr = TX_NULL;
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Test to make sure _tx_thread_shell_entry can handle a NULL mutex release function pointer. */
temp_mutex_release = _tx_thread_mutex_release;
temp_thread = _tx_thread_execute_ptr;
_tx_thread_mutex_release = TX_NULL;
init_test_thread.tx_thread_state = TX_READY;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_FALSE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_current_ptr = &init_test_thread;
_tx_thread_execute_ptr = &init_test_thread;
_tx_thread_entry_exit_notify(&init_test_thread, test_exit_notify);
_tx_thread_shell_entry();
_tx_thread_current_ptr = TX_NULL;
_tx_thread_execute_ptr = temp_thread;
_tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
#endif
/* Test _tx_thread_system_suspend when not current, preemption is needed but disabled. */
temp_thread = _tx_thread_execute_ptr;
init_test_thread.tx_thread_state = TX_READY;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_FALSE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_execute_ptr = &init_test_thread;
#ifndef TX_NOT_INTERRUPTABLE
_tx_thread_preempt_disable++;
#endif
_tx_thread_system_suspend(&init_test_thread);
_tx_thread_execute_ptr = temp_thread;
/* Test _tx_thread_system_resume when not current, suspending and in a COMPLETED state. */
temp_thread = _tx_thread_execute_ptr;
init_test_thread.tx_thread_state = TX_COMPLETED;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_TRUE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_preempt_disable++;
_tx_thread_execute_ptr = &init_test_thread;
_tx_thread_system_resume(&init_test_thread);
_tx_thread_execute_ptr = temp_thread;
/* Test _tx_thread_system_resume when not current, not suspending and already in a TX_READY state. */
temp_thread = _tx_thread_execute_ptr;
init_test_thread.tx_thread_state = TX_READY;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_FALSE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_preempt_disable++;
_tx_thread_execute_ptr = &init_test_thread;
_tx_thread_system_resume(&init_test_thread);
_tx_thread_execute_ptr = temp_thread;
/* Test _tx_thread_system_resume when not current, suspending and in a TERMINATED state. */
temp_thread = _tx_thread_execute_ptr;
init_test_thread.tx_thread_state = TX_TERMINATED;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_TRUE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_preempt_disable++;
_tx_thread_execute_ptr = &init_test_thread;
_tx_thread_system_resume(&init_test_thread);
_tx_thread_execute_ptr = temp_thread;
/* Test tx_thread_resume to test the saved_thread_ptr being NULL. */
temp_thread = _tx_thread_execute_ptr;
_tx_thread_execute_ptr = TX_NULL;
tx_thread_resume(&test_thread1);
tx_thread_suspend(&test_thread1);
_tx_thread_execute_ptr = temp_thread;
/* Test preemption change when the new priority is the same as the threshold. */
init_test_thread.tx_thread_state = TX_SUSPENDED;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_FALSE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_user_priority = 10;
init_test_thread.tx_thread_user_preempt_threshold = 10;
init_test_thread.tx_thread_priority = 10;
init_test_thread.tx_thread_preempt_threshold = 10;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_preemption_change(&init_test_thread, 10, &old_preemption);
#ifndef TX_NOT_INTERRUPTABLE
/* Test semaphore cleanup with an invalid semaphore ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
cleanup_semaphore.tx_semaphore_id = 0;
cleanup_semaphore.tx_semaphore_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_semaphore_cleanup(&init_test_thread, 0);
/* Test semaphore cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
cleanup_semaphore.tx_semaphore_id = 0;
cleanup_semaphore.tx_semaphore_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_semaphore_cleanup(&init_test_thread, 1);
/* Test semaphore cleanup with a NULL semaphore pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
cleanup_semaphore.tx_semaphore_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_semaphore_cleanup(&init_test_thread, 0);
/* Test semaphore cleanup with an valid semaphore ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
cleanup_semaphore.tx_semaphore_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_semaphore_cleanup(&init_test_thread, 0);
/* Test queue cleanup with a NULL cleanup pointer. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
cleanup_queue.tx_queue_id = 0;
cleanup_queue.tx_queue_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_queue_cleanup(&init_test_thread, 0);
/* Test queue cleanup with a NULL queue pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
cleanup_queue.tx_queue_id = 0;
cleanup_queue.tx_queue_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_queue_cleanup(&init_test_thread, 0);
/* Test queue cleanup with an invalid queue ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
cleanup_queue.tx_queue_id = 0;
cleanup_queue.tx_queue_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_queue_cleanup(&init_test_thread, 0);
/* Test queue cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
cleanup_queue.tx_queue_id = 0;
cleanup_queue.tx_queue_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_queue_cleanup(&init_test_thread, 1);
/* Test queue cleanup with an valid queue ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
cleanup_queue.tx_queue_id = TX_QUEUE_ID;
cleanup_queue.tx_queue_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_queue_cleanup(&init_test_thread, 0);
/* Test mutex cleanup with a NULL cleanup pointer. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
cleanup_mutex.tx_mutex_id = 0;
cleanup_mutex.tx_mutex_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_mutex_cleanup(&init_test_thread, 0);
/* Test mutex cleanup with a NULL mutex pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
cleanup_mutex.tx_mutex_id = 0;
cleanup_mutex.tx_mutex_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_mutex_cleanup(&init_test_thread, 0);
/* Test mutex cleanup with an invalid mutex ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
cleanup_mutex.tx_mutex_id = 0;
cleanup_mutex.tx_mutex_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_mutex_cleanup(&init_test_thread, 0);
/* Test mutex cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
cleanup_mutex.tx_mutex_id = 0;
cleanup_mutex.tx_mutex_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_mutex_cleanup(&init_test_thread, 1);
/* Test mutex cleanup with an valid mutex ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
cleanup_mutex.tx_mutex_id = TX_MUTEX_ID;
cleanup_mutex.tx_mutex_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_mutex_cleanup(&init_test_thread, 0);
/* Test event flag cleanup with a NULL cleanup pointer. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
cleanup_event_flags.tx_event_flags_group_id = 0;
cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_event_flags_cleanup(&init_test_thread, 0);
/* Test event flag cleanup with a NULL event flag pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
cleanup_event_flags.tx_event_flags_group_id = 0;
cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_event_flags_cleanup(&init_test_thread, 0);
/* Test event flag cleanup with an invalid ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
cleanup_event_flags.tx_event_flags_group_id = 0;
cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_event_flags_cleanup(&init_test_thread, 0);
/* Test event flag cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
cleanup_event_flags.tx_event_flags_group_id = 0;
cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_event_flags_cleanup(&init_test_thread, 1);
/* Test event flag cleanup with an valid ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
cleanup_event_flags.tx_event_flags_group_id = TX_EVENT_FLAGS_ID;
cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_event_flags_cleanup(&init_test_thread, 0);
/* Test block pool cleanup with a NULL cleanup pointer. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
cleanup_block_pool.tx_block_pool_id = 0;
cleanup_block_pool.tx_block_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_block_pool_cleanup(&init_test_thread, 0);
/* Test block pool cleanup with a NULL block pool pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
cleanup_block_pool.tx_block_pool_id = 0;
cleanup_block_pool.tx_block_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_block_pool_cleanup(&init_test_thread, 0);
/* Test block pool cleanup with an invalid ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
cleanup_block_pool.tx_block_pool_id = 0;
cleanup_block_pool.tx_block_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_block_pool_cleanup(&init_test_thread, 0);
/* Test block pool cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
cleanup_block_pool.tx_block_pool_id = 0;
cleanup_block_pool.tx_block_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_block_pool_cleanup(&init_test_thread, 1);
/* Test block pool cleanup with an valid ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
cleanup_block_pool.tx_block_pool_id = TX_BLOCK_POOL_ID;
cleanup_block_pool.tx_block_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_block_pool_cleanup(&init_test_thread, 0);
/* Test byte pool cleanup with a NULL cleanup pointer. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
cleanup_byte_pool.tx_byte_pool_id = 0;
cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_byte_pool_cleanup(&init_test_thread, 0);
/* Test byte pool cleanup with a NULL byte pool pointer. */
init_test_thread.tx_thread_suspend_control_block = TX_NULL;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
cleanup_byte_pool.tx_byte_pool_id = 0;
cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_byte_pool_cleanup(&init_test_thread, 0);
/* Test byte pool cleanup with an invalid ID. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
cleanup_byte_pool.tx_byte_pool_id = 0;
cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_byte_pool_cleanup(&init_test_thread, 0);
/* Test byte pool cleanup with an invalid suspension sequence. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
cleanup_byte_pool.tx_byte_pool_id = 0;
cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_byte_pool_cleanup(&init_test_thread, 1);
/* Test byte pool cleanup with an valid ID but a suspension count of 0. */
init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
cleanup_byte_pool.tx_byte_pool_id = TX_BYTE_POOL_ID;
cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
init_test_thread.tx_thread_suspension_sequence = 0;
_tx_byte_pool_cleanup(&init_test_thread, 0);
#endif
#ifndef TX_ENABLE_EVENT_TRACE
/* Call ISR trace events when trace is not enabled. */
/* Call trace ISR enter event insert. */
tx_trace_isr_enter_insert(1);
/* Call trace ISR exit event insert. */
tx_trace_isr_exit_insert(1);
#endif
/* Test the list start path in timer info get and timer deactivate. */
test_timer.tx_timer_id = 0;
_tx_timer_create(&test_timer, "init timer", init_timer_entry, 0x5678, 100, 200, TX_AUTO_ACTIVATE);
_timer_list_start_backup = _tx_timer_list_start;
_tx_timer_list_start = _tx_timer_list_end;
_tx_timer_info_get(&test_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
_tx_timer_deactivate(&test_timer);
_tx_timer_list_start = _timer_list_start_backup;
_tx_timer_deactivate(&test_timer);
_tx_timer_delete(&test_timer);
/* Test the stack analyze function with a dummy thread. */
/* Clear the test stack analyze flag. */
test_stack_analyze_flag = 0;
/* Make a fake thread with a fake stack. */
test_thread2.tx_thread_id = TX_THREAD_ID;
#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING)
/* Set the thread pointer. */
thread_ptr = &(test_thread2);
/* Initialize the stack fill value. */
thread_ptr -> tx_thread_stack_fill_value = (0xFEFEFEFEUL);
#endif
for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++)
{
/* Set the fake thread stack to the fill pattern. */
test_thread2_stack[i] = TX_STACK_FILL;
}
/* Setup index to last point. */
i = (sizeof(test_thread2_stack)/sizeof(ULONG)) - 1;
/* Setup the stack start and end pointers. */
test_thread2.tx_thread_stack_start = &(test_thread2_stack[0]);
test_thread2.tx_thread_stack_end = &(test_thread2_stack[i]);
test_thread2.tx_thread_stack_size = sizeof(test_thread2_stack);
test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
test_thread2.tx_thread_stack_ptr = test_thread2.tx_thread_stack_start;
/* Fill 20 words of stack. */
for (j = 0; j < 20; j++)
{
/* Fill the stack with 0s. */
test_thread2_stack[i--] = 0;
}
/* Call the analyze stack function. */
_tx_thread_stack_analyze(&test_thread2);
/* Call it again for no change coverage. */
_tx_thread_stack_analyze(&test_thread2);
/* Fill 99 words of stack. */
for (j = 0; j < 99; j++)
{
/* Fill the stack with 1s. */
test_thread2_stack[i--] = 1;
}
/* Call the analyze stack function. */
_tx_thread_stack_analyze(&test_thread2);
/* Call it again for no change coverage. */
_tx_thread_stack_analyze(&test_thread2);
#ifndef TX_MANUAL_TEST
/* Now set the flag to 1 to cause the thread ID to be cleared. */
test_stack_analyze_flag = 1;
/* Call stack analyze with an ID that is cleared in the middle. */
_tx_thread_stack_analyze(&test_thread2);
/* Restore the ID. */
test_thread2.tx_thread_id = TX_THREAD_ID;
/* Now set the flag to 2 to cause the stack ptr to be equal to the start of the stack. */
test_stack_analyze_flag = 2;
/* Call stack analyze with an ID that is cleared in the middle. */
_tx_thread_stack_analyze(&test_thread2);
test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
/* Now set the flag to 3 to cause the stack pointer to not have the fill pattern. */
test_stack_analyze_flag = 3;
/* Call stack analyze with an ID that is cleared in the middle. */
_tx_thread_stack_analyze(&test_thread2);
#endif
/* Test error condition on _tx_queue_flush. */
test_queue.tx_queue_enqueued = 1;
test_queue.tx_queue_suspended_count = 1;
test_queue.tx_queue_suspension_list = TX_NULL;
/* Call _tx_queue_flush to test the thread NULL check. */
_tx_queue_flush(&test_queue);
#ifndef TX_NOT_INTERRUPTABLE
/* Make sure the suspension cancelled path is exercised in tx_thread_system_resume... This normally happens,
however, sometimes on less real-time platforms the timing is not guaranteed. */
/* Increment the preempt disable flag. */
_tx_thread_preempt_disable++;
/* Build a thread control block with fake info. */
test_thread3.tx_thread_suspending = TX_TRUE;
test_thread3.tx_thread_state = TX_SUSPENDED;
test_thread3.tx_thread_delayed_suspend = TX_FALSE;
test_thread3.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
test_thread3.tx_thread_stack_start = (VOID *) &test_thread2_stack[0];
test_thread3.tx_thread_stack_end = (VOID *) &test_thread2_stack[255];
test_thread3.tx_thread_stack_ptr = (VOID *) &test_thread2_stack[255];
/* Call the system resume function directly to insure the suspension cancel works properly. */
_tx_thread_system_resume(&test_thread3);
#endif
/* Test preempt-disable safeguard. */
/* Increment the preempt disable flag. */
_tx_thread_preempt_disable++;
/* Test block pool suspenson safeguard. */
fake_block_pool.tx_block_pool_available = 0;
status = _tx_block_allocate(&fake_block_pool, (VOID **) &pointer, TX_WAIT_FOREVER);
if (status != TX_NO_MEMORY)
test_control_system_errors++;
/* Test byte pool suspension safeguard. */
fake_byte_pool.tx_byte_pool_fragments = 2;
fake_byte_pool.tx_byte_pool_available = 0;
status = _tx_byte_allocate(&fake_byte_pool, (VOID **) &pointer, 1000, TX_WAIT_FOREVER);
if (status != TX_NO_MEMORY)
test_control_system_errors++;
/* Test event flags suspension safeguard. */
fake_event_flags.tx_event_flags_group_current = 0;
status = _tx_event_flags_get(&fake_event_flags, 1, TX_AND, &flags, TX_WAIT_FOREVER);
if (status != TX_NO_EVENTS)
test_control_system_errors++;
/* Test mutex suspension safeguard. */
fake_mutex.tx_mutex_ownership_count = 1;
fake_mutex.tx_mutex_inherit = 0;
fake_mutex.tx_mutex_owner = &init_test_thread;
status = _tx_mutex_get(&fake_mutex, TX_WAIT_FOREVER);
if (status != TX_NOT_AVAILABLE)
test_control_system_errors++;
/* Test queue front send suspension safeguard. */
fake_queue.tx_queue_available_storage = 0;
status = _tx_queue_front_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
if (status != TX_QUEUE_FULL)
test_control_system_errors++;
/* Test queue receive suspension safeguard. */
fake_queue.tx_queue_enqueued = 0;
status = _tx_queue_receive(&fake_queue, (VOID **) &pointer, TX_WAIT_FOREVER);
if (status != TX_QUEUE_EMPTY)
test_control_system_errors++;
/* Test queue send suspension safeguard. */
fake_queue.tx_queue_available_storage = 0;
status = _tx_queue_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
if (status != TX_QUEUE_FULL)
test_control_system_errors++;
/* Test semaphore suspension safeguard. */
fake_semaphore.tx_semaphore_count = 0;
status = _tx_semaphore_get(&fake_semaphore, TX_WAIT_FOREVER);
if (status != TX_NO_INSTANCE)
test_control_system_errors++;
/* Test thread sleep suspension safeguard. */
_tx_thread_current_ptr = &init_test_thread;
temp = _tx_thread_system_state;
_tx_thread_system_state = 0;
status = _tx_thread_sleep(10);
if (status != TX_CALLER_ERROR)
test_control_system_errors++;
/* Test thread suspend suspension safeguard. */
init_test_thread.tx_thread_state = TX_READY;
status = _tx_thread_suspend(&init_test_thread);
if (status != TX_SUSPEND_ERROR)
test_control_system_errors++;
_tx_thread_system_state = temp;
_tx_thread_current_ptr = TX_NULL;
/* Decrement the preempt disable flag. */
_tx_thread_preempt_disable--;
}
/* Define the test control thread. This thread is responsible for dispatching all of the
tests in the ThreadX test suite. */
void test_control_thread_entry(ULONG thread_input)
{
UINT i;
/* Raise the priority of the control thread to 0. */
tx_thread_priority_change(&test_control_thread, 0, &i);
#ifdef CTEST
test_control_cleanup();
#endif
/* Print out banner. */
printf("********************** ThreadX Validation/Regression Test Suite *********************************\n\n");
/* Print version id. */
printf("Version: %s\n\n", _tx_version_id);
/* Print out the tests... */
printf("Running validation/regression test:\n\n");
/* Loop to process all tests... */
i = 0;
while (test_control_tests[i].test_entry != TX_NULL)
{
/* Clear the ISR dispatch. */
test_isr_dispatch = TX_NULL;
/* Dispatch the test. */
(test_control_tests[i++].test_entry)(test_free_memory_ptr);
/* Clear the ISR dispatch. */
test_isr_dispatch = TX_NULL;
/* Suspend control test to allow test to run. */
tx_thread_suspend(&test_control_thread);
/* Test finished, cleanup in preparation for the next test. */
test_control_cleanup();
}
/* Finished with all tests, print results and return! */
printf("**** Testing Complete ****\n");
printf("**** Test Summary: Tests Passed: %lu Tests Failed: %lu System Errors: %lu\n", test_control_successful_tests, test_control_failed_tests, test_control_system_errors);
#ifndef EXTERNAL_EXIT
exit(test_control_failed_tests + test_control_system_errors);
#else
external_exit(test_control_failed_tests + test_control_system_errors);
#endif
}
void test_control_return(UINT status)
{
UINT old_posture = TX_INT_ENABLE;
printf("********** Running Queue Max Message Size Test (%u) ************** \n ", TX_QUEUE_MESSAGE_MAX_SIZE);
/* Save the status in a global. */
test_control_return_status = status;
/* Ensure interrupts are enabled. */
old_posture = tx_interrupt_control(TX_INT_ENABLE);
/* Determine if it was successful or not. */
if (status)
test_control_failed_tests++;
else
test_control_successful_tests++;
/* Now check for system errors. */
/* Is preempt disable flag set? */
if (_tx_thread_preempt_disable)
{
/* System error - preempt disable should never be set inside of a thread! */
printf(" ***** SYSTEM ERROR ***** _tx_thread_preempt_disable is non-zero!\n");
test_control_system_errors++;
}
/* Is system state set? */
if (_tx_thread_system_state)
{
/* System error - system state should never be set inside of a thread! */
printf(" ***** SYSTEM ERROR ***** _tx_thread_system_state is non-zero!\n");
test_control_system_errors++;
}
/* Are interrupts disabled? */
if (old_posture == TX_INT_DISABLE)
{
/* System error - interrupts should always be enabled in our test threads! */
printf(" ***** SYSTEM ERROR ***** test returned with interrupts disabled!\n");
test_control_system_errors++;
}
/* Resume the control thread to fully exit the test. */
tx_thread_resume(&test_control_thread);
}
void test_control_cleanup(void)
{
TX_MUTEX *mutex_ptr;
TX_THREAD *thread_ptr;
/* Delete all queues. */
while(_tx_queue_created_ptr)
{
/* Delete queue. */
tx_queue_delete(_tx_queue_created_ptr);
}
/* Delete all semaphores. */
while(_tx_semaphore_created_ptr)
{
/* Delete semaphore. */
tx_semaphore_delete(_tx_semaphore_created_ptr);
}
/* Delete all event flag groups. */
while(_tx_event_flags_created_ptr)
{
/* Delete event flag group. */
tx_event_flags_delete(_tx_event_flags_created_ptr);
}
/* Delete all byte pools. */
while(_tx_byte_pool_created_ptr)
{
/* Delete byte pool. */
tx_byte_pool_delete(_tx_byte_pool_created_ptr);
}
/* Delete all block pools. */
while(_tx_block_pool_created_ptr)
{
/* Delete block pool. */
tx_block_pool_delete(_tx_block_pool_created_ptr);
}
/* Delete all timers. */
while(_tx_timer_created_ptr)
{
/* Deactivate timer. */
tx_timer_deactivate(_tx_timer_created_ptr);
/* Delete timer. */
tx_timer_delete(_tx_timer_created_ptr);
}
/* Delete all mutexes (except for system mutex). */
while(_tx_mutex_created_ptr)
{
/* Setup working mutex pointer. */
mutex_ptr = _tx_mutex_created_ptr;
#ifdef __ghs
/* Determine if the mutex is the GHS system mutex. If so, don't delete! */
if (mutex_ptr == &__ghLockMutex)
{
/* Move to next mutex. */
mutex_ptr = mutex_ptr -> tx_mutex_created_next;
}
/* Determine if there are no more mutexes to delete. */
if (_tx_mutex_created_count == 1)
break;
#endif
/* Delete mutex. */
tx_mutex_delete(mutex_ptr);
}
/* Delete all threads, except for timer thread, and test control thread. */
while (_tx_thread_created_ptr)
{
/* Setup working pointer. */
thread_ptr = _tx_thread_created_ptr;
#ifdef TX_TIMER_PROCESS_IN_ISR
/* Determine if there are more threads to delete. */
if (_tx_thread_created_count == 1)
break;
/* Determine if this thread is the test control thread. */
if (thread_ptr == &test_control_thread)
{
/* Move to the next thread pointer. */
thread_ptr = thread_ptr -> tx_thread_created_next;
}
#else
/* Determine if there are more threads to delete. */
if (_tx_thread_created_count == 2)
break;
/* Move to the thread not protected. */
while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread))
{
/* Yes, move to the next thread. */
thread_ptr = thread_ptr -> tx_thread_created_next;
}
#endif
/* First terminate the thread to ensure it is ready for deletion. */
tx_thread_terminate(thread_ptr);
/* Delete the thread. */
tx_thread_delete(thread_ptr);
}
/* At this point, only the test control thread and the system timer thread and/or mutex should still be
in the system. */
}
void test_thread_entry(ULONG thread_input)
{
/* Resume the next test thread. */
tx_thread_resume(&test_thread1);
/* Suspend this thread but with preemption disabled, so we will actually return. */
_tx_thread_preempt_disable++;
tx_thread_suspend(&test_thread);
/* Now perform a fake thread resume to cause preemption and exercise the path in _tx_thread_system_resume that returns to the scheduler. */
init_test_thread.tx_thread_state = TX_TERMINATED;
init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
init_test_thread.tx_thread_new_time_slice = 0;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_suspending = TX_TRUE;
init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
init_test_thread.tx_thread_entry = test_thread_entry1;
_tx_thread_system_resume(&init_test_thread);
/* We should not get back here! */
}
void test_thread_entry1(ULONG thread_input)
{
/* Do nothing, just return! */
}
void test_exit_notify(TX_THREAD *thread_ptr, UINT type)
{
/* Clear the suspending flag to short-circuit the suspension. */
thread_ptr -> tx_thread_suspending = TX_FALSE;
}