Why is Windows still tinkering with critical sections? – The Old New Thing
Critical sections, locks, and terminology
- Critical sections on Windows are one specific kind of lock:
- In-process only; cannot be shared across processes.
- Historically the main intra-process primitive; counted and recursively lockable.
- Can be configured to spin before blocking and are visible to debuggers via a global list.
- Win32 Mutex objects are heavier-weight, securable kernel objects, usable across processes and by name (e.g., “single-instance” apps). They require kernel involvement on every contended operation.
- On other platforms they’re roughly analogous to
pthread_mutex_t/futexes: uncontended paths are just atomic memory operations; contention enters the kernel. - Several commenters note that today SRWLock / WaitOnAddress (or
std::shared_mutex) are preferable to critical sections, which are seen as old and bloated. - There is confusion across ecosystems:
std::mutexis a lightweight lock, unlike Win32Mutex.fflushvsFlushFileBuffershave very different “flush” semantics.
- Some people also use “critical section” to mean the code region accessing shared mutable state, distinct from the lock mechanism itself.
The GTA bug and Windows compatibility
- The blog post was triggered by a GTA: San Andreas bug that surfaced when Windows changed critical-section internals.
- One side claims this reflects poor engineering at Microsoft and that compatibility should have prevented regressions.
- Others argue strongly that:
- The game was relying on undefined behavior: reading uninitialized stack variables whose contents happened to persist due to previous calls.
- The OS change did not affect API correctness; it merely changed stack layout, exposing the bug.
- Expecting the OS to preserve arbitrary stack contents indefinitely is unrealistic; “any change anywhere” could break such code.
- Compatibility mode on Windows is explained as specific app-compat shims, not whole old OS versions; maintaining multiple full implementations of every function would be infeasible.
- Some suggest specialized VMs or containerized “old Windows” images as a better long-term strategy for buggy legacy software.
Backward compatibility, open alternatives, and preservation
- Debate over whether this case demonstrates the need to preserve old OS versions:
- One view: only running the original OS guarantees old software runs “as intended,” including with latent bugs.
- Counterview: here the bug was already fixed in later game releases or is easily patched; this isn’t a strong example.
- Broader discussion of Windows vs other platforms:
- Windows is seen by many as unusually committed to binary backward compatibility (Win32 as “the only stable ABI”), enabling Wine/Proton on Linux.
- Others highlight UX and hardware-side breakage (e.g., Windows 11 requirements, UI churn) and argue that consoles and some other OSes rely more on explicit versioning/VM-like strategies.
- Open alternatives:
- Wine is praised as more compatible than modern Windows for some very old games.
- ReactOS is mentioned; some consider it too immature/buggy, others note such projects often look useless for a long time before becoming viable.
- There’s skepticism that an open OS would choose to preserve accidents like this GTA bug; patching individual games (as GOG and modders do) is seen as more practical.
Performance, bloat, and Explorer behavior
- Several commenters find it ironic that Microsoft micro-optimizes critical sections while Windows 11 feels slow and bloated in everyday use:
- Reports of long boot-to-usable times, laggy UI, slow Task Manager startup, and frequent File Explorer freezes.
- Comparisons to macOS on Apple Silicon and to Linux desktops (KDE, GNOME, minimal NixOS) that feel snappier on the same or weaker hardware.
- File Explorer issues are a major theme:
- Freezes often tied to synchronous shell extensions, mapped network drives, or third‑party plugins (PDF handlers, VCS overlays, preview handlers).
- Suggested mitigations: use Process Monitor to see what’s blocking; disable non‑Microsoft shell DLLs via Autoruns.
- Backward-compatible, synchronous COM interfaces for shell extensions make it hard to make Explorer truly asynchronous without breaking old extensions.
- Some criticize UI regressions and UX friction:
- Explorer’s Win11 reskin, changes to keyboard-driven workflows, and focus-stealing dialogs (e.g., meeting reminders).
- The sense that core shell interactions degrade while engineering effort targets low-level primitives and AI integrations like Copilot.