Skip to content

Completed Windows simulator support and regression coverage - #736

Open
fdesbiens wants to merge 22 commits into
eclipse-threadx:devfrom
fdesbiens:windows-sim-ports-refresh-2026-09-01
Open

Completed Windows simulator support and regression coverage#736
fdesbiens wants to merge 22 commits into
eclipse-threadx:devfrom
fdesbiens:windows-sim-ports-refresh-2026-09-01

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Summary

  • complete and stabilize the Win32 and Win64 MSVC simulator ports
  • replace high-latency host synchronization paths with bounded scheduler handoffs and critical sections
  • add high-resolution timer, tick batching, idle fast-forward, shutdown coordination, and Win64 extension-pointer support
  • make the Windows regression tooling and new thread-transition tests work with CMake, Ninja, and the Visual Studio Build Tools
  • extend SMP teardown diagnostics and correct 64-bit trace-test handling

This refresh incorporates and supersedes the useful work from the historical win64, win32-perf, windows-sim-ports, and windows-sim-ports-completion branches. The original Win64 port was merged in #529; no unmerged legacy change was found that is absent from this branch.

Validation

  • Win32: 515/515 tests passed across all five configurations
  • Win64: 515/515 tests passed across all five configurations
  • Win64 SMP: 580/580 tests passed across all five configurations
  • Total: 1,610/1,610 tests passed

All builds used CMake and Ninja with MSVC from the Visual Studio 2022 Community Build Tools environment. Tests ran serially with failed-test retry enabled.

Notes

  • The simulator timing changes are guarded by the existing Windows configuration switches where appropriate.
  • Existing MSVC warnings in the trace configuration remain unchanged.
  • No external dependency was added.

PR checklist

  • Updated function header with a short description and version number
  • Added or exercised regression coverage for the fixes and Windows simulator behavior
  • Validated on real hardware (not applicable: host simulator ports)

fdesbiens and others added 22 commits September 1, 2026 15:25
The netxduo64 suite's nx_user.h defines NX_THREAD_EXTENSION_PTR_SET/GET
using tx_thread_extension_ptr, which requires TX_THREAD_EXTENSION_1 to
expose this field in TX_THREAD_STRUCT. The Linux port already defines it;
align the win64 port accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
The win64 simulation port is purely for running the regression test suite,
not for production use.  With TX_TIMER_PERIODIC=10 (10ms per tick) the
simulation ran at 1:1 wall-clock time: protocol-level timeouts (ARP expiry,
TCP retransmit, DHCP renew) consumed real seconds, making a full test suite
run take hours.

Changing TX_TIMER_PERIODIC to 1 (1ms per tick via CreateWaitableTimerEx with
CREATE_WAITABLE_TIMER_HIGH_RESOLUTION) drives the simulation at 10x wall-clock
speed.  TX_TIMER_TICKS_PER_SECOND stays at 100, so all tick-count-based test
logic is unaffected; only the real elapsed time per test is reduced by ~10x.

The TX_WIN32_SLOW_TIMER escape hatch is preserved for debugging sessions where
slower simulation is desirable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
- Added tx_thread_win32_thread_start_semaphore to TX_THREAD_EXTENSION_0
- Rewrote tx_initialize_low_level.c: replaced timeSetEvent with
  CreateWaitableTimerEx and a dedicated timer thread; added
  _tx_win32_scheduler_wake_event, _tx_win32_isr_semaphore,
  _tx_win32_timer_waiting, and _tx_win32_scheduler_wake()
- Rewrote tx_thread_schedule.c: replaced Sleep(2) polling with
  WaitForSingleObject on _tx_win32_scheduler_wake_event; added
  timer/ISR handshake via _tx_win32_isr_semaphore
- Updated tx_thread_stack_build.c: create and use start semaphore
  for clean thread handoff, matching win64 behavior
- Set TX_TIMER_PERIODIC=1 (down from 10) for 10x faster simulation
- Added TX_WIN32_USE_HIGH_RESOLUTION_TIMER and
  CREATE_WAITABLE_TIMER_HIGH_RESOLUTION defines
- Updated tx_port.h with new extern declarations
- Fixed copyright year (2026) and version (6.5.2.202603)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Added the missing #endif /* TX_PORT_H */ guard at the end of the
win32 vs_2019 port header, which caused a C1070 mismatched #if/#endif
compiler error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
The win32 port was running at 10ms/tick (100 ticks/s real time) while
the win64 port runs at 1ms/tick (10x faster).  Several key files were
not updated during the original win32-perf cherry-pick, leaving the old
slow code in place.  This commit brings all six affected files to parity
with the win64 port:

tx_port.h
- Add _tx_win32_scheduler_wake_event, _tx_win32_timer_thread_handle,
  _tx_win32_isr_semaphore, _tx_win32_timer_waiting externs
- Add _tx_win32_scheduler_wake() prototype
- Add TX_WIN32_USE_HIGH_RESOLUTION_TIMER macro (default 1)
- Change TX_TIMER_PERIODIC default from 10 to 1 (1 ms per tick)
- Add tx_thread_win32_thread_start_semaphore to TX_THREAD_EXTENSION_0

tx_initialize_low_level.c
- Replace timeSetEvent() with CreateWaitableTimerEx + dedicated timer
  thread (_tx_win32_timer_thread_entry) for sub-millisecond precision
- Add _tx_win32_scheduler_wake_event creation
- Add _tx_win32_isr_semaphore creation
- Add _tx_win32_scheduler_wake() and _tx_win32_timer_start() helpers

tx_thread_context_restore.c
- Add _tx_win32_timer_waiting flag coordination with the scheduler
- Add _tx_win32_scheduler_wake() call on preemption
- Add _tx_win32_isr_semaphore handoff for solicited-wakeup ordering
- Add else-if branch for idle-scheduler / timer-makes-thread-ready case

tx_thread_schedule.c
- Replace Sleep(2) with WaitForSingleObject(_tx_win32_scheduler_wake_event)
- Add _tx_win32_semaphore_reset() helper to drain stale counts
- Add stale-semaphore drain before solicited resume
- Add _tx_win32_timer_waiting handoff: wait on start_semaphore, release
  isr_semaphore so the timer thread is not stuck for an extra tick

tx_thread_stack_build.c
- Create tx_thread_win32_thread_start_semaphore alongside run_semaphore
- Add startup handoff: new thread signals start_semaphore, creator waits
- Update _tx_win32_thread_entry with full handoff pattern and stale-
  thread exit guard (matches win64 tx_thread_stack_build.c exactly)

tx_thread_system_return.c
- Add _tx_win32_scheduler_wake() after ReleaseSemaphore(scheduler_sem)
  so the scheduler wakes promptly even when on the wake_event wait
- Add ReleaseSemaphore(start_semaphore) after WaitForSingleObject(run_sem)
  to ack the scheduler in the _tx_win32_timer_waiting handoff path
  (without this the scheduler deadlocks waiting on start_semaphore)

Result: 610/610 tests pass across all three win32 configs in ~567 s,
matching win64 performance.  Previously slow tests reduced 5-6x:
  netx_ipv6_prefix_test:       41 s -> 6.7 s
  netx_icmp_interface2_ping6:  21 s -> 4.0 s

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
The stash-pop merge left two artefacts in tx_thread_schedule.c:
- DWORD wait_status declared twice at the top of _tx_thread_schedule()
- _tx_win32_semaphore_reset() defined twice (lines 191 and 332)

The second definition also incorrectly replaced the critical-section
function bodies (_tx_win32_critical_section_obtain/release/release_all),
which caused LNK2001 unresolved-external errors at link time.

Fix: remove the duplicate variable declaration, the duplicate
semaphore_reset definition, and restore the missing critical-section
function bodies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
On win32 under WOW64, exit() has higher overhead than on native win64.
The 1ms waitable timer fires during CRT cleanup, causing
_tx_thread_context_save() to call SuspendThread() on the thread currently
holding the CRT heap lock. Any subsequent malloc() in another thread
deadlocks permanently. The symptom is a test that prints SUCCESS but
never exits, causing CTest to kill it at the 120s timeout.

Fix:
- Added volatile LONG _tx_win32_exiting flag in tx_initialize_low_level.c
- Registered _tx_win32_exit_cleanup() atexit handler that sets the flag,
  cancels the waitable timer, and terminates the timer thread if needed
- Added early-exit guard at top of _tx_win32_timer_interrupt() to skip
  interrupt processing once the flag is set
- Modified timer thread loop to check the flag and exit cleanly
- Added extern declaration and SuspendThread() guard in
  tx_thread_context_save.c: if _tx_win32_exiting is set when context save
  is triggered, release the critical section and return without suspending
- Used direct volatile LONG read (not _InterlockedAdd which is x64-only)
  to ensure the guard compiles correctly on x86

Tested: netx_15_24_test now passes in ~1 s instead of timing out at 120 s.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
- Added spin-poll idle waits using SwitchToThread() loops in place of
  blocking WaitForSingleObject() calls in tx_thread_schedule.c,
  tx_thread_system_return.c, tx_thread_stack_build.c, and
  tx_thread_context_restore.c to reduce scheduling latency
- Added TX_WIN32_TICKS_PER_INTERRUPT (default 5) to tx_initialize_low_level.c
  to fire the ThreadX timer interrupt N times per 1ms OS event, advancing
  the ThreadX system clock N× faster in real time
  This accelerates all tick-based waits (tx_thread_sleep, timers) and
  reduces total USBX regression suite time from ~451s to ~351s

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
The Win64 ThreadX simulator advanced its clock on a real Windows
waitable timer, so tests that sleep on tx_thread_sleep() consumed
wall-clock time. This mirrors the Linux port's TX_LINUX_NO_IDLE_ENABLE:
when no thread is ready to run, the scheduler kicks the timer thread to
fire the next tick immediately instead of waiting for the wall clock,
making idle periods CPU-bound.

- Add auto-reset _tx_win32_timer_kick_event; the timer thread now waits
  on the periodic timer OR the kick event (WaitForMultipleObjects).
- _tx_thread_schedule signals the kick when the system is idle
  (execute_ptr == NULL && system_state == 0), then waits briefly on the
  wake event for progress.
- All changes guarded by TX_WIN32_NO_IDLE_ENABLE so the default port
  remains real-time; the flag is enabled only for the USBX test build.

Reduces the USBX Win64 regression suite from ~748s to ~30s (430/430
tests pass), on par with the Linux suite.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Brings the Win32 (x86) ThreadX simulator to parity with the Win64 port
so the USBX regression suite is CPU-bound rather than wall-clock-bound.
Previously the Win32 port advanced its clock one tick per real 1ms
periodic timer and blocked indefinitely on the wake event when idle.

- Add TX_WIN32_TICKS_PER_INTERRUPT (default 5) tick batching in
  _tx_win32_timer_interrupt so the SuspendThread/ResumeThread overhead
  is amortized across N ticks per host timer event.
- Add auto-reset _tx_win32_timer_kick_event; the timer thread now waits
  on the periodic timer OR the kick event (WaitForMultipleObjects),
  preserving the existing _tx_win32_exiting exit-cleanup checks.
- _tx_thread_schedule signals the kick when the system is idle
  (execute_ptr == NULL && system_state == 0), then waits briefly on the
  wake event for progress, mirroring TX_LINUX_NO_IDLE_ENABLE.
- Add tx_thread_extension_ptr, TX_TIMER_INTERNAL_EXTENSION and the
  timeout-setup macros to tx_port.h so NetXDuo/USBX default extension
  macros resolve on the ILP32 target (matching the Win64 port).
- All fast-forward changes guarded by TX_WIN32_NO_IDLE_ENABLE so the
  default port remains real-time; the flag is enabled only for the USBX
  test build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Added <stdint.h> to the win32 tx_port.h so uint8_t and related fixed-width
types used by the regression test harness are available (matching win64).

Broadened the timeout-pointer setup guard in threadx_thread_basic_execution_test
from _WIN64 to _WIN32 so the win32 build also populates
_tx_timer_expired_timer_ptr before calling _tx_thread_timeout.  The win32
port defines TX_THREAD_TIMEOUT_POINTER_SETUP in terms of the expired-timer
extension pointer (like win64/linux), so the direct-cast path crashed with
an access violation.  Fixed the lone win32 SEGFAULT; suite now 96/96.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Raised the Win32 and Win64 simulator allocation to 256000 bytes so larger NetX Duo regression workloads do not overrun the host allocation.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Replaced kernel mutex lockouts with Windows critical sections and skipped host priority queries on the normal ThreadX execution path.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Replaced repeated blocking scheduler, application-thread, and timer-ISR semaphore waits with the spin-yield handoff pattern already validated by the Win64 port.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Kept immediate scheduler handoffs responsive while allowing dormant application threads to block after a short bounded spin. This avoids host CPU starvation in multi-threaded FileX workloads without restoring the original per-handoff latency.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Recorded the current Codex session in each refreshed Windows simulator source file that did not already contain the exact required disclosure.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Preserved both AI disclosure lines while accepting the upstream aligned fake stack pointer implementation.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Used MSVC forced-include and undefine options while preserving the existing GCC-family command line.

Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Assisted-by: Codex (gpt-5.6-sol) <codex@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant