Skip to content

Commit

Permalink
GH-103092: port _asyncio freelist to module state (#104196)
Browse files Browse the repository at this point in the history
  • Loading branch information
kumaraditya303 authored May 5, 2023
1 parent 81fc135 commit 2318bed
Showing 1 changed file with 25 additions and 27 deletions.
52 changes: 25 additions & 27 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ module _asyncio
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/


#define FI_FREELIST_MAXLEN 255

typedef struct futureiterobject futureiterobject;

/* State of the _asyncio module */
typedef struct {
PyTypeObject *FutureIterType;
Expand Down Expand Up @@ -67,6 +71,9 @@ typedef struct {

/* Counter for autogenerated Task names */
uint64_t task_name_counter;

futureiterobject *fi_freelist;
Py_ssize_t fi_freelist_len;
} asyncio_state;

static inline asyncio_state *
Expand Down Expand Up @@ -1574,28 +1581,24 @@ FutureObj_dealloc(PyObject *self)

/*********************** Future Iterator **************************/

typedef struct {
typedef struct futureiterobject {
PyObject_HEAD
FutureObj *future;
} futureiterobject;


#define FI_FREELIST_MAXLEN 255
static futureiterobject *fi_freelist = NULL;
static Py_ssize_t fi_freelist_len = 0;


static void
FutureIter_dealloc(futureiterobject *it)
{
PyTypeObject *tp = Py_TYPE(it);
asyncio_state *state = get_asyncio_state_by_def((PyObject *)it);
PyObject_GC_UnTrack(it);
tp->tp_clear((PyObject *)it);

if (fi_freelist_len < FI_FREELIST_MAXLEN) {
fi_freelist_len++;
it->future = (FutureObj*) fi_freelist;
fi_freelist = it;
if (state->fi_freelist_len < FI_FREELIST_MAXLEN) {
state->fi_freelist_len++;
it->future = (FutureObj*) state->fi_freelist;
state->fi_freelist = it;
}
else {
PyObject_GC_Del(it);
Expand Down Expand Up @@ -1799,17 +1802,12 @@ future_new_iter(PyObject *fut)
futureiterobject *it;

asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
if (!Future_Check(state, fut)) {
PyErr_BadInternalCall();
return NULL;
}

ENSURE_FUTURE_ALIVE(state, fut)

if (fi_freelist_len) {
fi_freelist_len--;
it = fi_freelist;
fi_freelist = (futureiterobject*) it->future;
if (state->fi_freelist_len) {
state->fi_freelist_len--;
it = state->fi_freelist;
state->fi_freelist = (futureiterobject*) it->future;
it->future = NULL;
_Py_NewReference((PyObject*) it);
}
Expand Down Expand Up @@ -3556,22 +3554,22 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop)


static void
module_free_freelists(void)
module_free_freelists(asyncio_state *state)
{
PyObject *next;
PyObject *current;

next = (PyObject*) fi_freelist;
next = (PyObject*) state->fi_freelist;
while (next != NULL) {
assert(fi_freelist_len > 0);
fi_freelist_len--;
assert(state->fi_freelist_len > 0);
state->fi_freelist_len--;

current = next;
next = (PyObject*) ((futureiterobject*) current)->future;
PyObject_GC_Del(current);
}
assert(fi_freelist_len == 0);
fi_freelist = NULL;
assert(state->fi_freelist_len == 0);
state->fi_freelist = NULL;
}

static int
Expand Down Expand Up @@ -3603,7 +3601,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
Py_VISIT(state->context_kwname);

// Visit freelist.
PyObject *next = (PyObject*) fi_freelist;
PyObject *next = (PyObject*) state->fi_freelist;
while (next != NULL) {
PyObject *current = next;
Py_VISIT(current);
Expand Down Expand Up @@ -3640,7 +3638,7 @@ module_clear(PyObject *mod)

Py_CLEAR(state->context_kwname);

module_free_freelists();
module_free_freelists(state);

return 0;
}
Expand Down

0 comments on commit 2318bed

Please sign in to comment.