Kaydet (Commit) f28dfdd0 authored tarafından Charles-Francois Natali's avatar Charles-Francois Natali

Issue #17912: Use a doubly linked-list for thread states.

üst 04e70d19
...@@ -69,6 +69,7 @@ typedef struct _ts PyThreadState; ...@@ -69,6 +69,7 @@ typedef struct _ts PyThreadState;
typedef struct _ts { typedef struct _ts {
/* See Python/ceval.c for comments explaining most fields */ /* See Python/ceval.c for comments explaining most fields */
struct _ts *prev;
struct _ts *next; struct _ts *next;
PyInterpreterState *interp; PyInterpreterState *interp;
......
...@@ -213,7 +213,10 @@ new_threadstate(PyInterpreterState *interp, int init) ...@@ -213,7 +213,10 @@ new_threadstate(PyInterpreterState *interp, int init)
_PyThreadState_Init(tstate); _PyThreadState_Init(tstate);
HEAD_LOCK(); HEAD_LOCK();
tstate->prev = NULL;
tstate->next = interp->tstate_head; tstate->next = interp->tstate_head;
if (tstate->next)
tstate->next->prev = tstate;
interp->tstate_head = tstate; interp->tstate_head = tstate;
HEAD_UNLOCK(); HEAD_UNLOCK();
} }
...@@ -349,35 +352,18 @@ static void ...@@ -349,35 +352,18 @@ static void
tstate_delete_common(PyThreadState *tstate) tstate_delete_common(PyThreadState *tstate)
{ {
PyInterpreterState *interp; PyInterpreterState *interp;
PyThreadState **p;
PyThreadState *prev_p = NULL;
if (tstate == NULL) if (tstate == NULL)
Py_FatalError("PyThreadState_Delete: NULL tstate"); Py_FatalError("PyThreadState_Delete: NULL tstate");
interp = tstate->interp; interp = tstate->interp;
if (interp == NULL) if (interp == NULL)
Py_FatalError("PyThreadState_Delete: NULL interp"); Py_FatalError("PyThreadState_Delete: NULL interp");
HEAD_LOCK(); HEAD_LOCK();
for (p = &interp->tstate_head; ; p = &(*p)->next) { if (tstate->prev)
if (*p == NULL) tstate->prev->next = tstate->next;
Py_FatalError( else
"PyThreadState_Delete: invalid tstate"); interp->tstate_head = tstate->next;
if (*p == tstate) if (tstate->next)
break; tstate->next->prev = tstate->prev;
/* Sanity check. These states should never happen but if
* they do we must abort. Otherwise we'll end up spinning in
* in a tight loop with the lock held. A similar check is done
* in thread.c find_key(). */
if (*p == prev_p)
Py_FatalError(
"PyThreadState_Delete: small circular list(!)"
" and tstate not found.");
prev_p = *p;
if ((*p)->next == interp->tstate_head)
Py_FatalError(
"PyThreadState_Delete: circular list(!) and"
" tstate not found.");
}
*p = tstate->next;
HEAD_UNLOCK(); HEAD_UNLOCK();
free(tstate); free(tstate);
} }
...@@ -429,26 +415,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) ...@@ -429,26 +415,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
HEAD_LOCK(); HEAD_LOCK();
/* Remove all thread states, except tstate, from the linked list of /* Remove all thread states, except tstate, from the linked list of
thread states. This will allow calling PyThreadState_Clear() thread states. This will allow calling PyThreadState_Clear()
without holding the lock. without holding the lock. */
XXX This would be simpler with a doubly-linked list. */
garbage = interp->tstate_head; garbage = interp->tstate_head;
if (garbage == tstate)
garbage = tstate->next;
if (tstate->prev)
tstate->prev->next = tstate->next;
if (tstate->next)
tstate->next->prev = tstate->prev;
tstate->prev = tstate->next = NULL;
interp->tstate_head = tstate; interp->tstate_head = tstate;
if (garbage == tstate) {
garbage = garbage->next;
tstate->next = NULL;
}
else {
for (p = garbage; p; p = p->next) {
if (p->next == tstate) {
p->next = tstate->next;
tstate->next = NULL;
break;
}
}
}
if (tstate->next != NULL)
Py_FatalError("_PyThreadState_DeleteExcept: tstate not found "
"in interpreter thread states");
HEAD_UNLOCK(); HEAD_UNLOCK();
/* Clear and deallocate all stale thread states. Even if this /* Clear and deallocate all stale thread states. Even if this
executes Python code, we should be safe since it executes executes Python code, we should be safe since it executes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment