File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 2626#pragma once
2727
2828#include "dpctl_capi.h"
29+ #include <atomic>
2930#include <complex>
3031#include <cstddef> // for std::size_t for C++ linkage
3132#include <memory>
33+ #include <mutex>
3234#include <pybind11/pybind11.h>
3335#include <stddef.h> // for size_t for C linkage
3436#include <stdexcept>
@@ -142,8 +144,32 @@ class dpctl_capi
142144
143145 static auto & get ()
144146 {
145- static dpctl_capi api {};
146- return api ;
147+ static std ::atomic < dpctl_capi * > global_capi {nullptr };
148+ dpctl_capi * capi_ptr = global_capi .load (std ::memory_order_acquire );
149+
150+ // fast path
151+ if (capi_ptr ) {
152+ return * capi_ptr ;
153+ }
154+
155+ // double-checked lock
156+ // can't use std::call_once here as it still may deadlock
157+ static std ::mutex init_mtx ;
158+
159+ py ::gil_scoped_release release ;
160+ std ::lock_guard < std ::mutex > lock (init_mtx );
161+
162+ capi_ptr = global_capi .load (std ::memory_order_relaxed );
163+
164+ if (!capi_ptr ) {
165+ py ::gil_scoped_acquire acquire ;
166+
167+ capi_ptr = new dpctl_capi ();
168+
169+ global_capi .store (capi_ptr , std ::memory_order_release );
170+ }
171+
172+ return * capi_ptr ;
147173 }
148174
149175 py ::object default_sycl_queue_pyobj () { return * default_sycl_queue_ ; }
You can’t perform that action at this time.
0 commit comments