Cross-platform stability fixes and FP-contract standardization#283
Open
Madreag wants to merge 13 commits into
Open
Cross-platform stability fixes and FP-contract standardization#283Madreag wants to merge 13 commits into
Madreag wants to merge 13 commits into
Conversation
Swap the per-tick hitMOAtoms thread-locals from unordered_map to std::map so impulse accumulation iterates MOID-ascending, removing a source of cross-run bit-noise in the physics step.
Add deviceId as a secondary sort key in WeaponSearch and ToolSearch so the pickup ordering is stable when scores collide; scheduler-dependent async callback order otherwise leaves the table order non-deterministic.
On macOS, route RTEError message/abort/assert boxes off worker threads to stderr: Cocoa dispatches the dialog onto the main thread, which deadlocks when that thread is blocked waiting on the worker. Windows/Linux tolerate cross-thread boxes and keep their behaviour. Guard the save-list file_clock -> system_clock conversion on macOS libc++, whose __int128 file_clock rep is rejected when constructing the time_point directly; an explicit duration_cast lands it in range.
CalculatePathAsync runs on the parallel ThreadedUpdateAI workers (AI scripts call Scene:CalculatePathAsync from HumanBehaviors); the static-int increment could hand two concurrent requests the same id and silently drop one Lua callback slot. Make the counter std::atomic with relaxed fetch_add.
Pin floating-point so same-arch Win/Linux/macOS builds produce bit-identical results. meson: -ffp-contract=off plus the no-fast-math family for GCC/Clang, /fp:precise + /arch:SSE2 for MSVC. RTEA.vcxproj: FloatingPointModel=Precise on every config (was Fast). Document the FPU + libm path in Source/CI.
The release branch reassigned extra_args to ['-w'], discarding -ffp-contract=off and the rest of the cross-platform FP block. Append instead of overwrite.
Atom::Clear left m_IntPos and the Bresenham step fields uninitialized. SetupPos branches on m_IntPos, and StepForward steps on the Bresenham state, before SetupSeg runs for a freshly-pooled Atom, so the stale pool value (which varies with allocation order) made collision stepping nondeterministic run to run. This was the dominant source of the cross-platform determinism divergence on the combat scenarios.
The sim-frame counter was incremented each tick but never initialized, so HitWhatMOID and HitWhatTerrMaterial read an uninitialized value when comparing a per-MO collision frame against it.
A SoundContainer's FMOD channels keep its address in userData, so the positional and channel-ended passes read freed memory once the container is destroyed. Null the back-reference on destroy and skip channels whose container is gone.
When every atom rasterizes to zero steps, stepsOnSeg is 0 and the step ratio divided 0/0. Use 0 in that case.
broadcastMsg.activeTime goes negative when the broadcast timestamp predates m_epoch, tripping Tracy's own assert(activeTime >= 0) on startup. Clamp to 0.
Vendored luabind 0.7.1 and boost 1.75 still use the C++17-removed APIs (auto_ptr, unary/binary_function, binders) that libc++ 19+ hides behind these macros, so the macOS build fails to compile without them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
These are cross platform stability fixes that came up while bringing the determinism work over to Mac and Linux. Most are small correctness issues that Windows happened to hide (its heap fill pattern and thread scheduling masked a few), so they only showed up once the same code ran on the other two platforms. see commit messages.
AtomGroupcollision iteration now runs in MOID order (the two thread localhitMOAtomsmaps go fromunordered_maptomap;MOIgnoreMapis left alone since it's lookup only and never iterated). Plus a guard against a 0/0 step ratio when every atom in a segment rasterizes to zero steps, which left a dead NaN that still trippedFE_INVALID.HumanBehaviorsweapon and tool pickup sort gets adeviceIdtie break, since the async pickup callbacks fire in scheduler dependent order and equal scores need a stable total order.FP contract pinned across toolchains:
-ffp-contract=offon GCC/Clang andFloatingPointModel=Preciseon every MSVC config, so the compiler can't fold FMA or reassociate floats differently per platform. A follow on fixes a Meson bug where the release branch reassignedextra_argsand silently dropped those flags on every release TU (checked incompile_commands.json: 203 TUs now, was 0).LuaAdaptersasync callback id counter is now astd::atomic<int>, closing a race under parallel AI.Two uninitialized reads off the pooled allocator, both returning prior occupant bytes so the value tracked allocation order:
Atom's integer step state, andMovableMan::m_SimUpdateFrameNumber. Caught with Valgrind/ASan.An
AudioManuse after free: an MO gibbed mid tick frees itsSoundContainer, but its still playing FMOD channels keep the freed address inuserData. The channels now get disowned on destroy (they keep playing) and the readers skip a container that's gone.A few Mac only fixes: message boxes raised from a worker thread now log to stderr instead of popping a dialog (a cross thread Cocoa alert deadlocks), an explicit
file_time_typetosystem_clockconversion in the save menu, and the libc++ removed-API macros that luabind 0.7.1 and boost 1.75 still need to build on libc++ 19+.a one line guard in Tracy (
TracyProfiler.cpp) that clampsbroadcastMsg.activeTimeto 0 when the timestamp predates the profiler epoch, otherwise it trips Tracy's own assert on startup.Built and ran clean on Windows, Linux, and macOS arm64. A few of these (the iteration order, FP contract, and uninitialized reads) are prerequisites for the determinism series this is part of, but they all stand on their own as fixes.