|
4 | 4 |
|
5 | 5 | #include "Python.h" |
6 | 6 | #include "pycore_dict.h" // _PyDict_GetItem_KnownHash() |
| 7 | +#include "pycore_freelist.h" // _Py_FREELIST_POP() |
7 | 8 | #include "pycore_modsupport.h" // _PyArg_CheckPositional() |
8 | 9 | #include "pycore_moduleobject.h" // _PyModule_GetState() |
9 | 10 | #include "pycore_object.h" // _Py_SetImmortalUntracked |
@@ -75,8 +76,6 @@ typedef struct { |
75 | 76 | #define Future_Check(state, obj) PyObject_TypeCheck(obj, state->FutureType) |
76 | 77 | #define Task_Check(state, obj) PyObject_TypeCheck(obj, state->TaskType) |
77 | 78 |
|
78 | | -#define FI_FREELIST_MAXLEN 255 |
79 | | - |
80 | 79 | #ifdef Py_GIL_DISABLED |
81 | 80 | # define ASYNCIO_STATE_LOCK(state) PyMutex_Lock(&state->mutex) |
82 | 81 | # define ASYNCIO_STATE_UNLOCK(state) PyMutex_Unlock(&state->mutex) |
@@ -138,11 +137,6 @@ typedef struct { |
138 | 137 | /* Counter for autogenerated Task names */ |
139 | 138 | uint64_t task_name_counter; |
140 | 139 |
|
141 | | -#ifndef Py_GIL_DISABLED |
142 | | - futureiterobject *fi_freelist; |
143 | | - Py_ssize_t fi_freelist_len; |
144 | | -#endif |
145 | | - |
146 | 140 | /* Linked-list of all tasks which are instances of asyncio.Task or subclasses |
147 | 141 | of it. Third party tasks implementations which don't inherit from |
148 | 142 | asyncio.Task are tracked separately using the 'non_asyncio_tasks' WeakSet. |
@@ -1584,24 +1578,7 @@ FutureIter_dealloc(futureiterobject *it) |
1584 | 1578 | PyObject_GC_UnTrack(it); |
1585 | 1579 | tp->tp_clear((PyObject *)it); |
1586 | 1580 |
|
1587 | | -#ifndef Py_GIL_DISABLED |
1588 | | - // GH-115874: We can't use PyType_GetModuleByDef here as the type might have |
1589 | | - // already been cleared, which is also why we must check if ht_module != NULL. |
1590 | | - PyObject *module = ((PyHeapTypeObject*)tp)->ht_module; |
1591 | | - asyncio_state *state = NULL; |
1592 | | - if (module && _PyModule_GetDef(module) == &_asynciomodule) { |
1593 | | - state = get_asyncio_state(module); |
1594 | | - } |
1595 | | - |
1596 | | - // TODO GH-121621: This should be moved to thread state as well. |
1597 | | - if (state && state->fi_freelist_len < FI_FREELIST_MAXLEN) { |
1598 | | - state->fi_freelist_len++; |
1599 | | - it->future = (FutureObj*) state->fi_freelist; |
1600 | | - state->fi_freelist = it; |
1601 | | - } |
1602 | | - else |
1603 | | -#endif |
1604 | | - { |
| 1581 | + if (!_Py_FREELIST_PUSH(futureiters, it, Py_futureiters_MAXFREELIST)) { |
1605 | 1582 | PyObject_GC_Del(it); |
1606 | 1583 | Py_DECREF(tp); |
1607 | 1584 | } |
@@ -1805,17 +1782,8 @@ future_new_iter(PyObject *fut) |
1805 | 1782 | asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); |
1806 | 1783 | ENSURE_FUTURE_ALIVE(state, fut) |
1807 | 1784 |
|
1808 | | -#ifndef Py_GIL_DISABLED |
1809 | | - if (state->fi_freelist_len) { |
1810 | | - state->fi_freelist_len--; |
1811 | | - it = state->fi_freelist; |
1812 | | - state->fi_freelist = (futureiterobject*) it->future; |
1813 | | - it->future = NULL; |
1814 | | - _Py_NewReference((PyObject*) it); |
1815 | | - } |
1816 | | - else |
1817 | | -#endif |
1818 | | - { |
| 1785 | + it = _Py_FREELIST_POP(futureiterobject, futureiters); |
| 1786 | + if (it == NULL) { |
1819 | 1787 | it = PyObject_GC_New(futureiterobject, state->FutureIterType); |
1820 | 1788 | if (it == NULL) { |
1821 | 1789 | return NULL; |
@@ -3678,27 +3646,6 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop) |
3678 | 3646 | return tasks; |
3679 | 3647 | } |
3680 | 3648 |
|
3681 | | -static void |
3682 | | -module_free_freelists(asyncio_state *state) |
3683 | | -{ |
3684 | | -#ifndef Py_GIL_DISABLED |
3685 | | - PyObject *next; |
3686 | | - PyObject *current; |
3687 | | - |
3688 | | - next = (PyObject*) state->fi_freelist; |
3689 | | - while (next != NULL) { |
3690 | | - assert(state->fi_freelist_len > 0); |
3691 | | - state->fi_freelist_len--; |
3692 | | - |
3693 | | - current = next; |
3694 | | - next = (PyObject*) ((futureiterobject*) current)->future; |
3695 | | - PyObject_GC_Del(current); |
3696 | | - } |
3697 | | - assert(state->fi_freelist_len == 0); |
3698 | | - state->fi_freelist = NULL; |
3699 | | -#endif |
3700 | | -} |
3701 | | - |
3702 | 3649 | static int |
3703 | 3650 | module_traverse(PyObject *mod, visitproc visit, void *arg) |
3704 | 3651 | { |
@@ -3727,16 +3674,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg) |
3727 | 3674 |
|
3728 | 3675 | Py_VISIT(state->context_kwname); |
3729 | 3676 |
|
3730 | | -#ifndef Py_GIL_DISABLED |
3731 | | - // Visit freelist. |
3732 | | - PyObject *next = (PyObject*) state->fi_freelist; |
3733 | | - while (next != NULL) { |
3734 | | - PyObject *current = next; |
3735 | | - Py_VISIT(current); |
3736 | | - next = (PyObject*) ((futureiterobject*) current)->future; |
3737 | | - } |
3738 | | -#endif |
3739 | | - |
3740 | 3677 | return 0; |
3741 | 3678 | } |
3742 | 3679 |
|
@@ -3768,8 +3705,6 @@ module_clear(PyObject *mod) |
3768 | 3705 |
|
3769 | 3706 | Py_CLEAR(state->context_kwname); |
3770 | 3707 |
|
3771 | | - module_free_freelists(state); |
3772 | | - |
3773 | 3708 | return 0; |
3774 | 3709 | } |
3775 | 3710 |
|
|
0 commit comments