[idd] common: centralize atomic operations

This commit is contained in:
Geoffrey McRae
2026-08-13 20:18:18 +10:00
parent 5d12ee4bce
commit af309de438
27 changed files with 477 additions and 271 deletions

View File

@@ -26,6 +26,7 @@
#include "transport/IFrameTransport.h"
#include "transport/IInputTransport.h"
#include "transport/TransportFactory.h"
#include "Atomic.h"
#include "CDebug.h"
#include <dxgi1_2.h>
@@ -168,7 +169,7 @@ void CDeviceContext::InitAdapter()
}
LONG initExpected = 0;
if (!m_initInProgress.compare_exchange_strong(initExpected, 1))
if (!Atomic::CAS(m_initInProgress, initExpected, 1))
{
DEBUG_TRACE("Adapter initialization skipped: initialization already in progress");
return;
@@ -182,7 +183,7 @@ void CDeviceContext::InitAdapter()
if (!m_transport)
{
DEBUG_ERROR("Failed to create the frame transport");
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
@@ -196,7 +197,7 @@ void CDeviceContext::InitAdapter()
}
else
DEBUG_ERROR("Failed to open the frame transport");
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
m_transportOpened = true;
@@ -268,13 +269,13 @@ void CDeviceContext::InitAdapter()
DEBUG_TRACE("Initializing frame transport metadata");
if (!InitializeTransport())
{
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
DEBUG_TRACE("Loading configured display modes");
if (!m_displayConfiguration.Load(*m_transport))
{
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
DEBUG_TRACE("Initializing monitor EDID");
@@ -347,7 +348,7 @@ void CDeviceContext::InitAdapter()
if (!NT_SUCCESS(status))
{
DEBUG_ERROR_HR(status, "IddCxAdapterInitAsync Failed");
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
@@ -355,7 +356,7 @@ void CDeviceContext::InitAdapter()
if (!m_adapter)
{
DEBUG_ERROR("IddCxAdapterInitAsync succeeded without returning an adapter object");
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
return;
}
@@ -367,7 +368,7 @@ void CDeviceContext::InitAdapter()
// Adapter is up; no need to keep retrying.
StopInitRetry();
m_initInProgress.store(0);
Atomic::Store(m_initInProgress, 0);
DEBUG_INFO("Adapter initialization request complete; returning to IddCx");
}

View File

@@ -20,11 +20,12 @@
#pragma once
#include "Atomic.h"
#include <Windows.h>
#include <wdf.h>
#include <IddCx.h>
#include <atomic>
#include <memory>
#include <stddef.h>
#include <stdint.h>

View File

@@ -48,8 +48,8 @@ NTSTATUS CMonitorContext::AssignSwapChain(
// new generation is established.
DetachSwapChain();
const UINT64 assignmentGeneration =
m_assignmentGeneration.fetch_add(1, std::memory_order_acq_rel) + 1;
const UINT64 assignmentGeneration = Atomic::FetchAdd(
m_assignmentGeneration, 1, std::memory_order_acq_rel) + 1;
// Build the D3D11 device into a local so the member is never observed
// half-constructed. The worker binds it before performing the expensive
@@ -96,7 +96,8 @@ void CMonitorContext::DetachSwapChain()
// Invalidate setup in progress before waiting for m_lock. This also lets a
// worker about to call SetDevice observe an unassign whose callback is
// blocked waiting for the processor to be published.
m_assignmentGeneration.fetch_add(1, std::memory_order_acq_rel);
Atomic::FetchAdd(
m_assignmentGeneration, 1, std::memory_order_acq_rel);
// Detach under the lock, then destroy outside it. Destroying the processor
// joins its worker thread, whose teardown (WdfObjectDelete) re-enters this

View File

@@ -20,13 +20,13 @@
#pragma once
#include "Atomic.h"
#include "CSRWLock.h"
#include <Windows.h>
#include <wdf.h>
#include <IddCx.h>
#include <atomic>
#include <memory>
#include <mutex>
@@ -71,7 +71,8 @@ public:
void UnassignSwapChain();
bool IsAssignmentCurrent(UINT64 generation) const
{
return m_assignmentGeneration.load(std::memory_order_acquire) == generation;
return Atomic::Load(
m_assignmentGeneration, std::memory_order_acquire) == generation;
}
CDeviceContext * GetDeviceContext() { return m_devContext; }

View File

@@ -21,6 +21,7 @@
#include "display/CMonitorManager.h"
#include "display/CMonitorContext.h"
#include "Atomic.h"
#include "CDebug.h"
bool CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter,
@@ -133,7 +134,7 @@ CMonitorManager::ReplugAction CMonitorManager::Replug()
{
// Either no monitor yet, or one is already pending; build it now and
// cancel any queued rebuild so we do not create two.
m_createQueued.store(0);
Atomic::Store(m_createQueued, 0);
return ReplugAction::CREATE;
}
@@ -163,7 +164,7 @@ CMonitorManager::ReplugAction CMonitorManager::Replug()
// If there was no swap chain there will be no unassign callback to queue
// the rebuild. Otherwise OnSwapChainReleased does so after teardown drains.
if (rebuild)
m_createQueued.store(1);
Atomic::Store(m_createQueued, 1);
return ReplugAction::NONE;
}
@@ -205,7 +206,7 @@ void CMonitorManager::OnSwapChainReleased()
}
if (rebuild)
m_createQueued.store(1);
Atomic::Store(m_createQueued, 1);
}
CMonitorManager::ReadyAction CMonitorManager::OnSwapChainReady()
@@ -249,15 +250,15 @@ CMonitorManager::ReadyAction CMonitorManager::OnSwapChainReady()
void CMonitorManager::QueueReplug()
{
m_replugQueued.store(1);
Atomic::Store(m_replugQueued, 1);
}
CMonitorManager::DeferredAction CMonitorManager::TakeDeferredAction()
{
if (m_createQueued.exchange(0))
if (Atomic::Swap(m_createQueued, 0))
return DeferredAction::CREATE;
if (m_replugQueued.exchange(0))
if (Atomic::Swap(m_replugQueued, 0))
return DeferredAction::REPLUG;
return DeferredAction::NONE;

View File

@@ -20,11 +20,11 @@
#pragma once
#include "Atomic.h"
#include "CSRWLock.h"
#include <Windows.h>
#include <wdf.h>
#include <IddCx.h>
#include <atomic>
#include <vector>
#include "config/CSettings.h"