|
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;
|
@@ -3683,27 +3651,6 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
|
3683 | 3651 | return tasks;
|
3684 | 3652 | }
|
3685 | 3653 |
|
3686 |
| -static void |
3687 |
| -module_free_freelists(asyncio_state *state) |
3688 |
| -{ |
3689 |
| -#ifndef Py_GIL_DISABLED |
3690 |
| - PyObject *next; |
3691 |
| - PyObject *current; |
3692 |
| - |
3693 |
| - next = (PyObject*) state->fi_freelist; |
3694 |
| - while (next != NULL) { |
3695 |
| - assert(state->fi_freelist_len > 0); |
3696 |
| - state->fi_freelist_len--; |
3697 |
| - |
3698 |
| - current = next; |
3699 |
| - next = (PyObject*) ((futureiterobject*) current)->future; |
3700 |
| - PyObject_GC_Del(current); |
3701 |
| - } |
3702 |
| - assert(state->fi_freelist_len == 0); |
3703 |
| - state->fi_freelist = NULL; |
3704 |
| -#endif |
3705 |
| -} |
3706 |
| - |
3707 | 3654 | static int
|
3708 | 3655 | module_traverse(PyObject *mod, visitproc visit, void *arg)
|
3709 | 3656 | {
|
@@ -3732,16 +3679,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
|
3732 | 3679 |
|
3733 | 3680 | Py_VISIT(state->context_kwname);
|
3734 | 3681 |
|
3735 |
| -#ifndef Py_GIL_DISABLED |
3736 |
| - // Visit freelist. |
3737 |
| - PyObject *next = (PyObject*) state->fi_freelist; |
3738 |
| - while (next != NULL) { |
3739 |
| - PyObject *current = next; |
3740 |
| - Py_VISIT(current); |
3741 |
| - next = (PyObject*) ((futureiterobject*) current)->future; |
3742 |
| - } |
3743 |
| -#endif |
3744 |
| - |
3745 | 3682 | return 0;
|
3746 | 3683 | }
|
3747 | 3684 |
|
@@ -3773,8 +3710,6 @@ module_clear(PyObject *mod)
|
3773 | 3710 |
|
3774 | 3711 | Py_CLEAR(state->context_kwname);
|
3775 | 3712 |
|
3776 |
| - module_free_freelists(state); |
3777 |
| - |
3778 | 3713 | return 0;
|
3779 | 3714 | }
|
3780 | 3715 |
|
|
0 commit comments