bpo-46008: Move thread-related interpreter state into a sub-struct. (gh-29971)

This parallels _PyRuntimeState.interpreters.  Doing this helps make it more clear what part of PyInterpreterState relates to its threads.

https://bugs.python.org/issue46008
This commit is contained in:
Eric Snow 2021-12-07 14:03:47 -07:00 committed by GitHub
parent 8262c96bcc
commit 313f92a57b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 40 deletions

View file

@ -784,7 +784,7 @@ Py_SetRecursionLimit(int new_limit)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
interp->ceval.recursion_limit = new_limit;
for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) {
for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
int depth = p->recursion_limit - p->recursion_remaining;
p->recursion_limit = new_limit;
p->recursion_remaining = new_limit - depth;

View file

@ -2043,7 +2043,7 @@ Py_EndInterpreter(PyThreadState *tstate)
_PyAtExit_Call(tstate->interp);
if (tstate != interp->tstate_head || tstate->next != NULL) {
if (tstate != interp->threads.head || tstate->next != NULL) {
Py_FatalError("not the last thread");
}

View file

@ -271,7 +271,7 @@ PyInterpreterState_New(void)
return NULL;
}
interp->tstate_next_unique_id = 0;
interp->threads.next_unique_id = 0;
interp->audit_hooks = NULL;
@ -297,7 +297,7 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
}
HEAD_LOCK(runtime);
for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) {
for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
PyThreadState_Clear(p);
}
HEAD_UNLOCK(runtime);
@ -371,7 +371,7 @@ zapthreads(PyInterpreterState *interp, int check_current)
PyThreadState *tstate;
/* No need to lock the mutex here because this should only happen
when the threads are all really dead (XXX famous last words). */
while ((tstate = interp->tstate_head) != NULL) {
while ((tstate = interp->threads.head) != NULL) {
_PyThreadState_Delete(tstate, check_current);
}
}
@ -399,7 +399,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
break;
}
}
if (interp->tstate_head != NULL) {
if (interp->threads.head != NULL) {
Py_FatalError("remaining threads");
}
*p = interp->next;
@ -702,12 +702,12 @@ new_threadstate(PyInterpreterState *interp, int init)
}
HEAD_LOCK(runtime);
tstate->id = ++interp->tstate_next_unique_id;
tstate->id = ++interp->threads.next_unique_id;
tstate->prev = NULL;
tstate->next = interp->tstate_head;
tstate->next = interp->threads.head;
if (tstate->next)
tstate->next->prev = tstate;
interp->tstate_head = tstate;
interp->threads.head = tstate;
HEAD_UNLOCK(runtime);
return tstate;
@ -930,7 +930,7 @@ tstate_delete_common(PyThreadState *tstate,
tstate->prev->next = tstate->next;
}
else {
interp->tstate_head = tstate->next;
interp->threads.head = tstate->next;
}
if (tstate->next) {
tstate->next->prev = tstate->prev;
@ -1008,7 +1008,7 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
/* Remove all thread states, except tstate, from the linked list of
thread states. This will allow calling PyThreadState_Clear()
without holding the lock. */
PyThreadState *list = interp->tstate_head;
PyThreadState *list = interp->threads.head;
if (list == tstate) {
list = tstate->next;
}
@ -1019,7 +1019,7 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
tstate->next->prev = tstate->prev;
}
tstate->prev = tstate->next = NULL;
interp->tstate_head = tstate;
interp->threads.head = tstate;
HEAD_UNLOCK(runtime);
/* Clear and deallocate all stale thread states. Even if this
@ -1180,7 +1180,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
* head_mutex for the duration.
*/
HEAD_LOCK(runtime);
for (PyThreadState *tstate = interp->tstate_head; tstate != NULL; tstate = tstate->next) {
for (PyThreadState *tstate = interp->threads.head; tstate != NULL; tstate = tstate->next) {
if (tstate->thread_id != id) {
continue;
}
@ -1244,7 +1244,7 @@ PyInterpreterState_Next(PyInterpreterState *interp) {
PyThreadState *
PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
return interp->tstate_head;
return interp->threads.head;
}
PyThreadState *
@ -1281,7 +1281,7 @@ _PyThread_CurrentFrames(void)
PyInterpreterState *i;
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
PyThreadState *t;
for (t = i->tstate_head; t != NULL; t = t->next) {
for (t = i->threads.head; t != NULL; t = t->next) {
InterpreterFrame *frame = t->cframe->current_frame;
if (frame == NULL) {
continue;
@ -1334,7 +1334,7 @@ _PyThread_CurrentExceptions(void)
PyInterpreterState *i;
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
PyThreadState *t;
for (t = i->tstate_head; t != NULL; t = t->next) {
for (t = i->threads.head; t != NULL; t = t->next) {
_PyErr_StackItem *err_info = _PyErr_GetTopmostException(t);
if (err_info == NULL) {
continue;

View file

@ -109,7 +109,7 @@ _PyThread_debug_deprecation(void)
size_t
PyThread_get_stacksize(void)
{
return _PyInterpreterState_GET()->pythread_stacksize;
return _PyInterpreterState_GET()->threads.stacksize;
}
/* Only platforms defining a THREAD_SET_STACKSIZE() macro

View file

@ -1,4 +1,4 @@
#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize
/* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */
/* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch@iso.ru */
@ -199,7 +199,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
obj->func = func;
obj->arg = arg;
PyThreadState *tstate = _PyThreadState_GET();
size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
size_t stacksize = tstate ? tstate->interp->threads.stacksize : 0;
hThread = (HANDLE)_beginthreadex(0,
Py_SAFE_DOWNCAST(stacksize, Py_ssize_t, unsigned int),
bootstrap, obj,
@ -376,13 +376,13 @@ _pythread_nt_set_stacksize(size_t size)
{
/* set to default */
if (size == 0) {
_PyInterpreterState_GET()->pythread_stacksize = 0;
_PyInterpreterState_GET()->threads.stacksize = 0;
return 0;
}
/* valid range? */
if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
_PyInterpreterState_GET()->pythread_stacksize = size;
_PyInterpreterState_GET()->threads.stacksize = size;
return 0;
}

View file

@ -1,4 +1,4 @@
#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize
/* Posix threads interface */
@ -262,7 +262,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
#endif
#if defined(THREAD_STACK_SIZE)
PyThreadState *tstate = _PyThreadState_GET();
size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
size_t stacksize = tstate ? tstate->interp->threads.stacksize : 0;
tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
if (tss != 0) {
if (pthread_attr_setstacksize(&attrs, tss) != 0) {
@ -764,7 +764,7 @@ _pythread_pthread_set_stacksize(size_t size)
/* set to default */
if (size == 0) {
_PyInterpreterState_GET()->pythread_stacksize = 0;
_PyInterpreterState_GET()->threads.stacksize = 0;
return 0;
}
@ -781,7 +781,7 @@ _pythread_pthread_set_stacksize(size_t size)
rc = pthread_attr_setstacksize(&attrs, size);
pthread_attr_destroy(&attrs);
if (rc == 0) {
_PyInterpreterState_GET()->pythread_stacksize = size;
_PyInterpreterState_GET()->threads.stacksize = size;
return 0;
}
}