ThreadX still declares 6.5.1.202602 with hotfix 'a', which is the previous
release rather than the one being cut.
prepare_release.sh updated the five version constants in tx_api.h and the
version string in 211 port headers across ports, ports_smp, ports_arch and
ports_module. The hotfix letter is cleared, since the target has none. Nothing
else changed: every line in the port commit carries a version, and no file
outside an inc/tx_port.h was touched.
The port consistency checks passed before the branch was cut, which is what the
script gates on. Host regression 113/113 with zero warnings, and the AI
disclosure check passes.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
* Normalized the AI disclosure line across every tracked file type
The repository-wide pass covered source files only, so build files, CMake
toolchain files, shell scripts and the GDB and manifest files kept the older
per-edit form of the disclosure comment, which names a product and a model
version. The Cortex-R52 module manager port then merged after that pass and
brought the old form back into the sources as well.
Replaced it with the fixed text in all of them, using the comment character
each file already uses.
Comment-only. 143 files, one line each. The repository now holds 601 files
carrying exactly one disclosure line, none carrying the old form, and none
carrying more than one.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
* Added a check that keeps the AI disclosure comment in its one accepted form
Nothing enforced the disclosure convention, so the drift it exists to prevent
returned twice: once when a port merged after the normalisation pass carrying
the older per-edit form, and once because that pass had covered source files
only, leaving build files and scripts untouched for months.
Added scripts/check_ai_disclosure.sh, which rejects the superseded per-edit
form, a doubled comment marker, more than one disclosure line in a file, and
any spelling of the line that is not exact. It runs from repo_checks.yml, a
workflow with no path filter, because a source-path filter is what hid the
build files the first time.
The check passes on this branch. Each of its four rules was confirmed to fail
on a tree with that defect reintroduced, and to pass once it was removed.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
* Normalised the disclosure lines that landed after this branch
Thirteen files reached dev after this branch was written, each carrying the
superseded per-edit form. txm_module_manager_dispatch.h reached it with six
stacked copies, naming the same product and the same model every time -- the
accumulation the fixed text exists to prevent.
Each of those files now carries one disclosure line in the accepted form. Where
the accepted line was already present, the superseded ones are deleted rather
than converted, so no file gains a second.
check_ai_disclosure.sh reported eighteen hits across thirteen files before the
pass and passes after it.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
* Exempted Markdown from the near-miss disclosure check
The near-miss rule flags any line carrying the phrase "AI assistance" that is
not the accepted text, which is right for source but wrong for documentation.
The contribution guide has to quote the accepted line and say when it applies,
so the check reports two paragraphs of prose as drift and fails the build.
Markdown is now exempt from that rule alone. The three rules that matter for a
documentation file -- superseded form, doubled comment marker, duplicate line
-- still scan it, so a stale disclosure in a Markdown file is still caught.
The check passes against a tree carrying the rewritten contribution guide, and
still fails when a near miss is planted in a source file.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
* Corrected the trailer command named in the disclosure check
The header comment points a reader at git's own trailer parser to find out
which agents have touched a file. That parser reads trailers only from a block
at the very end of a message, so a squash merge -- which concatenates a
branch's messages -- buries every trailer but the last one mid-message, and an
indented trailer is skipped outright. On dev it finds 122 attributions where
163 exist.
The comment now names count_assisted_by.sh, which reads whole bodies.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
_tx_thread_smp_unprotect takes the Linux mutex on entry and releases it twice when the
protection structure names this core, but only once when it does not, while the matching
_tx_thread_smp_protect took it once either way. _tx_thread_system_return clears the
protection outright, so an unprotect can find it no longer naming its core and return
having released one level fewer than were taken.
A thread that later reaches _tx_linux_mutex_release_all drains that level. The timer
interrupt thread has none on its tick path unless a thread was preempted on core 0, so a
level leaked there while core 0 is idle is never recovered: the nesting count never
reaches zero, the mutex is never handed back to Linux, and every other thread waits on
it for the life of the process while the tick keeps arriving.
The release of the level the matching protect took now happens whether or not the
protection still names this core. Protection bookkeeping and scheduling are unchanged,
and releasing beyond what a thread holds was already a no-op.
Two hung processes captured untraced, in different tests, show the timer thread owning
the mutex with a nesting count of one while parked in its tick wait, the scheduler
blocked in pthread_mutex_timedlock, and the clock advancing 99 ticks a second across a
ten second sample while nothing else changes. On a healthy run that path is taken 0
times in 26,546 unprotect calls. Forcing it on the timer thread leaks one level before
this change and balances after it.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The SMP Linux port suspends a thread with a signal whose handler calls sigsuspend
and does not return until the thread is resumed. That signal can arrive while the
thread is parked in pthread_mutex_lock on _tx_linux_mutex; the port knows it can,
because _tx_linux_mutex_obtain sets tx_thread_linux_mutex_access around the lock
call for exactly this case, and nothing anywhere reads that flag.
glibc waits for a contended mutex in a loop that re-arms the futex wait after a
signal, and this handler never returns to it. The next release hands its wake-up
to that thread, which will not act on it, and any other thread parked on the
mutex is never woken, leaving the mutex free with waiters on it. That deadlocks
the process: the only thread that can resume the suspended one is the scheduler,
and the scheduler takes this mutex on every pass.
_tx_linux_mutex_obtain now waits with pthread_mutex_timedlock and retries, so the
wait is re-armed every TX_LINUX_MUTEX_RETRY_NSEC and a lost wake-up costs one
retry period instead of the process. The period is one millisecond, half the
scheduler's own idle period. Nothing else changes.
Four hung processes captured untraced, across three tests, show the same state: a
thread in sigsuspend on top of pthread_mutex_lock, the scheduler blocked in
pthread_mutex_lock, and the mutex reading free. Standalone,
threadx_smp_random_resume_suspend_exclusion_test hung 3 times in 100 runs and 2
in 55 before the change and 0 in 400 after it.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
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
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
Both Linux ports define TX_TRACE_TIME_SOURCE as _tx_misra_time_stamp_get() when
TX_MISRA_ENABLE is set, and neither implements that function, so both inherit
the generic `return(0);` from tx_misra.c. Every trace event is stamped zero.
The buffer carries no timing, and the kernel's own check for an entry having
been overwritten -- time_stamp against the entry's own stamp, in the block and
byte allocates and in the system suspend and resume -- compares zero with zero,
so it never fires and a service patches whatever now occupies the slot.
Both ports now read in MISRA builds the clock they already read otherwise,
_tx_linux_time_stamp.tv_nsec, which TX_TRACE_PORT_EXTENSION refreshes on every
recorded event in both forms of the insert. The non-SMP port's non-MISRA macro
carried a trailing semicolon, which made it a statement and is why the MISRA
insert -- which takes the time source as a function argument -- could not use
it; that is dropped and the two branches become one definition. Both headers
keep the _tx_misra_time_stamp_get declaration, because tx_misra.c still defines
it and is compiled for these ports.
The MISRA insert evaluates its time source before the callee refreshes the
clock, so each entry carries the reading taken at the previous recorded event.
Stamps are real, distinct and ordered, which is what the overwrite check needs.
The trace entry update test gains an assertion that the buffer holds an entry
the port actually stamped. It fails on dev with ERROR #13 under
misra_trace_build and passes with this change. Suites green: 7/7 ThreadX
configurations, 5/5 SMP.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
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
* 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) <noreply@anthropic.com>
* 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) <noreply@anthropic.com>
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
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>
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
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
The context save, vectored context save and system return routines in the
ARMv7-A ports carried pseudo-code comments claiming that they saved the
thread stack pointer and then switched to _tx_thread_system_stack_ptr.
Neither of those things happens, and none of these ports references that
variable outside an unused IMPORT in their example builds.
On ARMv7-A each processor mode has its own banked stack pointer. The IRQ
handler branches to _tx_thread_context_save while still in IRQ mode, so the
core's banked IRQ stack already serves as the system stack, and the thread
stack pointer is stored in the control block by _tx_thread_context_restore,
and only when the interrupt results in preemption. The scheduler runs on the
banked SVC mode stack that the startup code sets up. There is nothing for a
software stack switch to do.
The comments were therefore misleading rather than merely redundant, and had
led at least one user to try to restore the code they described. They are now
replaced by a description of the actual mechanism.
The AArch64 SMP ports keep their comments unchanged, because ARMv8-A does not
bank a stack pointer per processor mode and those ports do reload
_tx_thread_system_stack_ptr[core] explicitly.
This is a comment-only change. Every changed line is a comment, and all
twenty-five GNU variants still assemble cleanly for their target core.
The fourteen files under ports/cortex_a{5,7,8,9,12,15,17} were regenerated
from ports_arch/ARMv7-A/threadx/common/src/tx_thread_system_return.S with
ports_arch/ARMv7-A/update.sh. The ARMv7-A SMP ports have no generator, so
those files were edited directly.
Fixes#734
Assisted-by: Copilot (Opus 5) <noreply@github.com>
* ports: add Linux build scripts for Cortex-A5 SMP
* ports: fix Cortex-A5 SMP sample linking on Linux
* ports: add Linux build scripts for Cortex-A7 and A9 SMP
* ports: fix Cortex-A7 SMP assembly source path
* wip: add ATFE selection to Armv7 SMP scripts
* ports: complete Armv7 SMP Linux toolchain support
* ports: add local startup for Armv7 SMP samples
* ports: add license headers to Armv7 SMP scripts
* Dropped the preprocessing flag the file extension now carries
Two lines named assembly sources that #672 renamed. That change moved
twenty-nine files under gnu trees from .s to .S, because GAS runs the C
preprocessor on .S and not on .s: in a .s file every # line is a comment, so a
#define is never substituted and an #if/#else pair emits both arms. Four files
were silently doing the wrong thing as a result, including
ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s, which ignored all
four of its own feature macros.
These scripts had worked around the same defect with -x assembler-with-cpp
rather than hitting it, which was correct when they were written. With the
rename the flag is redundant and the lowercase names no longer resolve, so
cortex_a5_smp/build_threadx.sh failed with "cc1: fatal error:
tx_initialize_low_level.s: No such file or directory". The other seven
references to those two files across these three scripts already named them
with a capital S.
Verified with the pinned Arm GNU 14.3.rel1 rather than the 13.2 that a distro
package supplies: build_threadx.sh and build_threadx_sample.sh both succeed for
a5, a7 and a9, all three link a sample_threadx.out, and scripts/check_gcc.sh
passes end to end with its example stage reading 45 of 45, up from 42.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
* Marked every published ThreadX include directory as SYSTEM so applications no longer get warnings from ThreadX headers
Commit 8c3c08f added the SYSTEM keyword to the target_include_directories
call in common/CMakeLists.txt, but the same call in every port, in the
SMP common directory's consumers, in the POSIX and FreeRTOS compatibility
layers, and for the generated tx_user.h directory was left unchanged.
A consumer building with a strict warning set therefore still saw
diagnostics coming from tx_port.h and from the compatibility layer
headers, which is exactly what the original change set out to avoid.
Added the SYSTEM keyword to all of those calls so CMake emits -isystem
rather than -I for every directory holding a ThreadX public header. The
ARMv7-M, ARMv8-M, ARMv7-A and ARMv8-A architecture sources under
ports_arch were updated alongside the ports they generate, keeping the
two in step.
Directories that are PRIVATE to an example or test build were left as
they are, since nothing is published from them.
Fixes#290
Assisted-by: Copilot (Opus 5) <noreply@github.com>
* Stopped apt-get update being a gate it was never meant to be
apt-get update fails if any configured repository serves a bad index,
including ones this project never reads. The GitHub runner image carries
Google's and Microsoft's apt repositories, and a Hash Sum mismatch from
Google's, their CDN caught mid-publish with the index and the Release
file eight hours apart, failed all three attempts and turned a run red
over a browser nobody was installing.
Made a failed update warn and carry on, leaving apt-get install as the
gate. Nothing is weakened by that: the install still exits on a package
it cannot find, so an unreachable archive still stops the script, one
step later and naming the package it could not get, which is a better
diagnostic than a hash mismatch in a repository nobody asked for.
Disabling third-party sources before updating would keep the update
strict, but this script also runs on a contributor's own machine, and
rewriting someone's apt configuration to suit CI would be worse than
tolerating a stale index for an archive we do not read.
Assisted-by: Copilot (Opus 5) <noreply@github.com>
The Cortex-A5, A7 and A9 SMP ports guarded the inter-core protection with
a FIFO wait list: a core that could not take the lock added itself to a
queue, incremented _tx_thread_smp_protect_wait_counts[core], and only the
core at the head of the queue was allowed to acquire.
Two parts of that scheme require the waiting core to be interruptible.
_tx_thread_smp_unprotect() refuses to release the protection while the
releasing core's own wait count is non-zero, and a queued core is taken
back out of the list by _tx_thread_context_restore() when it is preempted.
Neither can happen on a core that is spinning inside an ISR with
interrupts already masked, because the spin loop restores the caller's
interrupt posture rather than enabling interrupts. The core stays in the
list forever and the system deadlocks with cores stuck in the wait loop.
This is the deadlock Microsoft removed from the ARMv8-A SMP ports in
6.1.11, by dropping the wait list and using a plain LDAXR/STXR spinlock.
The same removal was announced for the ARMv7-A ports at the time but was
never made, so those three ports have carried the deadlock ever since.
The FIFO queueing is now removed from the ARMv7-A SMP ports as well.
_tx_thread_smp_protect() becomes an LDREX/STREX spinlock that releases
interrupts between attempts, matching the sequence already used by the
Cortex-R8 SMP port; _tx_thread_smp_unprotect() no longer consults the
wait counts; and _tx_thread_context_restore() no longer has to unqueue a
preempted core. The now unreferenced wait list macro headers are deleted.
Verified by assembling all three GNU ports with arm-none-eabi-gcc for
cortex-a5, cortex-a7 and cortex-a9, with and without
TX_ENABLE_FIQ_SUPPORT, TX_ENABLE_WFE and TX_MPCORE_DEBUG_ENABLE, and by
reading back the disassembly of the new protect sequence. The port
consistency checks pass.
Fixes#219
Assisted-by: Copilot (Opus 5) <noreply@github.com>
The Linux, Win32 and Win64 simulation ports build a fake initial stack
pointer by subtracting a fixed 8 bytes from tx_thread_stack_end. That
field addresses the last byte of the thread's stack area, so it is one
less than an aligned address and the resulting pointer is misaligned by
construction, no matter how well aligned the stack the application
supplied was.
Two ULONG accesses then use that pointer. _tx_thread_stack_build() itself
clears the word below it, and _tx_thread_create() copies it into
tx_thread_stack_highest_ptr, which TX_THREAD_STACK_CHECK dereferences on
every suspend and resume when TX_ENABLE_STACK_CHECKING is defined. Both
are undefined behaviour. They happen to work on x86 but are reported by
GCC's undefined behaviour sanitizer, and would fault on a host that
requires natural alignment.
The fake stack pointer is now rounded down to a ULONG boundary, which
leaves it inside the stack area and makes both accesses aligned.
Verified by building the Linux port with -fsanitize=undefined and
running the demo: the two reported diagnostics are produced before the
change and neither appears after it. The tx and smp regression suites
pass, 98 and 114 tests respectively.
Fixes#218
Assisted-by: Copilot (Opus 5) <noreply@github.com>
_tx_thread_schedule stores the newly selected thread into
_tx_thread_current_ptr[core] and then reloads _tx_thread_execute_ptr[core]
to detect a concurrent scheduling decision made by another core. On the
other side, _tx_thread_smp_core_interrupt stores the execute pointer and
then reads the current pointer to decide whether an inter-core interrupt is
required. This is a store-buffer pattern: without a barrier both cores can
observe stale values, the interrupt is skipped, and a ready thread with the
highest priority is never scheduled.
The barrier was added to the ARMv8-A SMP scheduler in 6.2.1, but the
ARMv7-A SMP ports were left untouched even though they implement the same
protocol. This adds the corresponding DMB to the Cortex-A5, Cortex-A7 and
Cortex-A9 SMP schedulers for both the AC5 and GNU toolchains.
The GNU variants were verified by assembling them with arm-none-eabi-gcc
13.2.1 for their respective cores.
Refs #209
Assisted-by: Copilot (Opus 5) <noreply@github.com>
_tx_thread_context_save() calls _tx_execution_isr_enter when
TX_ENABLE_EXECUTION_CHANGE_NOTIFY is defined. On the path where an interrupt
preempted a running thread, that call was made before the switch to the system
stack, so the 32-byte call frame and the whole stack footprint of the callout
were taken from the interrupted thread's stack, on top of the 160-byte interrupt
frame the port had already allocated there.
The callout is supplied by the application, so its stack usage is not bounded by
ThreadX, and it is charged to every thread that happens to be running when an
interrupt arrives.
The two other callout sites in the same routine, the nested save and the idle
system save, already run on the system stack, as does the _tx_execution_isr_exit
call in _tx_thread_context_restore. _tx_thread_schedule was reordered in 6.1.9
so that _tx_execution_thread_enter runs on the system stack rather than the
thread stack; the same reorder was never applied to the context save.
The switch to the system stack now happens before the callout in the ARCv2_EM,
ARC_HS and SMP ARC_HS ports. _tx_thread_context_fast_save is unchanged because
the fast interrupt path never switches stacks by design.
Fixes#149
Assisted-by: Copilot (Opus 5) <noreply@github.com>
Every AArch64 gnu example build failed at the sample link, all 27 of them --
13 under ports/ and 14 under ports_smp/:
libg.a(libc_a-init.o): in function `__libc_init_array':
undefined reference to `_init'
relocation truncated to fit: R_AARCH64_CALL26 against undefined
symbol `_init'
libg.a(libc_a-fini.o): in function `__libc_fini_array':
undefined reference to `_fini'
build_threadx_sample.sh links with -nostartfiles, which is correct for a port
carrying its own reset path, and that drops crti.o and crtn.o along with
everything else. startup.S calls __libc_init_array by design, and newlib's
implementation calls _init, which crti.o is what defines. The AArch32 scripts
are unaffected: they use nosys.specs and never reach __libc_init_array.
The fix links crti.o and crtn.o explicitly, bracketing the object list -- the
first must precede every .init contribution and the second must follow all of
them, so their position is load-bearing rather than stylistic. Both paths come
from the compiler's own -print-file-name, so nothing here hard-codes a
toolchain layout.
The atfe branch sets both to empty, deliberately: picolibc's __libc_init_array
does not call _init, those 27 images link today, and adding crti.o would change
a working link for no reason. That is also why check_clang.sh is green on these
and does not list them as expected to fail -- the LLVM path never reached the
gap, so nothing has ever linked them and failed.
Fixed in ports_arch/ARMv8-A/threadx/ports/gnu/example_build, which is the
single source for both the ports/ and ports_smp/ copies, then regenerated with
update.sh --port-sets tx,tx_smp. The 27 generated copies are in this commit
because ports_arch_check compares them.
Verified: all 27 link with arm-gnu-toolchain 14.3.rel1 aarch64-none-elf, where
0 of 27 did before; _init and _fini disassemble to the expected crti prologue
and crtn epilogue over a ret; check_clang.sh with ATfE 22.1.0 is still green on
all five stages, including the 42 script-driven example builds; check_ports.sh
is green including the reproducibility check.
No regression test: these are link-only example images that no host test
executes. What guards them is check_clang.sh's example stage today, and
check_gcc.sh's, which is the next change and is the reason this was found.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
scripts/check_clang.sh globbed ports_module/*/gnu/src, which does not exist --
the module ports keep their assembly in module_manager/src. The [ -d ] guard
skipped it in silence, so 116 assembly files across nine Arm module ports were
assembled by no check, with either compiler, in the script whose own comments
state three times that "a port that is simply absent from the count reads as
covered". Stage 1 goes from 724 of 724 to 840 of 840; the feature-macro stage
had the same gap and goes from 412 files to 469.
Correcting the path exposed five defects, and only one of them was a build
failure. The other four assembled cleanly and did the wrong thing, because GAS
runs the C preprocessor on .S and not on .s:
ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s, the only .s in a
directory of twenty-one .S, ignored all four of its own feature macros. It
wrote the caller's LR into the protection structure on every unprotect -- a
store guarded by TX_MPCORE_DEBUG_ENABLE -- sent an unconditional SEV, and
returned through both BX lr and MOV pc, lr. Its cortex_a5_smp and
cortex_a9_smp siblings are .S.
ports_module/cortex_m33/.../tx_thread_stack_build.s emitted both arms of an
#ifdef TX_SINGLE_MODE_SECURE, so the non-secure LR value overwrote the secure
one and the secure build got the wrong frame.
ports_module/cortex_m23/.../tx_thread_context_{save,restore}.S carried the
POP {r0, lr} that check_clang.sh's own comment describes as the reason the
feature-macro stage exists. The 16-bit Thumb POP takes r0-r7 and pc only.
The identical fix already sits in ports/cortex_m23/gnu/src; the module copy
never got it because nothing scanned it.
ports_module/cortex_m23/.../tx_thread_secure_stack_initialize.S used MOV
rather than MOVS for an 8-bit immediate, latent behind TX_SINGLE_MODE_SECURE.
Both siblings in the same directory already use MOVS.
ports_module/cortex_a7/gnu/module_manager/src is the one that failed to
assemble, on GCC 14.3 as well as on LLVM: #define SYS_MODE was never
expanded, so #SYS_MODE reached the assembler as an undefined symbol.
Twenty-nine .s files under gnu trees are renamed to .S. Every one of them is
already named .S by the build scripts that compile it, so this repairs those
scripts rather than churning them -- ports_module/cortex_a7's build_threadx.bat
names all eighteen with a capital S, and works today only on a case-insensitive
filesystem. Renaming rather than converting the #defines to GNU assignments is
what fixes the #ifdef blocks as well as the constants; the assignments would
have fixed two files and left twenty-seven silently ignoring their macros.
Files with no preprocessor directives are left as .s: they are not broken, and
check_ports.sh gains a check that keeps them that way. Only the gnu trees are
checked there -- the IAR, Arm Compiler 5 and Keil assemblers preprocess .s
themselves, and about three hundred files in this repository rely on that.
Verified with both toolchains on the same tree: 840 of 840 assembled by
ATfE 22.1.0 and by arm-gnu-toolchain 14.3.rel1, all five stages of
check_clang.sh green, and check_ports.sh green including the reproducibility
check. The new check was shown to fail by planting a copy of the file it was
written for.
No regression test accompanies this. The assembly it covers is executed by no
host test, and the check itself going from 724 files to 840 is the coverage
AGENTS.md asks for -- together with the new check_ports.sh section, which is
what stops the class recurring.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The CMake build produced libthreadx.a and nothing else, so trying ThreadX on
Linux meant using the Makefile beside the port instead. Build the demo the
Makefile builds, for the linux port and its SMP counterpart.
The target is behind an option that defaults off, so an ordinary build is
unchanged and still produces just the library. -DTHREADX_SAMPLE=ON adds it:
cmake -S . -B build -DTHREADX_ARCH=linux -DTHREADX_TOOLCHAIN=gnu \
-DTHREADX_SAMPLE=ON
cmake --build build --target sample_threadx
The include path uses TX_COMMON_DIR rather than naming common or common_smp,
since the top level already resolves which of the two applies.
Verified by building and running both variants. Non-SMP prints
**** ThreadX Linux Demonstration **** (c) 1996-2020 Microsoft Corporation
and SMP prints the SMP banner, both with the demo's thread counters advancing. A
default configure with no THREADX_SAMPLE has no sample_threadx target and still
produces libthreadx.a, so nothing existing moves.
Derived from the two example_build files in #404 by Yanfeng Liu, which had the
same goal. That change also rewrote the top level's SMP selection, added
common_smp/CMakeLists.txt and added ports_smp/linux/gnu/CMakeLists.txt; all three
have since arrived on dev by other routes, so only the sample targets were still
missing. The include path needed adjusting because the original depended on
THREADX_SMP being a string suffix, which it no longer is.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The project guidelines ask for CMake and Ninja, but only 15 of the 59 gnu port
directories had a CMakeLists.txt. None of the 27 AArch64 ports had one, so the
architecture whose examples were repaired over the last few changes still could
not be built the way the project says to build it, and nothing in CI could
compile it.
Add a CMakeLists.txt to the 44 that lacked one. Three of them are templates in
ports_arch, because 34 of the 44 are generated: the ARMv7-A and AArch64 source
lists are uniform within each family, so one template per family serves every
core in it and update.sh distributes it. The other 10 ports have no generator
and get their own file.
Add the toolchain files those ports select, following the shape of
cmake/cortex_a9.cmake. AArch64 needs a base file of its own rather than a
variant of arm-none-eabi.cmake: it has no -marm or -mthumb to choose between and
no -mfloat-abi, and aarch64-none-elf-gcc rejects -mlong-calls outright, so that
flag cannot be carried across. The tools are named without a path, unlike
cmake/cortex_r52.cmake which pins one, because pinning 30 files to a single
machine's directory layout is the problem the previous change removed from the
launch configurations.
Three toolchain files cover ports that already had a CMakeLists.txt but no way
to select it: the Armv8-M mainline gnu ports, cortex_m33, cortex_m55 and
cortex_m85. Without cmake/<arch>.cmake the documented invocation cannot reach
them.
The top level needed one fix. It derives the SMP port directory as
<arch>_smp, but ports_smp/linux and ports_smp/win64 predate that convention and
carry no suffix, so those two could never be configured. Fall back to the bare
name when the suffixed directory is absent. The check only fires when the
suffixed directory does not exist, so no port that already resolved changes
behaviour, and ports_smp/win64's existing CMakeLists.txt becomes reachable too.
Verified by configuring and building every one: 53 of 53 static libraries build
with cmake -G Ninja, using Arm GNU Toolchain 14.3.Rel1 for both arm-none-eabi
and aarch64-none-elf. That covers the 44 new ports plus the 9 that already
worked, and includes ports_smp/linux, which failed before the fallback.
scripts/check_ports.sh passes, so the three templates and their 34 generated
copies agree.
Six gnu ports are still outside the CMake build, all for want of a compiler
rather than a CMakeLists.txt: rxv1, rxv2 and rxv3 need the Renesas RX GNU
toolchain and mips32_interaptiv_smp needs a MIPS one, neither of which is
available here, so writing toolchain files for them would mean shipping
untested guesses. risc-v32 and risc-v64 already build through their own
differently named toolchain files.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The Arm Development Studio launch configurations and the IAR project files
carried absolute paths from the machines they were last opened on: four
individuals' home directories, a Broadcom support build tree, and directories
such as C:\release\threadx, C:\temp1702\tx and D:\threadx. They are published in
the repository and none of them resolves for anyone else.
In the launch files all of it is saved session state, which files that were never
opened in a debugger simply do not have:
breakpoints 72 files, saved breakpoints anchored to source
paths under cortex_a35 on one machine. Emptied
rather than deleted, matching the 27 launch files
that already carry an empty list.
scripts_view_script_links 70 files, a scripts view cache. The script the
launch actually runs is named one line earlier
through ${workspace_loc:...}, which is portable.
substitutePath 65 files, source lookup remapping. 30 map a path
to itself, and the rest point at one machine's
copy of libgloss or a build directory.
TREE_NODE_PROPERTIES 39 files, which rows the variables view had
expanded.
DebugCommandLine.History 2 files, the debug console command history,
including a typed absolute path.
The two IAR cases are not session state and are corrected rather than removed:
IarchiveOutput 23 files. The librarian output path pointed at
another machine, so the library was written
outside the project. Set to ###Unitialized###,
which 86 other option blocks already use, letting
IAR derive $EXE_DIR$\$PROJ_FNAME$.a.
IlinkIcfFile 1 file. The linker configuration file is load
bearing, so the file name is kept and the path
made project relative, as 33 other option blocks
spell it.
Seven of the files are ports_arch templates, so the generators would otherwise
have copied the paths back.
Verified: all 162 launch and IAR project files in the tree parse as well-formed
XML afterwards, no tracked launch or project file mentions any of the four user
names, and scripts/check_ports.sh passes, so the templates and their generated
copies still agree.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
Two identifiers in the Arm Development Studio launch configurations still said
A35 in every AArch64 port, because the generator's patch table could not reach
them.
The config database taxonomy id is spelt in lower case in the launch files,
/platform/armfvp/base_a35x4, but the search string read base_A35x4. Both
generators are case sensitive here, sed in update.sh and -creplace in
update.ps1, so the rule matched nothing and all 27 ports kept the A35 taxonomy
id while the platform name and model beside it named the right core. That the
rule exists at all shows the substitution was intended, and the ARMv7-A
generator does the same thing correctly, which is why its ports carry a per-core
ve_cortex_a<n>x1 id.
The SMP launch files name the activity "Cortex-A35x4 SMP" where the ThreadX ones
say "Debug Cortex-A35", so the existing activity rule reached the ThreadX ports
only and every SMP port advertised an A35 activity. Add a rule that matches the
" SMP" suffix, which also keeps it from rewriting the FVP model name that the
line above already handles.
Both changes are mirrored in update.ps1, which stays equivalent to update.sh.
Verified by regenerating: 50 launch files change and nothing else, 100 lines of
taxonomy id across 24 ThreadX and 26 SMP files, and 52 lines of activity name
across the 26 SMP files. No other attribute in those files moves, so the new
" SMP" rule does not touch the model name. The two Cortex-A35 ports are
untouched, as they must be, since substituting A35 for A35 is a no-op.
scripts/check_ports.sh passes, so the result is reproducible.
This cannot be exercised here: confirming that Arm Development Studio resolves
the per-core taxonomy ids needs Arm Development Studio. The change rests on the
platform name and model already naming the core, on the patch rule's existence,
and on the ARMv7-A ports having shipped per-core ids all along.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
ports/cortex_a34, ports_smp/cortex_a34_smp and ports_smp/cortex_a78_smp were
absent from the ARMv8-A generator's core list, so ports_arch never reached them
and scripts/check_ports.sh could not detect that they had drifted. They had.
The two Cortex-A34 ports sat two releases behind the shared sources, at 6.1.10
against 6.3.0. The difference is not only banners: tx_initialize_low_level.S
lacked the SUB x1, x1, #15 that precedes the BIC when the system stack pointer
is recorded, so the value stored was the incoming SP rather than the first
16-byte boundary below it. The Arm Development Studio example was missing
GICv3_aliases.h, which every other port's GICv3_gicc.h includes to reach the
interrupt controller registers through the stringify indirection.
The Cortex-A78 SMP port had never had its debug launch configuration patched at
all. It still named the A35 platform and model, so Debug Cortex-A35,
Base_A35x4 and FVP_Base_Cortex-A35x4 would have started an A35 model for an A78
port.
Add cortex_a34 to the core list. Cortex-A78 cannot go in the same list, because
the generator walks cores against port sets and would then create a
ports/cortex_a78 that the tree has never had; give it a separate SMP-only list
consulted only for the tx_smp port set. Both changes are mirrored in update.ps1,
which stays equivalent to update.sh.
Verified by regenerating: exactly these three port directories change, 116 files
modified and 13 added, and no already-covered core moves, so the core list was
the only thing holding them back. scripts/check_ports.sh passes, which now means
these three are checked for reproducibility for the first time.
scripts/check_clang.sh reports 38 of 38 example builds linked, the three new
ports included.
readme_threadx.txt is not added here. Only the two Cortex-A35 template ports
carry it; the other 23 AArch64 ports do not, so its absence from Cortex-A34 is
the tree's norm rather than drift, and supplying it everywhere is separate work.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The AArch64 examples could only be built through the Arm Development Studio
project files beside them. There was no script, so nothing in CI or on a
developer's machine could build them, and the sources they need were never
named anywhere: vectors.S, v8_aarch64.S and v8_utils.S were present but
unreferenced, which is why a hand written link failed on GetCPUID, GetAffinity,
InvalidateUDCaches and ZeroBlock. Those four are defined in v8_aarch64.S and
v8_utils.S, in the tree all along.
Add one pair of scripts, in ports_arch so every AArch64 port receives them.
Both derive the -mcpu value and the kernel source directory from the port
directory they sit in, so a single pair serves the twelve ThreadX ports and the
twelve SMP ports, the latter building against common_smp and picking up the C
sources those ports carry alongside the assembly. TOOLCHAIN=atfe selects Arm
Toolchain for Embedded in place of the GNU toolchain, as it does for the ARMv7
example scripts.
One symbol genuinely had no definition. startup.S calls
initialise_monitor_handles to open the standard file handles over a debugger
connection; the GNU toolchain provides it in libgloss through
--specs=rdimon.specs, while picolibc has no equivalent and neither does the
LLVM toolchain's semihosting library. semihost_stub.S supplies a weak no-op,
linked for that toolchain only, so a real definition always wins.
Extend scripts/check_clang.sh to cover ports_smp as well as ports, since the
example builds now exist there too.
Verified by building every AArch64 example with Arm Toolchain for Embedded:
twelve ThreadX ports at 314,744 to 315,256 bytes of text and twelve SMP ports
at 325,304 to 325,880. scripts/check_clang.sh now reports 35 of 35 example
builds linking with none failing, the twenty-four new ones plus the eleven that
already built. The images have not been executed: the sample
targets the Base platform peripheral addresses, which the available emulator
does not provide.
Cortex-A34, and the Cortex-A34 and A78 SMP ports, are left out. They are not in
the generator's core list, so they receive nothing from ports_arch and cannot be
checked for reproducibility either. Bringing them in rewrites 114 files in those
three directories, which deserves its own change.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The gnu ports are only ever built with GNU tooling, and GNU as accepts several
non-canonical forms that LLVM's assembler rejects. Nothing noticed, because
nothing built them with anything else. This matters beyond clang itself: Arm
Toolchain for Embedded is LLVM based and is the successor to Arm Compiler 6, so
these are the code paths ac6 users move onto.
Seven files needed changing, none of which alters the emitted code:
LDREX and STREX take no offset in A32 state; the #imm form is Thumb-2 only. GNU
as drops the redundant zero, LLVM rejects it. Removed from the Cortex-A5, A7 and
A9 SMP protect routines.
ARMv8-M Baseline has no flag-preserving MOV immediate, so GNU as already emits
MOVS. Writing MOVS in the two Cortex-M23 sources says what the assembler was
doing anyway. One of them sits in a branch only compiled for the single mode
secure configurations, which is why it had never surfaced.
The Cortex-M0 schedule routine wrote LDR r0, =#0x10000000 with a stray hash,
which its own sibling file already wrote correctly.
The Cortex-M0 system return routine selected the numbered subsection .text 32,
which makes LLVM place the constant pool beyond the range a Thumb-1 PC relative
load can reach. Plain .text fixes it and GNU accepts either form. The reason is
recorded in the file, since 32 files pair a numbered subsection with a literal
pool load and the rest only escape because Thumb-2 and A32 have far more range.
Add scripts/check_clang.sh, which assembles every Arm gnu port source and
compiles the common C sources for one core per architecture profile, and a
clang_check workflow that installs Arm Toolchain for Embedded and runs it. The
toolchain version is pinned and checksum verified, for the same reason the
runner image is pinned.
The port directory to target mapping in that script is explicit rather than
prefix matched. Prefix matching is what makes cortex_a5 also match cortex_a53
and cortex_a55, which are AArch64, and assembling those as ARM32 produces
hundreds of misleading errors; that mistake cost real time while measuring this,
so the reason is recorded next to the table.
Verified with Arm Toolchain for Embedded 22.1.0: 711 of 711 assembly sources
assemble and 185 of 185 C sources compile for all eight profiles, against 6
assembly failures before the change. arm-none-eabi-gcc still assembles all 315
ARM32 sources, so nothing regressed for GNU. The check was confirmed to fail
when any one of the fixes is reverted.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
The ARMv7-A and ARMv8-A ports are generated by update.ps1, which needs
PowerShell, so the cortex-a job in ports_arch_check ran on a Windows image and
nobody could reproduce it locally on Linux. Add update.sh beside each
update.ps1, with the same cores, compilers, copy sets and patches, and move the
job to the same Linux image as everything else.
The bash scripts were checked against the PowerShell ones by comparing what
each reports as drifted. They agree exactly on the 63 files the Windows job
last reported, and differ on 12 more, which turn out to be a defect in
update.ps1 rather than in the port. Its two .cproject patterns are written as
'value=`"cortex-a7`"' with backticks that survive into the pattern, so that
replacement has never matched, while the neighbouring Cortex-A7.NoFPU pattern
has no backticks and always worked. The result is that the AC6 example builds
for the A5, A8, A9, A12, A15 and A17 cores name cortex-a7 as their CPU while
their FPU string is correct. The bash scripts do what the PowerShell ones
intended, so regenerating corrects those twelve files.
Restore ports_arch as the source for the rest. The implementation of
_tx_thread_smp_time_get from #555 was applied to the twenty four generated SMP
ports and never to ports_arch, which still held MOV x0, #0 with a FIXME
comment, so regenerating would have replaced a working generic timer read with
a stub. That implementation now lives in the source. The remaining differences
are cosmetic and resolve in favour of the source: a trailing blank line in 38
copies of tx_thread_schedule.S and comment spacing in one tx_port.h.
Note that the Cortex-A VFP fix is already present in ports_arch and was never
at risk, contrary to what the description of the port consistency checks change
said before this was measured.
Extend scripts/check_ports.sh to run the A profile generators too, and make it
fail when a generator fails or is missing rather than reporting a clean tree,
which would have been a false pass.
Pin every workflow to ubuntu-24.04. ubuntu-latest already resolves to that
image, so nothing changes today, but a future migration becomes a deliberate
commit rather than something that happens underneath the -m32 builds.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
Follow up on the issue-541 execution profiling work. PR #553 fixed SMP execution profile total-time aggregation, and PR #554 fixed Armv7/R SMP timestamp hooks that used decrementing private timers.
This change addresses the remaining related gap in ARMv8-A SMP ports: their timestamp hooks returned zero, which left execution profiling and trace timestamps without a progressing time source. Replace those stubs with the architectural generic physical counter, CNTPCT_EL0, across the ARMv8-A SMP GNU, AC6, IAR, and GHS variants.
The local ARMv8 AArch64 system timer example already uses CNTPCT_EL0 for physical count reads, so this keeps the SMP timestamp hook aligned with the existing port examples while preserving the 32-bit ULONG return contract.
Co-authored-by: Codex <codex@openai.com>
* Fixed Cortex-A9 SMP time source
Updated Cortex-A9 SMP timestamp reads to use the global timer low counter instead of the decrementing private timer counter. Applied the change to GNU and AC5 ports.
* Fixed remaining Arm SMP time sources
Updated Cortex-A5, Cortex-A7, and Cortex-R8 SMP timestamp hooks so execution profiling uses incrementing time sources instead of the decrementing private timer count register.
Cortex-A5 and Cortex-R8 now read the global timer count low register, matching the Cortex-A9 fix. Cortex-A7 now reads the generic timer physical count register.
---------
Co-authored-by: Codex <codex@openai.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Codex (gpt 5.5) <codex@openai.com>
* Unify ThreadX and SMP for ARMv8-A.
* Fix path in pipeline to check ports arch.
* Add ignore folders for ARM DS
* Generate ThreadX and SMP ports for ARMv8-A.
* Ignore untracked files for ports_arch check.
* Use arch instead of CPU to simplify the project management.
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
b5d5df511 #include tx_user.h in assembly files for cortex-m ports
33e04e3d5 initial port of MIPS SMP for GHS and GNU
2eda2c17d capitalize extensions for M23 asm files
21c354ccb Fix armv7-m MPU settings for corner case, unify txm_module_port.h files
4a1ff93f9 remove uneeded include for ac6
c823e91ff update riscv iar example for latest iar tools
5559d185d check module stack for overlap (not kernel stack)
efa9ce7b7 apply patch from mobileye to fix time slice processing
75fdcb722 Updated copy_armv7_cm.yml
de04b9904 initialize unused MPU settings so that aliasing will work
79b317b60 add config directory to IAR RISC-V port in order to use simulator