Commit 2bda6d1f authored by Jason Madden's avatar Jason Madden

Stop using the PyObject_ allocation functions on PyPy altogether.

They take special linking (unlike CPython) because the PyPy maintainers don't want you using them. That leaves us without a way to add memory pressure from C on PyPy.
parent 27e913c6
PyPy no longer uses the Python allocation functions for libuv and
libev allocations.
#define GIL_DECLARE PyGILState_STATE ___save #include <stddef.h>
#define GIL_ENSURE ___save = PyGILState_Ensure(); #ifndef GEVENT_ALLOC_C
#define GIL_RELEASE PyGILState_Release(___save); #define GEVENT_ALLOC_C
#ifdef PYPY_VERSION_NUM
#define GGIL_DECLARE
#define GGIL_ENSURE
#define GGIL_RELEASE
#define GPyObject_Free free
#define GPyObject_Realloc realloc
#else
#include "Python.h"
#define GGIL_DECLARE PyGILState_STATE ___save
#define GGIL_ENSURE ___save = PyGILState_Ensure();
#define GGIL_RELEASE PyGILState_Release(___save);
#define GPyObject_Free PyObject_Free
#define GPyObject_Realloc PyObject_Realloc
#endif
void* gevent_realloc(void* ptr, size_t size) void* gevent_realloc(void* ptr, size_t size)
{ {
...@@ -8,26 +23,34 @@ void* gevent_realloc(void* ptr, size_t size) ...@@ -8,26 +23,34 @@ void* gevent_realloc(void* ptr, size_t size)
// done with realloc(), assuming that passing in a size of 0 means to // done with realloc(), assuming that passing in a size of 0 means to
// free the pointer. But the C/++ standard explicitly says that // free the pointer. But the C/++ standard explicitly says that
// this is undefined. So this wrapper function exists to do it all. // this is undefined. So this wrapper function exists to do it all.
GIL_DECLARE; GGIL_DECLARE;
void* result; void* result;
if(!size && !ptr) { if(!size && !ptr) {
// libev for some reason often tries to free(NULL); I won't specutale // libev for some reason often tries to free(NULL); I won't specutale
// why. No need to acquire the GIL or do anything in that case. // why. No need to acquire the GIL or do anything in that case.
return NULL; return NULL;
} }
// Using PyObject_* APIs to get access to pymalloc allocator on // Using PyObject_* APIs to get access to pymalloc allocator on
// all versions of CPython; in Python 3, PyMem_* and PyObject_* use // all versions of CPython; in Python 3, PyMem_* and PyObject_* use
// the same allocator, but in Python 2, only PyObject_* uses pymalloc. // the same allocator, but in Python 2, only PyObject_* uses pymalloc.
GIL_ENSURE; GGIL_ENSURE;
if(!size) { if(!size) {
PyObject_Free(ptr); GPyObject_Free(ptr);
result = NULL; result = NULL;
} }
else { else {
result = PyObject_Realloc(ptr, size); result = GPyObject_Realloc(ptr, size);
} }
GIL_RELEASE; GGIL_RELEASE;
return result; return result;
} }
#undef GGIL_DECLARE
#undef GGIL_ENSURE
#undef GGIL_RELEASE
#undef GPyObject_Free
#undef GPyObject_Realloc
#endif /* GEVENT_ALLOC_C */
...@@ -4,8 +4,17 @@ ...@@ -4,8 +4,17 @@
#include "ev.h" #include "ev.h"
#include "corecext.h" #include "corecext.h"
#include "callbacks.h" #include "callbacks.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#ifdef Py_PYTHON_H #ifdef Py_PYTHON_H
/* define gevent_realloc with libev semantics */
#include "../_ffi/alloc.c"
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
#define PyInt_FromLong PyLong_FromLong #define PyInt_FromLong PyLong_FromLong
#endif #endif
...@@ -25,6 +34,10 @@ ...@@ -25,6 +34,10 @@
#endif #endif
#endif #endif
#define GGIL_DECLARE PyGILState_STATE ___save
#define GGIL_ENSURE ___save = PyGILState_Ensure();
#define GGIL_RELEASE PyGILState_Release(___save);
static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) { static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) {
if (!ev_is_default_loop(loop->_ptr)) { if (!ev_is_default_loop(loop->_ptr)) {
...@@ -39,10 +52,6 @@ static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) ...@@ -39,10 +52,6 @@ static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop)
((struct PY_TYPE *)(((char *)EV_PTR) - offsetof(struct PY_TYPE, MEMBER))) ((struct PY_TYPE *)(((char *)EV_PTR) - offsetof(struct PY_TYPE, MEMBER)))
/* define gevent_realloc with libev semantics */
#include "../_ffi/alloc.c"
void gevent_noop(struct ev_loop* loop, void* watcher, int revents) {} void gevent_noop(struct ev_loop* loop, void* watcher, int revents) {}
static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) { static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) {
...@@ -65,11 +74,11 @@ static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) { ...@@ -65,11 +74,11 @@ static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) {
static void gevent_callback(struct PyGeventLoopObject* loop, PyObject* callback, PyObject* args, PyObject* watcher, void *c_watcher, int revents) { static void gevent_callback(struct PyGeventLoopObject* loop, PyObject* callback, PyObject* args, PyObject* watcher, void *c_watcher, int revents) {
GIL_DECLARE; GGIL_DECLARE;
PyObject *result, *py_events; PyObject *result, *py_events;
long length; long length;
py_events = 0; py_events = 0;
GIL_ENSURE; GGIL_ENSURE;
Py_INCREF(loop); Py_INCREF(loop);
Py_INCREF(callback); Py_INCREF(callback);
Py_INCREF(args); Py_INCREF(args);
...@@ -121,7 +130,7 @@ end: ...@@ -121,7 +130,7 @@ end:
Py_DECREF(args); Py_DECREF(args);
Py_DECREF(callback); Py_DECREF(callback);
Py_DECREF(loop); Py_DECREF(loop);
GIL_RELEASE; GGIL_RELEASE;
} }
...@@ -181,8 +190,8 @@ DEFINE_CALLBACKS ...@@ -181,8 +190,8 @@ DEFINE_CALLBACKS
void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) { void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) {
struct PyGeventLoopObject* loop; struct PyGeventLoopObject* loop;
PyObject *result; PyObject *result;
GIL_DECLARE; GGIL_DECLARE;
GIL_ENSURE; GGIL_ENSURE;
loop = GET_OBJECT(PyGeventLoopObject, watcher, _prepare); loop = GET_OBJECT(PyGeventLoopObject, watcher, _prepare);
Py_INCREF(loop); Py_INCREF(loop);
gevent_check_signals(loop); gevent_check_signals(loop);
...@@ -195,16 +204,24 @@ void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) { ...@@ -195,16 +204,24 @@ void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) {
PyErr_Clear(); PyErr_Clear();
} }
Py_DECREF(loop); Py_DECREF(loop);
GIL_RELEASE; GGIL_RELEASE;
} }
/* This is only used on Win32 */ /* This is only used on Win32 */
void gevent_periodic_signal_check(struct ev_loop *_loop, void *watcher, int revents) { void gevent_periodic_signal_check(struct ev_loop *_loop, void *watcher, int revents) {
GIL_DECLARE; GGIL_DECLARE;
GIL_ENSURE; GGIL_ENSURE;
gevent_check_signals(GET_OBJECT(PyGeventLoopObject, watcher, _periodic_signal_checker)); gevent_check_signals(GET_OBJECT(PyGeventLoopObject, watcher, _periodic_signal_checker));
GIL_RELEASE; GGIL_RELEASE;
} }
#undef GGIL_DECLARE
#undef GGIL_ENSURE
#undef GGIL_RELEASE
#endif /* Py_PYTHON_H */ #endif /* Py_PYTHON_H */
#ifdef __clang__
#pragma clang diagnostic pop
#endif
...@@ -131,14 +131,6 @@ static void gevent_zero_loop(uv_loop_t* handle) ...@@ -131,14 +131,6 @@ static void gevent_zero_loop(uv_loop_t* handle)
memset(handle, 0, sizeof(uv_loop_t)); memset(handle, 0, sizeof(uv_loop_t));
} }
#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM <= 0x07020000
/* Pypy 7.2 and below don't have the needed APIs.
See
https://ci.appveyor.com/project/denik/gevent/builds/30029974/job/oqf8pjpm7r28hcy2
*/
static void gevent_set_uv_alloc() {}
#else
#include "_ffi/alloc.c" #include "_ffi/alloc.c"
static void* _gevent_uv_malloc(size_t size) static void* _gevent_uv_malloc(size_t size)
...@@ -175,14 +167,9 @@ static void gevent_set_uv_alloc() ...@@ -175,14 +167,9 @@ static void gevent_set_uv_alloc()
_gevent_uv_calloc, _gevent_uv_calloc,
_gevent_uv_free); _gevent_uv_free);
} }
#endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code" #pragma clang diagnostic ignored "-Wunreachable-code"
#endif #endif
/* Local Variables: */
/* flycheck-clang-include-path: ("../../../deps/libuv/include") */
/* End: */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment