summaryrefslogtreecommitdiff
path: root/common_smp
AgeCommit message (Collapse)Author
2026-09-28Made ThreadX object names const-qualifiable behind an option (#761)Frédéric Desbiens
Fixes #61 Object names are exposed as writable pointers throughout the kernel API, which rejects string literals in C++ and lets a caller modify a name an object still holds. Information services return those names through writable double pointers. Create services, control blocks, information services, the module manager and trace registration now preserve const qualification, behind TX_ENABLE_CONST_NAMES. The option defaults to off, so a build that says nothing gets exactly the types it got before. It is opt-in rather than opt-out because it changes the type of a public struct field: application code that copies a name into a writable CHAR * stops compiling, which is a reasonable thing to ask of a minor release and not of a patch one. Issue #780 tracks making it the default in 6.6. Two things the option reaches that its own call sites do not. TX_CHAR_TO_UCHAR_POINTER_CONVERT has exactly two users, both of them reading an object name in _tx_trace_object_register, and every form of that macro but the MISRA one casts the qualifier away without saying so; the conversion is now const in and const out, so nothing launders const to make the build pass. The FreeRTOS adapter holds the name pcTaskGetName retrieves in a TX_NAME_CONST pointer so that it tracks whichever declaration tx_thread_info_get has, and keeps its writable return type through an explicit MISRA C:2012 Rule 11.8 cast, because that signature is part of the FreeRTOS API. Default build: all seven host configurations and all five SMP configurations build with zero warnings and pass -- 113/113 on five host configurations, 100/100 on the two MISRA builds, 118/118 on SMP, 3/3 FreeRTOS. With TX_ENABLE_CONST_NAMES set, the host default and both MISRA configurations, the SMP trace configuration and the FreeRTOS adapter build with zero warnings and pass. Co-authored-by: Tilen Majerle <[email protected]> Assisted-by: Codex (gpt-6-astra) <[email protected]> Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-09-28Silenced the SMP MISRA shim's implicit conversions (#751)Frédéric Desbiens
common_smp/src/tx_misra.c performs four implicit conversions that its monoprocessor twin makes explicit, and ignores a parameter the twin casts to void. Built with the warning set common_smp uses, the file reports five diagnostics that common/src/tx_misra.c does not: tx_misra.c:49 conversion to 'int' from 'UINT' may change the sign of the result tx_misra.c:93 conversion to 'ULONG' from 'int' may change the sign of the result tx_misra.c:151 the same tx_misra.c:221 the same tx_misra.c:624 unused parameter 'status' The two files are otherwise the same shim, so this is drift rather than a deliberate difference: common/src already carries (INT) on the memset value, (ULONG) on the three pointer differences, and (VOID)status. That the shim is the file reporting them is the reason to fix it. It exists to route the kernel's pointer conversions through functions a MISRA analysis can account for, and an implicit signed-to-unsigned conversion inside it is the class of construct it was written to remove. The test trees hide it. test/tx builds the kernel with -Werror, so the monoprocessor copy could never have regressed this way; test/smp has -Werror commented out, so the SMP copy warns and builds. Applying the monoprocessor form to all five sites. Object code is byte identical before and after, compared with --strip-debug at -m32 -std=c99 with TX_MISRA_ENABLE defined, so this changes diagnostics and nothing else. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-09-28Stopped tx_thread_relinquish discarding the rebalance it requests (#758)Frédéric Desbiens
_tx_thread_relinquish walks the ready list at the relinquishing thread's priority for a thread to hand its core to. When the walk reaches one it cannot place, carrying preemption-threshold or excluded from that thread's mapped core, it sets the rebalance flag and breaks. That exit falls into the block concluding no other thread is ready, which is not what the walk found, and that block sets the finished flag. The rebalance at the end of the function is guarded on that flag, so it never runs. Every rebalance requested from inside the walk is discarded, because that exit always reaches the block first. A ready thread behind the obstacle then never reaches a core while the others hold them and relinquish to each other. The tick keeps arriving, so it is a livelock rather than a deadlock. The early return now applies only when no rebalance was requested, which lets control reach the rebalance path the other three request sites already use. threadx_smp_relinquish_rebalance_test fills the cores with threads of one priority relinquishing in a loop, places a thread excluded from every core behind them and a runnable thread behind that, and fails if the runnable one has not run within 100 ticks. It fails 3 of 3 before this change and passes 5 of 5 after. Instrumenting a passing run of threadx_thread_relinquish_test counted 12 rebalance requests from the walk against 4 performed, all 4 from sites outside it. 109/109 in all eight configurations, twice from clean. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-09-15Fixed the simulator ports and thread create paths so they compile when ↵Frédéric Desbiens
TX_MISRA_ENABLE is defined (#742) * Fixed the simulator ports so they compile when TX_MISRA_ENABLE is defined _tx_thread_stack_build() in the four simulator ports converts the fake stack pointer through TX_POINTER_TO_ALIGN_TYPE_CONVERT and TX_ALIGN_TYPE_TO_POINTER_CONVERT. tx_api.h defines both macros only in the non-MISRA branch of its #ifdef TX_MISRA_ENABLE, so with that macro defined the two names are undeclared and none of the four files compiles. Reproduced with: gcc -m32 -c -DTX_MISRA_ENABLE -I common/inc -I ports/linux/gnu/inc \ ports/linux/gnu/src/tx_thread_stack_build.c -o /dev/null which reports both names as implicit declarations and then an int to pointer assignment. The same command without the define compiles cleanly. No build configuration under test/tx/cmake or test/smp/cmake defines TX_MISRA_ENABLE, so CI never compiles these files in that mode. It surfaced on a branch that carries such a configuration. The conversions are now written inline, which is what the non-MISRA macros expand to and what the surrounding port code already does, including the line this replaced. The alternative would be the idiom common/src/tx_thread_create.c uses for the same conversion: an explicit #ifdef selecting the ULONG pair under MISRA. That is not equivalent here. On __x86_64__ this port defines ULONG as unsigned int and ALIGN_TYPE as unsigned long long, so a pointer round-tripped through the ULONG pair loses its top 32 bits. Writing the conversion inline keeps one form that is correct in both modes and on both widths. Verified by compiling the Linux port with and without TX_MISRA_ENABLE, both clean. Assisted-by: Claude Code (Opus 5) <[email protected]> * Fixed the same MISRA build break in the SMP and module manager thread create _tx_thread_create() in common_smp and _txm_module_manager_thread_create() convert the thread's stack start through TX_POINTER_TO_ALIGN_TYPE_CONVERT and TX_ALIGN_TYPE_TO_POINTER_CONVERT with no conditional at all. tx_api.h defines both macros only in the non-MISRA branch, so with TX_MISRA_ENABLE and TX_ENABLE_STACK_CHECKING both defined neither file compiles. It is the same defect as the simulator ports in the previous commit, in two more files. Reproduced with: gcc -c -DTX_MISRA_ENABLE -DTX_ENABLE_STACK_CHECKING \ -I common_smp/inc -I ports_smp/linux/gnu/inc \ common_smp/src/tx_thread_create.c -o /dev/null which reports both names as implicit declarations. Both files now compile with and without TX_MISRA_ENABLE. The conversions are written inline for the same reason as the ports: the #ifdef idiom that common/src/tx_thread_create.c uses selects the ULONG pair under MISRA, which truncates a pointer wherever ALIGN_TYPE is wider than ULONG. That is reported separately. Verified: the SMP regression suite passes 117 of 117, and the ThreadX suite still builds. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-09-15Normalized the AI disclosure comment to one fixed line per file (#740)Frédéric Desbiens
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) <[email protected]>
2026-09-15Restored the random stack fill value cleared during thread creation (#732)Frédéric Desbiens
Fixes #723 With `TX_ENABLE_STACK_CHECKING` and `TX_ENABLE_RANDOM_NUMBER_STACK_FILLING` both enabled, `_tx_thread_create` picked a random byte, stored it in `tx_thread_stack_fill_value`, filled the stack with it -- and then cleared the whole control block with `TX_MEMSET`. The stack held the pattern while the control block claimed zero, so `TX_THREAD_STACK_CHECK` and `_tx_thread_stack_analyze` compared against the wrong value for the entire life of the thread. The value is now computed into a local and written back after the clear. The clear stays where it is, because the module manager's error checking walks the created list before the control block may be touched. Fixed in `common/src/tx_thread_create.c`, `common_smp/src/tx_thread_create.c` and `txm_module_manager_thread_create.c`, where it additionally left a user-mode module thread's kernel stack filled with zeros. `threadx_thread_stack_fill_value_test` creates sixteen unstarted threads and checks each control block against the pattern in its stack, tolerating a random zero byte without letting that hide the defect. Added to both suites: `ERROR #3` on `dev` in `stack_checking_rand_fill_build`, green with the fix. Five tx configurations at 104 tests, five SMP at 117, and all three sources clean under `-Wall -Wextra` across every combination of the four stack-filling switches. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-09-15Allowed tx_timer_change to be called from tx_application_define (#730)Frédéric Desbiens
Fixes #224 `_txe_timer_change` returned `TX_CALLER_ERROR` for any call at or above `TX_INITIALIZE_IN_PROGRESS`, making `tx_timer_change` the only timer service that could not be called from `tx_application_define` -- while still being allowed from an ISR. The check has no technical basis: `_tx_timer_change` only writes the expiration fields of a timer that is not on an active list, with interrupts disabled. Removed it from both the `common` and `common_smp` copies of `txe_timer_change.c`, with the now-unused includes and the `TX_CALLER_ERROR` line in the header comment. Relaxing an error check is backward compatible. `testcontrol.c` in both suites now calls `tx_timer_change` at initialization, so the timer simple test covers it: `ERROR #30` on `dev`, green with the fix. 116/116 SMP, 103/103 non-SMP. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-09-15Masked the SMP remap core maps to silence a false -O2 array bounds error (#728)Frédéric Desbiens
Fixes #469 `_tx_thread_smp_remap_solution_find` indexes `_tx_thread_smp_schedule_list` with the lowest set bit of the core maps it is given. Every caller already masks those maps with `TX_THREAD_SMP_CORE_MASK`, but the compiler cannot see it, so when the function is inlined into `_tx_thread_system_suspend` at `-O2` GCC assumes a bit number as high as 31 and reports an out-of-bounds subscript. `-Werror` turns that into a build failure. Masked the three incoming maps at the top of the function, in both the inline version in `common_smp/inc/tx_thread.h` and the twin in `tx_thread_smp_utilities.c`. The masks are semantic no-ops, so scheduling is unchanged, but the range is now visible to the optimizer. The first core queue entry is also initialized, because the narrowed range lets GCC consider an empty queue and warn about that instead. Reproduced on the Cortex-A9 SMP port with arm-none-eabi-gcc 13.2.1, and clean afterwards across -O2, -O3 and -Os and 2, 4 and 8 core configurations. SMP suite 116/116. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-09-15Guarded _tx_thread_stack_analyze against inverted stack pointers (#727)Frédéric Desbiens
Fixes #460 `TX_ULONG_POINTER_DIF` casts the pointer difference to `ULONG`, so when `tx_thread_stack_highest_ptr` sits below `tx_thread_stack_start` the midpoint wraps to a huge value, the probe lands outside the stack, and the search never converges: the caller hangs or faults. `_tx_thread_stack_analyze` now requires the highest pointer to be strictly above the start of the stack, and bounds the final scan by it. #464 covered the `TX_THREAD_STACK_CHECK` path; this covers direct callers too, as @billlamiework suggested on the issue. Inconsistent pointers still mean a real overflow or a corrupted control block, which remains the application's problem. What changes is that ThreadX reports it through the stack error handler instead of hanging. New cases for an inverted and an equal pointer pair crash the suite without the fix and pass with it. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-09-10Initialized the suspend status before the non-interruptable suspend in ↵Frédéric Desbiens
tx_thread_sleep, so a sleep no longer returns a stale error left over from an earlier timed-out suspension (#725) When TX_NOT_INTERRUPTABLE is defined, _tx_thread_sleep did not set tx_thread_suspend_status to TX_SUCCESS before calling _tx_thread_system_ni_suspend. The interruptable path always did. Nothing else writes that field on behalf of a sleeping thread: _tx_thread_timeout resumes a TX_SLEEP thread directly and there is no suspend cleanup routine for sleep. The value therefore survived from whatever suspension the thread performed last, and tx_thread_sleep returned it. A tx_semaphore_get that timed out with TX_NO_INSTANCE would be followed by a tx_thread_sleep that also returned TX_NO_INSTANCE after sleeping correctly. The same change is applied to the SMP copy, which is identical. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-09-10Refused thread delete and reset while an exit transition is in progress (#724)Frédéric Desbiens
_tx_thread_shell_entry and _tx_thread_terminate both publish a thread's terminal state -- TX_COMPLETED or TX_TERMINATED -- and then call that thread's exit notification callback, before the thread has been detached from the ready list and before either service has finished with the pointer it holds to the control block. That terminal state is exactly the state _tx_thread_delete and _tx_thread_reset accept as authorization to invalidate or rebuild the control block, and neither service tested whether the transition producing it had finished. A callback could therefore delete the thread it was called for -- and then lawfully recreate it over the same memory, since delete exists to permit that -- while the scheduler was still linked to the old incarnation. tx_thread_create zeroes the whole control block and can auto-start the new one, so the old priority list is left heading at a block whose own priority field names a different list, with the old priority's map bit set behind nothing. Alternatively a callback could reset a terminated thread, which moves it out of the terminal state, and then resume it: the interrupted- suspension logic in _tx_thread_system_resume refuses to void a suspension only while the state is still terminal, so with the reset allowed first the resume clears the suspending flag and restores TX_READY, the outer service then finds the flag clear and skips the removal, and tx_thread_terminate returns TX_SUCCESS for a thread that is runnable again. Interrupt masking does not close the window, because the kernel restores the prior posture before invoking the callback deliberately. On SMP TX_RESTORE also releases the global protection, so the target can be executing on another core while its callback runs -- and a reset there memsets the stack a live core is running on. On the Linux, Win32 and Win64 host simulation ports the consequence is more immediate than corruption: TX_THREAD_DELETE_PORT_COMPLETION cancels and joins the host thread backing the deleted thread, so a callback-side delete of the completing thread destroys the host thread the callback is running on. The fix marks the transition and has the two services refuse a marked target, returning the errors they already document, TX_DELETE_ERROR and TX_NOT_DONE. The refusal is transient and the same call succeeds once the transition has completed, so no documented lifecycle is lost; and it is in the core services rather than the _txe_ wrappers, so disabling error checking cannot disable it. Refusing the reset is also what closes the resume path, without touching _tx_thread_system_resume: its existing terminal-state test is sufficient once nothing can turn the terminal state into TX_SUSPENDED from inside the window. tx_thread_suspending is the marker, rather than a new control-block field. It already means "a suspension is in progress" and is already true across the callback in the two interruptable paths, so no field is added, the public structure is unchanged, and sizeof(TX_THREAD) is unchanged -- which matters, because the Module Manager's object handling depends on the sizes of the control blocks. Widening its lifetime was checked against every reader rather than assumed. There are four: two in _tx_thread_system_suspend and two in _tx_thread_system_resume. In every window this change widens, the state is TX_COMPLETED or TX_TERMINATED, and both resume readers already refuse to void a suspension for exactly those two states, so their behaviour is unchanged; and no suspension routine is called on the target in those windows, so the suspend readers never see them. No suspension-initiating service can set the marker again inside a window either: every one of them acts on a thread that is ready or suspended. Three sites needed changing beyond the two refusals, and the shape of each was decided by where the marker can safely be cleared: - The non-ready branch of _tx_thread_terminate cleared the marker before the terminated extension and the callback, which is what left them free to act on a control block the service still had mutex-release processing to do against. The clear moves to the common tail, after the last dereference of the target, and becomes the single clear site for the whole service. In the interruptable ready branch the flag is already false there, because _tx_thread_system_suspend cleared it when it detached the thread, so the tail store is a second store of a value the flag already holds -- cheaper than testing for it, and it keeps one clear site. - Under TX_NOT_INTERRUPTABLE neither path set the marker at all, because that configuration does not use the interruptable suspension path that sets it. Both now set it before the callback. Interrupts being disabled there does not help: the callback is reached by a direct call. - In the TX_NOT_INTERRUPTABLE completion path the marker is cleared before _tx_thread_system_ni_suspend rather than after it. That call returns to the scheduler for a thread that is the current thread, which a completing thread is, and does not come back; clearing afterwards would leave a normally completed thread marked for ever and therefore permanently undeletable. Nothing is lost by clearing early there, because everything from that point to the detachment runs with interrupts disabled and calls no application code. The change is the same change twice. All four files are byte-for-byte identical between common and common_smp at this commit and stay so after it, so common_smp was written by copying rather than by repeating the edits. tx_thread_system_suspend.c and tx_thread_system_resume.c, which do differ between the kernels, are deliberately untouched. Tests. The in-tree regression test goes to both trees and is byte-for-byte identical between them. It drives seven scenarios: terminating a ready non-current target with two peers ready at the same priority, with the callback attempting the delete and recreating the block if it succeeded; the same with the callback attempting the reset and then the resume; terminating a target suspended on a semaphore while owning a mutex, which is the non-ready branch; natural completion alone at its priority, including the safe post-completion reset, terminate, delete and recreate at another priority; self termination; a benign callback, whose notification count and ordering are unchanged; and the state and boundary cases, where the new refusal must not fire. It measures rather than describes. The callback records the published state, the marker, and the status of every lifecycle service it can reach, calling the core service as well as the wrapper wherever a refusal is expected. A snapshot taken under interrupt lockout -- which is the global SMP protection on an SMP port -- checks that every ready list agrees with the control blocks it heads, that the priority map agrees with the lists, and that each execute pointer is a member of the list its own priority field names. Every walk is bounded, so a corrupted ring costs an assertion and not a hang, and no test in the suite can hang. Expectations are counted inside a scenario and gated between scenarios, so a failing kernel reports how much it failed by without being driven further into its own corruption. The consequences are demonstrated from the terminator's context rather than the completing thread's, which is what makes the pre-fix behaviour an assertion instead of a wedged simulator. Compiled against the unfixed sources the test fails 9 of the 24 expectations it reaches in the uniprocessor tree and 10 of 24 in the SMP tree, and the failures are the finding: the callback-side delete succeeds, the recreate succeeds, the consistency snapshot disagrees, the target is neither terminal nor detached when the service returns, and a peer has left the ready ring the recreated block hijacked. The SMP tree gets a second test for the case that needs concurrency. The victim is excluded to core 1 and spins there without relinquishing while the controller, excluded to core 0, terminates it, so the callback runs on one core while the target executes on another. The callback-side reset and delete must both be refused, and a sentinel written into the unused low end of the victim's stack must survive -- a reset would have memset the whole stack before rebuilding the frame. Every wait is bounded, and if the remote precondition cannot be established the test says so and drops only the assertions that depend on it rather than reporting a pass it did not earn; measured over twenty consecutive runs it established the precondition every time. TX_NOT_INTERRUPTABLE and TX_DISABLE_ERROR_CHECKING are not among the five build configurations either tree compiles, and each tree builds the whole library once per configuration, so neither can be reached from inside the suites. The lines this change adds under TX_NOT_INTERRUPTABLE are therefore in no configuration the trees build, and they are where the permanent- undeletability failure mode lives, so they get their own harness rather than a compile check: the four sources plus the two error wrappers are compiled directly into a test executable, once per combination, with recorders standing behind the scheduler services they call. That is what makes the marker's value at the moment of detachment directly observable. It runs 66 expectations under TX_NOT_INTERRUPTABLE, 66 under that with error checking disabled, 45 under that with notification disabled, and 63 under error checking disabled alone; against the unfixed sources those fail 25, 22, 6 and 20 respectively. The harness lives in the uniprocessor tree only, because the four sources are identical between the kernels and the shim replaces the very primitive the SMP port differs in, so a second copy would compile the same text under the same macros. It is deliberately left out of the coverage instrumentation, since the same source under different feature macros has a different line set and merging those would confuse the union rather than add to it. Results. Both suites pass in all five configurations with GCC 14: 103 of 103 in the uniprocessor tree, up from 98, and 116 of 116 in the SMP tree, up from 114. Merged line coverage is 100% in the uniprocessor tree and 5172 of 5183 in the SMP tree, whose eleven uncovered lines are the same eleven that were uncovered before this change and are in tx_byte_pool_search and tx_thread_smp_utilities; all four changed files are at 100% line coverage in both trees, and SMP branch coverage rises from 2819 of 3548 to 2831 of 3556. Cross-compiled with arm-none-eabi-gcc at -Wall -Wextra for Cortex-M4 against common and for Cortex-A7 SMP against common_smp, all four files produce no diagnostics at all and an identical warning set to before the change, under -std=gnu99 and -std=c99 alike -- unlike the module ports, -std=c99 does not fail on these base ports, and even -Wconversion is clean. No MISRA deviation is required: explicit comparisons to TX_TRUE, existing ThreadX types, single-entry and single-exit control flow, no goto, and two added constant-time tests that change no real-time complexity. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-09-10Made the stack analyze binary search require several consecutive fill words, ↵Frédéric Desbiens
so unwritten holes in a used stack no longer cause the highest stack pointer to be under-reported (#720) The binary search in _tx_thread_stack_analyze() accepted a probe location as unused as soon as a single word still held TX_STACK_FILL. A word inside an otherwise used region that simply was never written - the padding of a partially initialized local array, for example - therefore made the search move away from the real boundary and report far less stack usage than the thread had actually consumed, which in turn kept the stack guard from firing. The probe now walks down from the candidate location and requires TX_THREAD_STACK_ANALYZE_FILL_WORDS consecutive fill words before it treats the location as unused, stopping early at the lowest location already known to hold the fill pattern. The new macro defaults to eight words and can be overridden in tx_port.h; setting it to one restores the previous behavior. Holes shorter than the configured run no longer mislead the search, and the result is unchanged for stacks that contain no such holes. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-08-20Stopped the SMP stack check analyzing a stack it just found broken (#648)Frédéric Desbiens
TX_THREAD_STACK_CHECK detects a broken stack, calls the error handler, and then tests whether the word below the high-water mark still holds the fill pattern. On the SMP side that second test is a plain if, so a thread whose stack has just been reported as corrupt goes straight on into _tx_thread_stack_analyze(). Analyzing a stack that is known to be broken is what that function is least able to do. It binary searches between stack_lowest and stack_highest for the fill pattern and then scans forward with while (*stack_ptr == TX_STACK_FILL) which has no bound of its own and no reason to terminate once the pattern it is looking for is no longer where the pointers say it should be. The non-SMP copy was given an else for exactly this reason. The SMP copy never was, and the two macros are otherwise identical, line for line, so this single keyword was the whole of the divergence. The path is live in CI rather than theoretical. Instrumenting the internal handler and running all 110 binaries of stack_checking_build shows threadx_thread_stack_checking_test reaching it four times per run, on a thread whose stack the test corrupts on purpose. Every one of those four currently falls through into the analyze it should be skipping. This is not the timeout the SMP suite has been failing on. threadx_thread_priority_change never reaches the error handler at all, so whatever wedges it in teardown is something else. Worth closing regardless: a runaway scan inside stack analysis would present as a test that stops producing output and is eventually killed, which is the shape that has been costing this suite whole runs, and it would be indistinguishable in the log from the hang already being chased. Verified on both configurations that define TX_ENABLE_STACK_CHECKING. threadx_thread_stack_checking_test, the one test that exercises the changed branch, passes 60 consecutive runs, and stack_checking_build and stack_checking_rand_fill_build both pass 110 of 110, repeated at the parallelism CI uses. Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-05-26Added win64 ports of ThreadX and ThreadX SMP (#529)Frédéric Desbiens
Windows x64 port and regression suite This PR adds the Windows x64 (Win64) simulation port for both the standalone and SMP variants of ThreadX, along with the full CMake build and test infrastructure needed to run the regression suite on Windows. New ports Win64 standalone (ports/win64/vs_2022): self-contained Windows simulation port using Win32 threading primitives as virtual cores. Includes CMake integration, build/test scripts, and MSVC project files. Win64 SMP (ports/win64_smp/vs_2022): multi-core Windows simulation port. Supports up to 4 virtual cores backed by Windows host threads. Scheduler and timer improvements The initial port used coarse polling and synchronous SuspendThread/ResumeThread pairs throughout the scheduler hot path. Several rounds of optimization reduced the SMP regression suite runtime from ~150 s to ~78 s (-48%), with no regressions: - Replaced scheduler polling with an event-driven wake path; switched the simulated timer to one-shot rearming to eliminate catch-up ticks. - Skip SuspendThread when _tx_thread_preempt_disable != 0 (new suspension type 3) -- the primary optimization, yielding up to 7.9x speedup on preemption-heavy tests. - Skip SuspendThread when a thread is spinning on the Win32 critical section (suspension type 4), and fix a stale-TLS bug in _tx_win32_critical_section_obtain that could stamp mutex_access on the wrong virtual core. - Added a 2 ms scheduler event timeout (matching the Linux SMP port) to prevent stalls on any missed SetEvent. - Enabled high-resolution waitable timers (SetWaitableTimerEx) for accurate 100 Hz tick cadence. - Increased TX_WIN32_CONTENTION_PAUSE_COUNT from 64 to 256 to reduce SwitchToThread overhead under heavy CS contention. Build and test infrastructure - Hardened the Windows build wrapper (scripts/build_tx.ps1): invoke Ninja directly for Ninja build trees, fix timeout detection, add a default build timeout, and limit fallback replay to real timeout cases. - Added -Clean support to Windows test scripts to remove stale CTest state before each run. - Skip Visual Studio DevShell re-entry when the active MSVC environment already matches the requested architecture. - Fixed scripts/build_tx.sh (Linux) regression source generation: replaced brittle exact-string insertion with line-based matching so the interrupt dispatcher hook is inserted reliably for both simulator ports. Test suite updates - Introduced test/tx/regression/threadx_test_port.h with portable macros (TX_TEST_POINTER_WORD, TX_TEST_STORE_POINTER) for storing pointers in test arrays on 64-bit targets where ULONG remains 32-bit. - Adjusted pool-capacity and pointer-storage patterns in regression tests to use ALIGN_TYPE-sized slots, making the suite correct on 64-bit hosts. - Restored stricter event flag, sleep, and timer expectations now that port-level fixes make prior Windows accommodations unnecessary. - Tightened SMP watchdog and clean-build timeout defaults. Version metadata Updated Win32, Win64, and Win64 SMP port version strings to 6.5.1.202602. Co-authored-by: Copilot <[email protected]> Co-authored-by: Codex (gpt 5.5) <[email protected]>
2026-04-15build: add conditional CMake support for ThreadX SMPFrédéric Desbiens
- Introduce THREADX_SMP option in root CMakeLists.txt. - Implement conditional source and port directory selection for SMP builds. - Add CMake support for common_smp and Cortex-A9 SMP port. - Fix linker flags in Cortex-A9 SMP sample build script. - Remove duplicate invalidateCaches_IS declarations in v7.h headers. Assisted-by: Gemini (Experimental)
2026-03-05Updated copyright headers and version number constants (#509)Frédéric Desbiens
* Updated version number constants * Removed revision history from all files * Added Eclipse ThreadX contributors' copyright header
2026-02-26Added a missing symbol to tx_api.h for TX SMP.Frédéric Desbiens
2026-01-09Updated the version numberFrédéric Desbiens
2025-11-25fix typo TX_BYTE_POOL_DELAY_VALUE instead of TX_BTYE_POOL_DELAY_VALUEMAY
2025-09-28Updated version number and added build and hotfix.Frédéric Desbiens
2025-09-28Added missing check for TX_QUEUE_MESSAGE_MAX_SIZE.Frédéric Desbiens
2025-02-24Updated version number to 6.4.2.Frédéric Desbiens
2024-02-27Update version number to 6.4.1TiejunZhou
2024-01-30Update version id string.Bo Chen (from Dev Box)
2024-01-29Update copyright.Bo Chen (from Dev Box)
2023-12-28Update release date and version (#338)TiejunZhou
* Update version number in API header * Update release date and version
2023-10-23Update release version to 6.3.0 and date to 10-31-2023 (#308)v6.3.0_relTiejunZhou
2023-05-18Fix MISRA issues for ThreadX SMP (#263)TiejunZhou
* Fixed MISRA2012 rule 10.4_a The operands `pool_ptr->tx_byte_pool_fragments' and `2' have essential type categories unsigned 32-bit int and signed 8-bit int, which do not match. * Fixed MISRA2012 rule 10.4_a The operands `next_priority' and `TX_MAX_PRIORITIES' have essential type categories unsigned 32-bit int and signed 8-bit int, which do not match. * Fixed MISRA2012 rule 8.3 Declaration/definition of `_tx_thread_smp_preemptable_threads_get' is inconsistent with previous declaration/definition in types and/or type qualifiers
2023-05-12Add random number stack filling option. (#257)Xiuwen Cai
Co-authored-by: TiejunZhou <[email protected]>
2023-03-08Release 6.2.1 on 08 Mar 2023. Expand to see details.v6.2.1_relTiejun Zhou
cee19603d Include tx_user.h conditionally. e40e08007 Update owners d69641273 Update release date and version 394aee52f Add tx_user.h to GNU port assembly files 5cca2ddd0 RISC-V 64 bit port for Microchip e0f2c373c Link Winmm.lib that required by the high-resolution timer. 6af472a68 Update Win32 port with high resolution timer. aea7b556a Add DMB ISH barrier inst in ARMv8-A SMP scheduler 19091a262 Add .section .preamble to m3 m4 m7 module ports ced60e1b7 Add missing parenthesis in ports assembly file 309dc77ca Modules Cortex-A7 IAR new port c752a4063 Modules Cortex-A7 GNU new port dc224b90f Fix race condition in tx_thread_wait_abort and update regression test 6e261f5b7 create threadx cmsis-pack
2022-10-26Release 6.2.0v6.2.0_relTiejun Zhou
2022-07-26Release 6.1.12v6.1.12_relYuxin Zhou
2022-04-20Release 6.1.11Yuxin Zhou
2022-01-29Release 6.1.10Yuxin Zhou
2021-10-14Release 6.1.9Yuxin Zhou
2021-07-28Release 6.1.8v6.1.8_relYuxin Zhou
2021-06-02Release 6.1.7Bo Chen
2021-04-03Release 6.1.6v6.1.6_relYuxin Zhou
2021-03-05Release 6.1.5v6.1.5_relYuxin Zhou
2021-01-08update to v6.1.3Scott Larson
2020-11-10patch release 6.1.2v6.1.2_relScott Larson
2020-10-166.1.1 patch: add stack sealing to armv8-m, fix misra warning, fix stack ↵v6.1.1_relScott Larson
check link error
2020-09-306.1 minor releaseScott Larson
2020-08-14apply 6.0.2 patchScott Larson
2020-08-07add SMP, Modules, and more processor/tools releasesScott Larson