GH-103092: port _asyncio freelist to module state (#104196)

This commit is contained in:
Kumar Aditya 2023-05-05 16:42:58 +05:30 committed by GitHub
parent 81fc135f26
commit 2318bedb36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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;
@ -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 *
@ -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);
@ -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);
}
@ -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
@ -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);
@ -3640,7 +3638,7 @@ module_clear(PyObject *mod)
Py_CLEAR(state->context_kwname);
module_free_freelists();
module_free_freelists(state);
return 0;
}