diff options
| author | Frédéric Desbiens <[email protected]> | 2026-10-02 10:42:44 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-10-02 10:42:44 -0400 |
| commit | 93387b0a60382a29579bbad5045c68328e3751df (patch) | |
| tree | 42be790d602cb76f55090e5a7c418df7ea2b3428 /test/smp/regression/threadx_thread_stack_fill_value_test.c | |
| parent | 44d7c95c582d415c4ad84527180b29c93c3bf664 (diff) | |
| parent | 28281cd5647d4671236ca08d19bd18ed15b2265a (diff) | |
Merge pull request #783 from eclipse-threadx/devv6.5.2.202603_rel
Merged changes ahead of the v6.5.2.202603 release
Diffstat (limited to 'test/smp/regression/threadx_thread_stack_fill_value_test.c')
| -rw-r--r-- | test/smp/regression/threadx_thread_stack_fill_value_test.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/test/smp/regression/threadx_thread_stack_fill_value_test.c b/test/smp/regression/threadx_thread_stack_fill_value_test.c new file mode 100644 index 00000000..fa6eda22 --- /dev/null +++ b/test/smp/regression/threadx_thread_stack_fill_value_test.c @@ -0,0 +1,190 @@ +/***************************************************************************/ +/* 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 */ +/***************************************************************************/ + +// Portions of this file were generated with AI assistance. + +/* This test checks that the stack fill value recorded in a thread control block is the + value that was actually written into that thread's stack. The two used to disagree + when TX_ENABLE_RANDOM_NUMBER_STACK_FILLING was enabled, because the control block was + cleared after the random value had been chosen and the stack had been filled with it, + which left the stack checking and stack analyze routines looking for a pattern that is + not the one present in the stack. */ + +#include <stdio.h> +#include "tx_api.h" + + +/* Number of probe threads created. A random fill value can legitimately come out as zero, + which hides the defect for that one thread, so several threads are created and at least + one of them is required to have produced a non-zero pattern. */ + +#define TEST_PROBE_THREADS 16 + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_THREAD probe_thread; +static ULONG probe_stack[TX_MINIMUM_STACK / sizeof(ULONG)]; + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_stack_fill_value_application_define(void *first_unused_memory) +#endif +{ + +UINT 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, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Fill Value Test................................ ERROR #1\n"); + test_control_return(1); + } +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ULONG stack_pattern; +UINT non_zero_seen = TX_FALSE; + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Thread Stack Fill Value Test................................ "); + + for (i = 0; i < TEST_PROBE_THREADS; i++) + { + + /* Create a thread that is never started, so that its stack still holds nothing but + the fill pattern and the initial stack frame built at the top of the stack. */ + status = tx_thread_create(&probe_thread, "probe thread", thread_0_entry, 0, + probe_stack, sizeof(probe_stack), + 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #2\n"); + test_control_return(1); + } + + /* Pick up the pattern the create service wrote into the unused part of the stack. */ + stack_pattern = *(((ULONG *) probe_thread.tx_thread_stack_start) + 4); + +#ifndef TX_DISABLE_STACK_FILLING +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* The control block must hold the value that was written into the stack. */ + if (probe_thread.tx_thread_stack_fill_value != stack_pattern) + { + + printf("ERROR #3\n"); + test_control_return(1); + } + + /* The random value is duplicated into all four bytes of the fill value. */ + if ((stack_pattern & 0xFFUL) != + ((stack_pattern >> 24) & 0xFFUL)) + { + + printf("ERROR #4\n"); + test_control_return(1); + } + + if (stack_pattern != ((ULONG) 0)) + { + + non_zero_seen = TX_TRUE; + } +#else + + /* Without random filling, the pattern is the fixed one. */ + if (stack_pattern != ((ULONG) 0xEFEFEFEFUL)) + { + + printf("ERROR #5\n"); + test_control_return(1); + } + + non_zero_seen = TX_TRUE; +#endif +#else + + /* Stack filling is disabled, so there is nothing to compare. */ + non_zero_seen = TX_TRUE; +#endif + + /* Terminate and delete the probe thread so that the next pass starts from a clean + slate. A thread created with TX_DONT_START is suspended rather than completed, + so it must be terminated before it can be deleted. */ + status = tx_thread_terminate(&probe_thread); + + if (status == TX_SUCCESS) + { + + status = tx_thread_delete(&probe_thread); + } + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #6\n"); + test_control_return(1); + } + } + + /* A run in which every fill value came out as zero would prove nothing. */ + if (non_zero_seen != TX_TRUE) + { + + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Success! */ + printf("SUCCESS!\n"); + test_control_return(0); +} |
