Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d3d12 runtime: replacing spinlocks by mutex objects #7489

Merged
merged 2 commits into from
Apr 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions src/runtime/d3d12compute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#include "device_interface.h"
#include "gpu_context_common.h"
#include "printer.h"
#include "scoped_spin_lock.h"
#include "scoped_mutex_lock.h"

#if !defined(INITGUID)
#define INITGUID
Expand Down Expand Up @@ -93,13 +93,13 @@ static void *const user_context = nullptr;

// Trace and logging utilities for debugging.
#if HALIDE_D3D12_TRACE
static volatile ScopedSpinLock::AtomicFlag trace_lock = 0;
static halide_mutex trace_lock;
static constexpr uint64_t trace_buf_size = 4096;
static char trace_buf[trace_buf_size] = {};
static int trace_indent = 0;

struct trace : public BasicPrinter<trace_buf_size> {
ScopedSpinLock lock;
ScopedMutexLock lock;

explicit trace(void *user_context = nullptr)
: BasicPrinter<trace_buf_size>(user_context, trace_buf),
Expand Down Expand Up @@ -139,7 +139,7 @@ struct TraceScope {
_func = func;
t0 = TRACETIME_CHECKPOINT();
#endif
ScopedSpinLock lock(&trace_lock);
ScopedMutexLock lock(&trace_lock);
trace_indent++;
}

Expand All @@ -150,7 +150,7 @@ struct TraceScope {
TRACETIME_REPORT(t0, t1, "Time [" << _func << "]: ");
}
#endif
ScopedSpinLock lock(&trace_lock);
ScopedMutexLock lock(&trace_lock);
trace_indent--;
}

Expand Down Expand Up @@ -2059,7 +2059,8 @@ static void commit_command_list(d3d12_compute_command_list *cmdList) {
cmdList->signal = queue_insert_checkpoint();
}

static bool spinlock_until_signaled(uint64_t signal) {
// WARN(marcos): busywait interface for internal debugging purposes only
static bool busywait_until_signaled(uint64_t signal) {
TRACELOG;
while (queue_fence->GetCompletedValue() < signal) {
// nothing
Expand Down Expand Up @@ -2408,7 +2409,7 @@ static void *buffer_contents(d3d12_buffer *buffer) {
return pData;
}

volatile ScopedSpinLock::AtomicFlag WEAK thread_lock = 0;
WEAK halide_mutex thread_lock;

WEAK Halide::Internal::GPUCompilationCache<d3d12_device *, d3d12_library *> compilation_cache;

Expand Down Expand Up @@ -2504,7 +2505,7 @@ static halide_error_code_t d3d12_create_context(void *user_context) {
}

// The default implementation of halide_d3d12compute_acquire_context uses the global
// pointers above, and serializes access with a spin lock.
// pointers above, and serializes access with a mutex.
// Overriding implementations of acquire/release must implement the following
// behavior:
// - halide_acquire_d3d12compute_context should always store a valid device/command
Expand All @@ -2520,9 +2521,12 @@ WEAK int halide_d3d12compute_acquire_context(void *user_context, halide_d3d12com
halide_start_clock(user_context);
#endif

halide_abort_if_false(user_context, &thread_lock != nullptr);
while (__atomic_test_and_set(&thread_lock, __ATOMIC_ACQUIRE)) {
}
// TODO(marcos): acquire_context will acquire the context lock and hold it
// until it gets released by release_context; it should be possible to simply
// hold it to obtain 'device_ret' and 'queue_ret' and release it immediatley
// after -- as a safe-guard, increment the reference count of the underlying
// ID3D12Device and ID3D12CommandQueue COM objects.
halide_mutex_lock(&thread_lock);

TRACEPRINT("user_context: " << user_context << " | create: " << create << "\n");
TRACEPRINT("current d3d12_device: " << device << "\n");
Expand All @@ -2547,7 +2551,7 @@ WEAK int halide_d3d12compute_acquire_context(void *user_context, halide_d3d12com

WEAK int halide_d3d12compute_release_context(void *user_context) {
TRACELOG;
__atomic_clear(&thread_lock, __ATOMIC_RELEASE);
halide_mutex_unlock(&thread_lock);
return halide_error_code_success;
}

Expand Down