summaryrefslogtreecommitdiffstats
path: root/Python/ceval_macros.h
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval_macros.h')
-rw-r--r--Python/ceval_macros.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 603b71e..9250b86 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -284,6 +284,29 @@ GETITEM(PyObject *v, Py_ssize_t i) {
}
+// Try to lock an object in the free threading build, if it's not already
+// locked. Use with a DEOPT_IF() to deopt if the object is already locked.
+// These are no-ops in the default GIL build. The general pattern is:
+//
+// DEOPT_IF(!LOCK_OBJECT(op));
+// if (/* condition fails */) {
+// UNLOCK_OBJECT(op);
+// DEOPT_IF(true);
+// }
+// ...
+// UNLOCK_OBJECT(op);
+//
+// NOTE: The object must be unlocked on every exit code path and you should
+// avoid any potentially escaping calls (like PyStackRef_CLOSE) while the
+// object is locked.
+#ifdef Py_GIL_DISABLED
+# define LOCK_OBJECT(op) PyMutex_LockFast(&(_PyObject_CAST(op))->ob_mutex._bits)
+# define UNLOCK_OBJECT(op) PyMutex_Unlock(&(_PyObject_CAST(op))->ob_mutex)
+#else
+# define LOCK_OBJECT(op) (1)
+# define UNLOCK_OBJECT(op) ((void)0)
+#endif
+
#define GLOBALS() frame->f_globals
#define BUILTINS() frame->f_builtins
#define LOCALS() frame->f_locals