Skip to content

Commit

Permalink
interpreter.c: Temporary reset PYMEM_DOMAIN_RAW allocator
Browse files Browse the repository at this point in the history
So tracemalloc won't deadlock on us.

Ref #11
  • Loading branch information
zhuyifei1999 committed Nov 26, 2019
1 parent 2ea3496 commit 98dfad7
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/heapy/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,68 @@ static char hp_set_async_exc_doc[] =
#include "pythread.h"
#include "eval.h"

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
# define Py_BUILD_CORE
/* _PyMem_SetDefaultAllocator */
# include <internal/pycore_pymem.h>
# undef Py_BUILD_CORE
#elif PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 7
PyAPI_FUNC(int) _PyMem_SetDefaultAllocator(
PyMemAllocatorDomain domain,
PyMemAllocatorEx *old_alloc);
#else
// source: cpython: Objects/obmalloc.c
static void *
_PyMem_RawMalloc(void *ctx, size_t size)
{
if (size == 0)
size = 1;
return malloc(size);
}

static void *
_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize)
{
if (nelem == 0 || elsize == 0) {
nelem = 1;
elsize = 1;
}
return calloc(nelem, elsize);
}

static void *
_PyMem_RawRealloc(void *ctx, void *ptr, size_t size)
{
if (size == 0)
size = 1;
return realloc(ptr, size);
}

static void
_PyMem_RawFree(void *ctx, void *ptr)
{
free(ptr);
}

static int _PyMem_SetDefaultAllocator(
PyMemAllocatorDomain domain,
PyMemAllocatorEx *old_alloc)
{
assert(domain == PYMEM_DOMAIN_RAW);
PyMem_GetAllocator(domain, old_alloc);

PyMemAllocatorEx alloc = {
.malloc = _PyMem_RawMalloc,
.calloc = _PyMem_RawCalloc,
.realloc = _PyMem_RawRealloc,
.free = _PyMem_RawFree,
.ctx = NULL
};
PyMem_SetAllocator(domain, &alloc);
return 0;
}
#endif

struct bootstate {
PyObject *cmd;
PyObject *locals;
Expand All @@ -49,11 +111,17 @@ t_bootstrap(void *boot_raw)
int res = 0;
const char *str;

// This is needed so that tracemalloc won't deadlock on us
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

// borrow GIL from parent
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
tstate = Py_NewInterpreter();
PyThreadState_Swap(save_tstate);

PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

if (!tstate) {
Py_DECREF(boot->cmd);
Py_XDECREF(boot->locals);
Expand Down
1 change: 1 addition & 0 deletions src/heapy/rootstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ char rootstate_doc[] =

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
# define Py_BUILD_CORE
/* PyInterpreterState */
# include <internal/pycore_pystate.h>
# undef Py_BUILD_CORE
#endif
Expand Down

0 comments on commit 98dfad7

Please sign in to comment.