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+
30+ #include <atomic>
2931#include <complex>
3032#include <cstddef> // for std::size_t for C++ linkage
3133#include <memory>
34+ #include <mutex>
3235#include <pybind11/pybind11.h>
3336#include <stddef.h> // for size_t for C linkage
3437#include <stdexcept>
@@ -142,8 +145,33 @@ class dpctl_capi
142145
143146 static auto & get ()
144147 {
145- static dpctl_capi api {};
146- return api ;
148+ static std ::atomic < dpctl_capi * > global_capi {nullptr };
149+ dpctl_capi * capi_ptr = global_capi .load (std ::memory_order_acquire );
150+
151+ // fast path
152+ if (capi_ptr ) {
153+ return * capi_ptr ;
154+ }
155+
156+ static std ::mutex init_mtx ;
157+
158+ // release gil while holding lock
159+ py ::gil_scoped_release release ;
160+ std ::lock_guard < std ::mutex > lock (init_mtx );
161+
162+ // double check after acquiring lock
163+ capi_ptr = global_capi .load (std ::memory_order_relaxed );
164+
165+ if (!capi_ptr ) {
166+ // acquire gil to safely call into Python C API
167+ py ::gil_scoped_acquire acquire ;
168+
169+ capi_ptr = new dpctl_capi ();
170+
171+ global_capi .store (capi_ptr , std ::memory_order_release );
172+ }
173+
174+ return * capi_ptr ;
147175 }
148176
149177 py ::object default_sycl_queue_pyobj () { return * default_sycl_queue_ ; }
You can’t perform that action at this time.
0 commit comments