Author: Armin Rigo <ar...@tunes.org>
Branch: stm-thread-2
Changeset: r61409:3576f38d6a82
Date: 2013-02-18 14:21 +0100
http://bitbucket.org/pypy/pypy/changeset/3576f38d6a82/

Log:    Use ThreadLocalReference to get the excutioncontext more
        efficiently.

diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py
--- a/pypy/module/thread/stm.py
+++ b/pypy/module/thread/stm.py
@@ -4,13 +4,16 @@
 
 from pypy.module.thread.threadlocals import OSThreadLocals
 from pypy.module.thread.error import wrap_thread_error
+from pypy.interpreter.executioncontext import ExecutionContext
 from rpython.rlib import rthread
 from rpython.rlib import rstm
 from rpython.rlib.objectmodel import invoke_around_extcall
 
 
+ec_cache = rstm.ThreadLocalReference(ExecutionContext)
+
+
 class STMThreadLocals(OSThreadLocals):
-    can_cache = False
 
     def initialize(self, space):
         """NOT_RPYTHON: set up a mechanism to send to the C code the value
@@ -27,6 +30,17 @@
         space.actionflag.setcheckinterval_callback = setcheckinterval_callback
         self.threads_running = False
 
+    def clear_cache(self):
+        ec_cache.set(None)
+
+    def getvalue(self):
+        value = ec_cache.get()
+        if value is None:
+            ident = rthread.get_ident()
+            value = self._valuedict.get(ident, None)
+            ec_cache.set(value)
+        return value
+
     def setup_threads(self, space):
         self.threads_running = True
         self.configure_transaction_length(space)
diff --git a/pypy/module/thread/threadlocals.py 
b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -12,8 +12,6 @@
     a thread finishes.  This works as long as the thread was started by
     os_thread.bootstrap()."""
 
-    can_cache = True
-
     def __init__(self):
         self._valuedict = {}   # {thread_ident: ExecutionContext()}
         self._cleanup_()
@@ -21,20 +19,24 @@
     def _cleanup_(self):
         self._valuedict.clear()
         self._mainthreadident = 0
-        if self.can_cache:
-            self._mostrecentkey = 0        # fast minicaching for the common 
case
-            self._mostrecentvalue = None   # fast minicaching for the common 
case
+        self.clear_cache()
+
+    def clear_cache(self):
+        # Cache function: fast minicaching for the common case.  Relies
+        # on the GIL; overridden in stm.py.
+        self._mostrecentkey = 0
+        self._mostrecentvalue = None
 
     def getvalue(self):
+        # Overridden in stm.py.
         ident = rthread.get_ident()
-        if self.can_cache and ident == self._mostrecentkey:
+        if ident == self._mostrecentkey:
             result = self._mostrecentvalue
         else:
             value = self._valuedict.get(ident, None)
-            if self.can_cache:
-                # slow path: update the minicache
-                self._mostrecentkey = ident
-                self._mostrecentvalue = value
+            # slow path: update the minicache
+            self._mostrecentkey = ident
+            self._mostrecentvalue = value
             result = value
         return result
 
@@ -50,10 +52,8 @@
                 del self._valuedict[ident]
             except KeyError:
                 pass
-        if self.can_cache:
-            # update the minicache to prevent it from containing an outdated 
value
-            self._mostrecentkey = ident
-            self._mostrecentvalue = value
+        # clear the minicache to prevent it from containing an outdated value
+        self.clear_cache()
 
     def signals_enabled(self):
         ec = self.getvalue()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to