Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Include/internal/pycore_pyatomic_ft_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern "C" {
#endif

#ifdef Py_GIL_DISABLED
#define FT_ATOMIC_ADD_UINT64(value, new_value) _Py_atomic_add_uint64(&value, new_value)
#define FT_ATOMIC_LOAD_PTR(value) _Py_atomic_load_ptr(&value)
#define FT_ATOMIC_STORE_PTR(value, new_value) _Py_atomic_store_ptr(&value, new_value)
#define FT_ATOMIC_LOAD_SSIZE(value) _Py_atomic_load_ssize(&value)
Expand Down Expand Up @@ -63,6 +64,7 @@ extern "C" {
_Py_atomic_store_uint32_relaxed(&value, new_value)

#else
#define FT_ATOMIC_ADD_UINT64(value, new_value) value += new_value
#define FT_ATOMIC_LOAD_PTR(value) value
#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
#define FT_ATOMIC_LOAD_SSIZE(value) value
Expand Down
26 changes: 24 additions & 2 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,21 @@ typedef struct {

#define FI_FREELIST_MAXLEN 255

#ifdef Py_GIL_DISABLED
# define ASYNCIO_STATE_LOCK(state) PyMutex_Lock(&state->mutex)
# define ASYNCIO_STATE_UNLOCK(state) PyMutex_Unlock(&state->mutex)
#else
# define ASYNCIO_STATE_LOCK(state) ((void)state)
# define ASYNCIO_STATE_UNLOCK(state) ((void)state)
#endif

typedef struct futureiterobject futureiterobject;

/* State of the _asyncio module */
typedef struct {
#ifdef Py_GIL_DISABLED
PyMutex mutex;
#endif
PyTypeObject *FutureIterType;
PyTypeObject *TaskStepMethWrapper_Type;
PyTypeObject *FutureType;
Expand Down Expand Up @@ -341,6 +352,8 @@ get_running_loop(asyncio_state *state, PyObject **loop)
}
}

// TODO GH-121621: The should be moved to PyThreadState
// for easier and quicker access.
state->cached_running_loop = rl;
state->cached_running_loop_tsid = ts_id;
}
Expand Down Expand Up @@ -384,9 +397,11 @@ set_running_loop(asyncio_state *state, PyObject *loop)
return -1;
}


// TODO GH-121621: The should be moved to PyThreadState
// for easier and quicker access.
state->cached_running_loop = loop; // borrowed, kept alive by ts_dict
state->cached_running_loop_tsid = PyThreadState_GetID(tstate);

return 0;
}

Expand Down Expand Up @@ -1667,6 +1682,7 @@ FutureIter_dealloc(futureiterobject *it)
state = get_asyncio_state(module);
}

// TODO GH-121621: This should be moved to thread state as well.
if (state && state->fi_freelist_len < FI_FREELIST_MAXLEN) {
state->fi_freelist_len++;
it->future = (FutureObj*) state->fi_freelist;
Expand Down Expand Up @@ -2018,6 +2034,7 @@ static PyMethodDef TaskWakeupDef = {
static void
register_task(asyncio_state *state, TaskObj *task)
{
ASYNCIO_STATE_LOCK(state);
assert(Task_Check(state, task));
assert(task != &state->asyncio_tasks.tail);
if (task->next != NULL) {
Expand All @@ -2030,6 +2047,7 @@ register_task(asyncio_state *state, TaskObj *task)
task->next = state->asyncio_tasks.head;
state->asyncio_tasks.head->prev = task;
state->asyncio_tasks.head = task;
ASYNCIO_STATE_UNLOCK(state);
}

static int
Expand All @@ -2049,13 +2067,15 @@ unregister_task(asyncio_state *state, TaskObj *task)
assert(state->asyncio_tasks.head != task);
return;
}
ASYNCIO_STATE_LOCK(state);
task->next->prev = task->prev;
if (task->prev == NULL) {
assert(state->asyncio_tasks.head == task);
state->asyncio_tasks.head = task->next;
} else {
task->prev->next = task->next;
}
ASYNCIO_STATE_UNLOCK(state);
task->next = NULL;
task->prev = NULL;
assert(state->asyncio_tasks.head != task);
Expand Down Expand Up @@ -2213,7 +2233,8 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
// optimization: defer task name formatting
// store the task counter as PyLong in the name
// for deferred formatting in get_name
name = PyLong_FromUnsignedLongLong(++state->task_name_counter);
FT_ATOMIC_ADD_UINT64(state->task_name_counter, 1);
name = PyLong_FromUnsignedLongLong(state->task_name_counter);
} else if (!PyUnicode_CheckExact(name)) {
name = PyObject_Str(name);
} else {
Expand Down Expand Up @@ -3947,6 +3968,7 @@ static int
module_exec(PyObject *mod)
{
asyncio_state *state = get_asyncio_state(mod);

Py_SET_TYPE(&state->asyncio_tasks.tail, state->TaskType);
_Py_SetImmortalUntracked((PyObject *)&state->asyncio_tasks.tail);
state->asyncio_tasks.head = &state->asyncio_tasks.tail;
Expand Down