diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-06-14 22:37:46 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-06-14 22:37:46 (GMT) |
commit | 4d7056258b07df7cbb1b9b44e7a1a9bad04f7454 (patch) | |
tree | f5b3d2b16be7b8d16dd234ac59c722d0ca24e0b4 /Doc/c-api | |
parent | 8c18da20f979cf428414a038bfaee46283e12fa2 (diff) | |
download | cpython-4d7056258b07df7cbb1b9b44e7a1a9bad04f7454.zip cpython-4d7056258b07df7cbb1b9b44e7a1a9bad04f7454.tar.gz cpython-4d7056258b07df7cbb1b9b44e7a1a9bad04f7454.tar.bz2 |
Issue #3329: Add new APIs to customize memory allocators
* Add a new PyMemAllocators structure
* New functions:
- PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree(): GIL-free memory
allocator functions
- PyMem_GetRawAllocators(), PyMem_SetRawAllocators()
- PyMem_GetAllocators(), PyMem_SetAllocators()
- PyMem_SetupDebugHooks()
- _PyObject_GetArenaAllocators(), _PyObject_SetArenaAllocators()
* Add unit test for PyMem_Malloc(0) and PyObject_Malloc(0)
* Add unit test for new get/set allocators functions
* PyObject_Malloc() now falls back on PyMem_Malloc() instead of malloc() if
size is bigger than SMALL_REQUEST_THRESHOLD, and PyObject_Realloc() falls
back on PyMem_Realloc() instead of realloc()
* PyMem_Malloc() and PyMem_Realloc() now always call malloc() and realloc(),
instead of calling PyObject_Malloc() and PyObject_Realloc() in debug mode
Diffstat (limited to 'Doc/c-api')
-rw-r--r-- | Doc/c-api/memory.rst | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 8afa56a..5b8fb44 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -84,6 +84,46 @@ the C library allocator as shown in the previous example, the allocated memory for the I/O buffer escapes completely the Python memory manager. +Raw Memory Interface +==================== + +The following function are wrappers to system allocators: :c:func:`malloc`, +:c:func:`realloc`, :c:func:`free`. These functions are thread-safe, the +:term:`GIL <global interpreter lock>` does not need to be held to use these +functions. + +The behaviour of requesting zero bytes is not defined: return *NULL* or a +distinct non-*NULL* pointer depending on the platform. Use +:c:func:`PyMem_Malloc` and :c:func:`PyMem_Realloc` to have a well defined +behaviour. + +.. versionadded:: 3.4 + +.. c:function:: void* PyMem_RawMalloc(size_t n) + + Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the + allocated memory, or *NULL* if the request fails. The memory + will not have been initialized in any way. + + +.. c:function:: void* PyMem_RawRealloc(void *p, size_t n) + + Resizes the memory block pointed to by *p* to *n* bytes. The contents will + be unchanged to the minimum of the old and the new sizes. If *p* is *NULL*, + the call is equivalent to ``PyMem_RawMalloc(n)``. Unless *p* is *NULL*, it + must have been returned by a previous call to :c:func:`PyMem_RawMalloc` or + :c:func:`PyMem_RawRealloc`. If the request fails, :c:func:`PyMem_RawRealloc` + returns *NULL* and *p* remains a valid pointer to the previous memory area. + + +.. c:function:: void PyMem_RawFree(void *p) + + Frees the memory block pointed to by *p*, which must have been returned by a + previous call to :c:func:`PyMem_RawMalloc` or :c:func:`PyMem_RawRealloc`. + Otherwise, or if ``PyMem_Free(p)`` has been called before, undefined + behavior occurs. If *p* is *NULL*, no operation is performed. + + .. _memoryinterface: Memory Interface @@ -91,8 +131,12 @@ Memory Interface The following function sets, modeled after the ANSI C standard, but specifying behavior when requesting zero bytes, are available for allocating and releasing -memory from the Python heap: +memory from the Python heap. +.. warning:: + + The :term:`GIL <global interpreter lock>` must be held when using these + functions. .. c:function:: void* PyMem_Malloc(size_t n) @@ -155,6 +199,81 @@ versions and is therefore deprecated in extension modules. :c:func:`PyMem_NEW`, :c:func:`PyMem_RESIZE`, :c:func:`PyMem_DEL`. +Customize Memory Allocators +=========================== + +.. versionadded:: 3.4 + +.. c:type:: PyMemAllocators + + Structure used to describe memory allocator. This structure has + four fields: + + +----------------------------------------------------------+-----------------+ + | Field | Meaning | + +==========================================================+=================+ + | ``void *ctx`` | user data | + +----------------------------------------------------------+-----------------+ + | ``void* malloc(void *ctx, size_t size)`` | allocate memory | + +----------------------------------------------------------+-----------------+ + | ``void* realloc(void *ctx, void *ptr, size_t new_size)`` | allocate memory | + | | or resize a | + | | memory block | + +----------------------------------------------------------+-----------------+ + | ``void free(void *ctx, void *ptr)`` | release memory | + +----------------------------------------------------------+-----------------+ + +.. c:function:: void PyMem_GetRawAllocators(PyMemAllocators *allocators) + + Get internal functions of :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` + and :c:func:`PyMem_RawFree`. + +.. c:function:: void PyMem_SetRawAllocators(PyMemAllocators *allocators) + + Set internal functions of :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` + and :c:func:`PyMem_RawFree`. + + :c:func:`PyMem_SetupDebugHooks` should be called to reinstall debug hooks if + new functions do no call original functions anymore. + +.. c:function:: void PyMem_GetAllocators(PyMemAllocators *allocators) + + Get internal functions of :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` + and :c:func:`PyMem_Free`. + +.. c:function:: void PyMem_SetAllocators(PyMemAllocators *allocators) + + Set internal functions of :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc` + and :c:func:`PyMem_Free`. + + ``malloc(ctx, 0)`` and ``realloc(ctx, ptr, 0)`` must not return *NULL*: it + would be treated as an error. + + :c:func:`PyMem_SetupDebugHooks` should be called to reinstall debug hooks if + new functions do no call original functions anymore. + +.. c:function:: void PyMem_SetupDebugHooks(void) + + Setup hooks to detect bugs in the following Python memory allocator + functions: + + - :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc`, + :c:func:`PyMem_RawFree` + - :c:func:`PyMem_Malloc`, :c:func:`PyMem_Realloc`, :c:func:`PyMem_Free` + - :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc`, + :c:func:`PyObject_Free` + + Newly allocated memory is filled with the byte ``0xCB``, freed memory is + filled with the byte ``0xDB``. Additionnal checks: + + - detect API violations, ex: :c:func:`PyObject_Free` called on a buffer + allocated by :c:func:`PyMem_Malloc` + - detect write before the start of the buffer (buffer underflow) + - detect write after the end of the buffer (buffer overflow) + + The function does nothing if Python is not compiled is debug mode. + + .. _memoryexamples: Examples |