From ebeb02b95828ca100c3f24de5f9603a41049f8ff Mon Sep 17 00:00:00 2001 From: Tiejun Zhou Date: Mon, 3 Apr 2023 07:24:52 +0000 Subject: Release ThreadX regression system --- .../threadx_thread_stack_checking_test.c | 224 +++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 test/smp/regression/threadx_thread_stack_checking_test.c (limited to 'test/smp/regression/threadx_thread_stack_checking_test.c') diff --git a/test/smp/regression/threadx_thread_stack_checking_test.c b/test/smp/regression/threadx_thread_stack_checking_test.c new file mode 100644 index 00000000..3ffe3841 --- /dev/null +++ b/test/smp/regression/threadx_thread_stack_checking_test.c @@ -0,0 +1,224 @@ +/* This test is for the thread stack checking services. */ + +#include +#include "tx_api.h" + + +/* Prototype for direct call. */ + +VOID _tx_thread_stack_analyze(TX_THREAD *thread_ptr); + + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static CHAR *thread_2_stack_start; +static UINT stack_error = 0; + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); +static void thread_1_entry(ULONG task_input); +static void thread_2_entry(ULONG task_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the stack checking error handler. */ + +void stack_error_handler(TX_THREAD *thread_ptr) +{ + + /* Check for the right thread. */ + if (thread_ptr == &thread_2) + stack_error = 1; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_stack_checking_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + thread_2_stack_start = pointer; + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #3\n"); + test_control_return(1); + } + + /* Register the stack checking handler. */ + status = tx_thread_stack_error_notify(stack_error_handler); + +#ifdef TX_ENABLE_STACK_CHECKING + /* Check for status. */ + if (status != TX_SUCCESS) +#else + if (status != TX_FEATURE_NOT_ENABLED) +#endif + + { + + printf("Running Thread Stack Checking Test.................................. ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Thread Stack Checking Test.................................. "); + + /* Resume thread 1 to get the stack checking to take place. */ + status = tx_thread_resume(&thread_1); + + /* Suspend to allow thread 1 to run. */ + tx_thread_suspend(&thread_0); + + /* Terminate thread 1. */ + status = tx_thread_terminate(&thread_1); + + /* Check error code. */ +#ifdef TX_ENABLE_STACK_CHECKING + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 1)) +#else + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 0)) +#endif + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + else + { + + /* Success! */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +TX_THREAD fake_thread; + + /* Call stack analyze with a NULL pointer. */ + _tx_thread_stack_analyze(TX_NULL); + + /* Call the stack analyze with a fake stack just to test that path. */ + fake_thread.tx_thread_id = 0; + _tx_thread_stack_analyze(&fake_thread); + + /* Call the stack analyze with a NULL stack pointer. */ + fake_thread.tx_thread_id = ((ULONG) 0x54485244); + fake_thread.tx_thread_stack_start = TX_NULL; + _tx_thread_stack_analyze(&fake_thread); + + /* Call the stack analyze with a NULL highest stack pointer. */ + fake_thread.tx_thread_id = ((ULONG) 0x54485244); + fake_thread.tx_thread_stack_start = (void *) 0x1000; + fake_thread.tx_thread_stack_highest_ptr = TX_NULL; + _tx_thread_stack_analyze(&fake_thread); + + /* Clear the pattern in thread 2's stack. */ + TX_MEMSET(thread_2_stack_start, (CHAR) 0x11, TEST_STACK_SIZE_PRINTF); + + /* Resume thread 2, which should cause the stack error to occur. */ + tx_thread_resume(&thread_2); + + /* Suspend thread 2. */ + tx_thread_suspend(&thread_2); + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Now, deregister the stack error handler and get into a spin condition. We will then + want to terminate thread 1 from thread 0 when it awakes! */ + tx_thread_stack_error_notify(TX_NULL); + + /* Now resume thread 2 again to cause the stack error! */ + tx_thread_resume(&thread_2); + + /* Now suspend thread 2 again. */ + tx_thread_suspend(&thread_2); + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Increment thread 1 counter. */ + thread_2_counter++; +} -- cgit v1.3.1