@@ -241,9 +241,20 @@ static MlirBlock createBlock(const py::sequence &pyArgTypes,
241241
242242// / Wrapper for the global LLVM debugging flag.
243243struct PyGlobalDebugFlag {
244- static void set (py::object &o, bool enable) { mlirEnableGlobalDebug (enable); }
244+ static void set (py::object &o, bool enable) {
245+ withLock ([&](){
246+ mlirEnableGlobalDebug (enable);
247+ return 0 ;
248+ });
249+ }
245250
246- static bool get (const py::object &) { return mlirIsGlobalDebugEnabled (); }
251+ static bool get (const py::object &) {
252+ // Use lock in free-threading to avoid data-races,
253+ // observed in ir/debug.py, testDebugDlag
254+ return withLock ([&](){
255+ return mlirIsGlobalDebugEnabled ();
256+ });
257+ }
247258
248259 static void bind (py::module &m) {
249260 // Debug flags.
@@ -253,40 +264,72 @@ struct PyGlobalDebugFlag {
253264 .def_static (
254265 " set_types" ,
255266 [](const std::string &type) {
256- mlirSetGlobalDebugType (type.c_str ());
267+ withLock ([&](){
268+ mlirSetGlobalDebugType (type.c_str ());
269+ return 0 ;
270+ });
257271 },
258272 " types" _a, " Sets specific debug types to be produced by LLVM" )
259273 .def_static (" set_types" , [](const std::vector<std::string> &types) {
260274 std::vector<const char *> pointers;
261275 pointers.reserve (types.size ());
262276 for (const std::string &str : types)
263277 pointers.push_back (str.c_str ());
264- mlirSetGlobalDebugTypes (pointers.data (), pointers.size ());
278+ withLock ([&](){
279+ mlirSetGlobalDebugTypes (pointers.data (), pointers.size ());
280+ return 0 ;
281+ });
265282 });
266283 }
284+
285+ private:
286+ #ifdef Py_GIL_DISABLED
287+ static PyMutex &getLock () {
288+ static PyMutex lock;
289+ return lock;
290+ }
291+ #endif
292+
293+ template <typename F>
294+ static inline auto withLock (const F& cb) -> decltype(cb()) {
295+ #ifdef Py_GIL_DISABLED
296+ auto &lock = getLock ();
297+ PyMutex_Lock (&lock);
298+ #endif
299+ auto result = cb ();
300+ #ifdef Py_GIL_DISABLED
301+ PyMutex_Unlock (&lock);
302+ #endif
303+ return result;
304+ }
267305};
268306
269307struct PyAttrBuilderMap {
270308 static bool dunderContains (const std::string &attributeKind) {
271309 return PyGlobals::get ().lookupAttributeBuilder (attributeKind).has_value ();
272310 }
273- static py::function dundeGetItemNamed (const std::string &attributeKind) {
274- auto builder = PyGlobals::get ().lookupAttributeBuilder (attributeKind);
311+ static py::function dunderGetItemNamed (const std::string &attributeKind) {
312+ auto builder = PyGlobals::withInstance ([&](PyGlobals& instance) {
313+ return instance.lookupAttributeBuilder (attributeKind);
314+ });
275315 if (!builder)
276316 throw py::key_error (attributeKind);
277317 return *builder;
278318 }
279- static void dundeSetItemNamed (const std::string &attributeKind,
319+ static void dunderSetItemNamed (const std::string &attributeKind,
280320 py::function func, bool replace) {
281- PyGlobals::get ().registerAttributeBuilder (attributeKind, std::move (func),
282- replace);
321+ PyGlobals::withInstance ([&](PyGlobals& instance) {
322+ instance.registerAttributeBuilder (attributeKind, std::move (func),
323+ replace);
324+ return 0 ;
325+ });
283326 }
284327
285328 static void bind (py::module &m) {
286329 py::class_<PyAttrBuilderMap>(m, " AttrBuilder" , py::module_local ())
287330 .def_static (" contains" , &PyAttrBuilderMap::dunderContains)
288- .def_static (" get" , &PyAttrBuilderMap::dundeGetItemNamed )
289- .def_static (" insert" , &PyAttrBuilderMap::dundeSetItemNamed ,
331+ .def_static (" get" , &PyAttrBuilderMap::dunderGetItemNamed )
332+ .def_static (" insert" , &PyAttrBuilderMap::dunderSetItemNamed ,
290333 " attribute_kind" _a, " attr_builder" _a, " replace" _a = false ,
291334 " Register an attribute builder for building MLIR "
292335 " attributes from python values." );
0 commit comments