[Python-checkins] cpython: Issue #17912: Use a doubly linked-list for thread states.

charles-francois.natali python-checkins at python.org
Wed May 8 21:10:31 CEST 2013


http://hg.python.org/cpython/rev/375d4fed4cf2
changeset:   83690:375d4fed4cf2
parent:      83688:c89febab4648
user:        Charles-Francois Natali <cf.natali at gmail.com>
date:        Wed May 08 21:09:52 2013 +0200
summary:
  Issue #17912: Use a doubly linked-list for thread states.

files:
  Include/pystate.h |   1 +
  Python/pystate.c  |  58 ++++++++++------------------------
  2 files changed, 18 insertions(+), 41 deletions(-)


diff --git a/Include/pystate.h b/Include/pystate.h
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -69,6 +69,7 @@
 typedef struct _ts {
     /* See Python/ceval.c for comments explaining most fields */
 
+    struct _ts *prev;
     struct _ts *next;
     PyInterpreterState *interp;
 
diff --git a/Python/pystate.c b/Python/pystate.c
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -213,7 +213,10 @@
             _PyThreadState_Init(tstate);
 
         HEAD_LOCK();
+        tstate->prev = NULL;
         tstate->next = interp->tstate_head;
+        if (tstate->next)
+            tstate->next->prev = tstate;
         interp->tstate_head = tstate;
         HEAD_UNLOCK();
     }
@@ -349,35 +352,18 @@
 tstate_delete_common(PyThreadState *tstate)
 {
     PyInterpreterState *interp;
-    PyThreadState **p;
-    PyThreadState *prev_p = NULL;
     if (tstate == NULL)
         Py_FatalError("PyThreadState_Delete: NULL tstate");
     interp = tstate->interp;
     if (interp == NULL)
         Py_FatalError("PyThreadState_Delete: NULL interp");
     HEAD_LOCK();
-    for (p = &interp->tstate_head; ; p = &(*p)->next) {
-        if (*p == NULL)
-            Py_FatalError(
-                "PyThreadState_Delete: invalid tstate");
-        if (*p == tstate)
-            break;
-        /* 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;
+    if (tstate->prev)
+        tstate->prev->next = tstate->next;
+    else
+        interp->tstate_head = tstate->next;
+    if (tstate->next)
+        tstate->next->prev = tstate->prev;
     HEAD_UNLOCK();
     free(tstate);
 }
@@ -429,26 +415,16 @@
     HEAD_LOCK();
     /* Remove all thread states, except tstate, from the linked list of
        thread states.  This will allow calling PyThreadState_Clear()
-       without holding the lock.
-       XXX This would be simpler with a doubly-linked list. */
+       without holding the lock. */
     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;
-    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();
     /* Clear and deallocate all stale thread states.  Even if this
        executes Python code, we should be safe since it executes

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list