From 86efce6aa68bee59aa1b4a3502d7385ad4a5dbb5 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 12 Sep 2024 21:36:42 +0900 Subject: [PATCH 1/6] gh-119802: Update memory management docs for free-threaded build --- Doc/c-api/memory.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 4ecc998b37e598..9f23d8e9fc7444 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -102,12 +102,16 @@ All allocating functions belong to one of three different "domains" (see also strategies and are optimized for different purposes. The specific details on how every domain allocates memory or what internal functions each domain calls is considered an implementation detail, but for debugging purposes a simplified -table can be found at :ref:`here `. There is no hard -requirement to use the memory returned by the allocation functions belonging to -a given domain for only the purposes hinted by that domain (although this is the -recommended practice). For example, one could use the memory returned by -:c:func:`PyMem_RawMalloc` for allocating Python objects or the memory returned -by :c:func:`PyObject_Malloc` for allocating memory for buffers. +table can be found at :ref:`here `. In the default build, +there is no hard requirement to use the memory returned by the allocation functions +belonging to a given domain for only the purposes hinted by that domain. +(although this is the recommended practice). For example, one could use the memory +returned by :c:func:`PyMem_RawMalloc` for allocating Python objects or the memory +returned by :c:func:`PyObject_Malloc` for allocating memory for buffers. +However, in the free-threaded build, Python objects must be allocated through :c:func:`PyObject_Malloc`. +Non-Python objects must not be allocated this function, for example, +it is currently acceptable to allocate buffers(non-Python objects) through :c:func:`PyObject_Malloc`; +that will no longer be allowed and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`.. The three allocation domains are: From 3150eab653dda4f4d621fb0a431e11a8fa8126f6 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 12 Sep 2024 21:38:12 +0900 Subject: [PATCH 2/6] nit --- Doc/c-api/memory.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 9f23d8e9fc7444..c20c5fef849252 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -109,9 +109,9 @@ belonging to a given domain for only the purposes hinted by that domain. returned by :c:func:`PyMem_RawMalloc` for allocating Python objects or the memory returned by :c:func:`PyObject_Malloc` for allocating memory for buffers. However, in the free-threaded build, Python objects must be allocated through :c:func:`PyObject_Malloc`. -Non-Python objects must not be allocated this function, for example, -it is currently acceptable to allocate buffers(non-Python objects) through :c:func:`PyObject_Malloc`; -that will no longer be allowed and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`.. +Non-Python objects must not be allocated this function, for example, it is currently acceptable to +allocate buffers(non-Python objects) through :c:func:`PyObject_Malloc`; that will no longer be allowed +and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`.. The three allocation domains are: From a92d9382af28498743e95173e71af2cb71fbb3ad Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 12 Sep 2024 21:39:39 +0900 Subject: [PATCH 3/6] nit --- Doc/c-api/memory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index c20c5fef849252..dfb0b0c4e789c8 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -111,7 +111,7 @@ returned by :c:func:`PyObject_Malloc` for allocating memory for buffers. However, in the free-threaded build, Python objects must be allocated through :c:func:`PyObject_Malloc`. Non-Python objects must not be allocated this function, for example, it is currently acceptable to allocate buffers(non-Python objects) through :c:func:`PyObject_Malloc`; that will no longer be allowed -and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`.. +and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`. The three allocation domains are: From db3acd264ac485b7f087beb94e7db0055c13c085 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Fri, 13 Sep 2024 21:15:12 +0900 Subject: [PATCH 4/6] Address code review --- Doc/c-api/memory.rst | 38 ++++++++++++++----------- Doc/howto/free-threading-extensions.rst | 2 ++ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index dfb0b0c4e789c8..674af69b907d7b 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -102,34 +102,38 @@ All allocating functions belong to one of three different "domains" (see also strategies and are optimized for different purposes. The specific details on how every domain allocates memory or what internal functions each domain calls is considered an implementation detail, but for debugging purposes a simplified -table can be found at :ref:`here `. In the default build, -there is no hard requirement to use the memory returned by the allocation functions -belonging to a given domain for only the purposes hinted by that domain. -(although this is the recommended practice). For example, one could use the memory -returned by :c:func:`PyMem_RawMalloc` for allocating Python objects or the memory -returned by :c:func:`PyObject_Malloc` for allocating memory for buffers. -However, in the free-threaded build, Python objects must be allocated through :c:func:`PyObject_Malloc`. -Non-Python objects must not be allocated this function, for example, it is currently acceptable to -allocate buffers(non-Python objects) through :c:func:`PyObject_Malloc`; that will no longer be allowed -and buffers should instead be allocated through :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`. +table can be found at :ref:`here `. +The APIs used to allocate and free a block of memory must be from the same domain. +For example, :c:func:`PyMem_Free` must be used to free memory allocated using :c:func:`PyMem_Malloc`. The three allocation domains are: * Raw domain: intended for allocating memory for general-purpose memory buffers where the allocation *must* go to the system allocator or where the allocator can operate without the :term:`GIL`. The memory is requested directly - to the system. + from the system. See :ref:`Raw Memory Interface `. * "Mem" domain: intended for allocating memory for Python buffers and general-purpose memory buffers where the allocation must be performed with the :term:`GIL` held. The memory is taken from the Python private heap. + See :ref:`Memory Interface `. -* Object domain: intended for allocating memory belonging to Python objects. The - memory is taken from the Python private heap. +* Object domain: intended for allocating memory for Python objects. The + memory is taken from the Python private heap. See :ref:`Object allocators `. -When freeing memory previously allocated by the allocating functions belonging to a -given domain,the matching specific deallocating functions must be used. For example, -:c:func:`PyMem_Free` must be used to free memory allocated using :c:func:`PyMem_Malloc`. +.. note:: + + The :term:`free-threaded ` build requires that only Python objects are allocated using the "object" domain + and that all Python objects are allocated using that domain. This differs from the prior Python versions, + where this was only a best practice and not a hard requirement. + + For example, buffers (non-Python objects) should be allocated using :c:func:`PyMem_Malloc`, + :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`, but not :c:func:`PyObject_Malloc`. + + See :ref:`Memory Allocation APIs `: + + +.. _raw-memoryinterface: Raw Memory Interface ==================== @@ -303,6 +307,8 @@ versions and is therefore deprecated in extension modules. * ``PyMem_DEL(ptr)`` +.. _objectinterface: + Object allocators ================= diff --git a/Doc/howto/free-threading-extensions.rst b/Doc/howto/free-threading-extensions.rst index 99e3ab3f52a60d..1efd81e25ef841 100644 --- a/Doc/howto/free-threading-extensions.rst +++ b/Doc/howto/free-threading-extensions.rst @@ -184,6 +184,8 @@ to provide implementations of these functions for older Python versions. Memory Allocation APIs ====================== +.. _free-threaded-memory-allocation: + Python's memory management C API provides functions in three different :ref:`allocation domains `: "raw", "mem", and "object". For thread-safety, the free-threaded build requires that only Python objects From edcda53586062b66b70fde294d0cc6dd69088494 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Fri, 13 Sep 2024 21:16:24 +0900 Subject: [PATCH 5/6] nit --- Doc/howto/free-threading-extensions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/free-threading-extensions.rst b/Doc/howto/free-threading-extensions.rst index 1efd81e25ef841..6abe93d71ad529 100644 --- a/Doc/howto/free-threading-extensions.rst +++ b/Doc/howto/free-threading-extensions.rst @@ -181,11 +181,11 @@ Some of these functions were added in Python 3.13. You can use the to provide implementations of these functions for older Python versions. +.. _free-threaded-memory-allocation: + Memory Allocation APIs ====================== -.. _free-threaded-memory-allocation: - Python's memory management C API provides functions in three different :ref:`allocation domains `: "raw", "mem", and "object". For thread-safety, the free-threaded build requires that only Python objects From 0401afaae6219b87d23081562a5fa1b1ba0db497 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Fri, 13 Sep 2024 23:55:04 +0900 Subject: [PATCH 6/6] Update Doc/c-api/memory.rst Co-authored-by: Sam Gross --- Doc/c-api/memory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 674af69b907d7b..aa2ef499bddaf3 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -130,7 +130,7 @@ The three allocation domains are: For example, buffers (non-Python objects) should be allocated using :c:func:`PyMem_Malloc`, :c:func:`PyMem_RawMalloc`, or :c:func:`malloc`, but not :c:func:`PyObject_Malloc`. - See :ref:`Memory Allocation APIs `: + See :ref:`Memory Allocation APIs `. .. _raw-memoryinterface: