Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python Raw memory helper functions #2537

Merged
merged 4 commits into from Aug 11, 2018

Conversation

jakirkham
Copy link
Contributor

In Python 3.4+, Raw memory helper functions were added to wrap, track, and check malloc and free calls for C memory outside of the GIL. These have the same API as the existing PyMem_* calls except they use Raw and never require the GIL. For Python 2/3 compatibility, export the existing PyMem_ functions on Python 2 as PyMem_Raw where they act basically equivalently. These are especially important as Python 3.6 changed the existing PyMem_ functions to allocate from pymalloc instead of the C allocator meaning the GIL must now be held with them. So these are Python 2/3 alternatives that can be relied on to not require the GIL.

@@ -22,6 +24,15 @@ cdef extern from "Python.h":
# for the I/O buffer escapes completely the Python memory
# manager."

IF PY_VERSION_HEX >= 0x03040000:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's not how this works. The Python version only comes into play at C compilation time, not during the C code generation.

Instead, add the fallback code to ModuleSetupCode.c and always define the functions here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks. Knew something was off, but wasn't sure how to fix it. Will update.

@jakirkham
Copy link
Contributor Author

Tried to update it. Though am less familiar with the inner workings of Cython. So please let me know if needs to change somehow. Thanks again for your help.

@jakirkham
Copy link
Contributor Author

If you have another chance to look, @scoder, would really appreciate it. Seems like there is some issue with this change (probably me doing something incorrectly) and could use some advice. 😄

@@ -1,3 +1,10 @@
from cpython.version cimport PY_VERSION_HEX

cdef extern from *:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just keep these together with the others below. They are all defined in Python.h.

@@ -441,6 +441,12 @@ class __Pyx_FakeReference {
#define PyObject_Realloc(p) PyMem_Realloc(p)
#endif

#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to restrict this to CPython. PyMem_Malloc() & friends should generally be available. I would add a && !defined(PyMem_Malloc), though, just in case. PyPy uses C-defines for all of the C-API, for example.

Also, more accurately, these functions were first added in 0x030400A1, as you can see from the tags here: python/cpython@0507bf5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the PyPy ones work without the GIL? Don't really know the PyPy C API so had left them out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't say. But if it's a documented C-API feature of these functions to allow that, then it's simply PyPy's fault if it doesn't support that. I don't see why it should be up to Cython to decide whether to provide these names at all.

@scoder
Copy link
Contributor

scoder commented Aug 9, 2018

Sorry, the test failures were my fault. Just pushed a test fix to master. Could you please rebase your branch?

In Python 3.4+, Raw memory helper functions were added to wrap, track,
and check `malloc` and `free` calls for C memory outside of the GIL.
These have the same API as the existing `PyMem_*` calls except they use
Raw and never require the GIL. For Python 2/3 compatibility, export the
existing `PyMem_` functions on Python 2 as `PyMem_Raw` where they act
basically equivalently. These are especially important as Python 3.6
changed the existing `PyMem_` functions to allocate from pymalloc
instead of the C allocator meaning the GIL must now be held with them.
So these are Python 2/3 alternatives that can be relied on to not
require the GIL.
To handle the Python version differences, handle the definitions of
`PyMem_Raw*` functions in `ModuleSetupCode`. Then extern them in
`cpython.mem` without using a version check or a specific header.
Technically these functions were around in some of the Python 3.4
prereleases. So add a more accurate version constraint.
@@ -1,3 +1,5 @@
from cpython.version cimport PY_VERSION_HEX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a left-over now.

@scoder
Copy link
Contributor

scoder commented Aug 9, 2018

BTW, what's missing now is a test that shows that these three functions actually work, across all Python versions.

@scoder scoder merged commit 0da92b5 into cython:master Aug 11, 2018
@scoder scoder added this to the 0.29 milestone Aug 11, 2018
@jakirkham jakirkham deleted the extern_py_raw_mem branch August 15, 2018 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants