summaryrefslogtreecommitdiffstats
path: root/Python/ceval_macros.h
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-11-26 21:46:06 (GMT)
committerGitHub <noreply@github.com>2024-11-26 21:46:06 (GMT)
commit71ede1142ddad2d31cc966b8fe4a5aff664f4d53 (patch)
treec8e17fd89be977bf04ffd1c01b352c4bbcb191f5 /Python/ceval_macros.h
parentf0d3f10c43c9029378adba11a65b3d1287e4be32 (diff)
downloadcpython-71ede1142ddad2d31cc966b8fe4a5aff664f4d53.zip
cpython-71ede1142ddad2d31cc966b8fe4a5aff664f4d53.tar.gz
cpython-71ede1142ddad2d31cc966b8fe4a5aff664f4d53.tar.bz2
gh-115999: Add free-threaded specialization for `STORE_SUBSCR` (#127169)
The specialization only depends on the type, so no special thread-safety considerations there. STORE_SUBSCR_LIST_INT needs to lock the list before modifying it. `_PyDict_SetItem_Take2` already internally locks the dictionary using a critical section.
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