[pypy-commit] pypy stm-jit: introduce thread.exclusive_atomic

RonnyPfannschmidt noreply at buildbot.pypy.org
Fri Aug 17 19:17:46 CEST 2012


Author: Ronny Pfannschmidt <Ronny.Pfannschmidt at gmx.de>
Branch: stm-jit
Changeset: r56738:a255c9eadffd
Date: 2012-08-17 19:14 +0200
http://bitbucket.org/pypy/pypy/changeset/a255c9eadffd/

Log:	introduce thread.exclusive_atomic

	it will throw an error if it is used within another atomic block

diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py
--- a/pypy/module/thread/__init__.py
+++ b/pypy/module/thread/__init__.py
@@ -5,6 +5,7 @@
 class Module(MixedModule):
     appleveldefs = {
         'atomic':                 'app_atomic.atomic',
+        'exclusive_atomic':       'app_atomic.exclusive_atomic',
     }
 
     interpleveldefs = {
@@ -22,6 +23,7 @@
         '_local':                 'os_local.Local',
         'error':                  'space.fromcache(error.Cache).w_error',
         '_atomic_enter':          'atomic.atomic_enter',
+        '_exclusive_atomic_enter': 'atomic.exclusive_atomic_enter',
         '_atomic_exit':           'atomic.atomic_exit',
     }
 
diff --git a/pypy/module/thread/app_atomic.py b/pypy/module/thread/app_atomic.py
--- a/pypy/module/thread/app_atomic.py
+++ b/pypy/module/thread/app_atomic.py
@@ -4,4 +4,9 @@
     __enter__ = thread._atomic_enter
     __exit__  = thread._atomic_exit
 
+class ExclusiveAtomic(object):
+    __enter__ = thread._exclusive_atomic_enter
+    __exit__ = thread._atomic_exit
+
 atomic = Atomic()
+exclusive_atomic = ExclusiveAtomic()
diff --git a/pypy/module/thread/atomic.py b/pypy/module/thread/atomic.py
--- a/pypy/module/thread/atomic.py
+++ b/pypy/module/thread/atomic.py
@@ -1,6 +1,21 @@
 from pypy.interpreter.error import OperationError
 from pypy.module.thread.error import wrap_thread_error
 
+
+
+def exclusive_atomic_enter(space):
+    if space.config.translation.stm:
+        from pypy.rlib.rstm import is_atomic
+        count = is_atomic()
+    else:
+        giltl = space.threadlocals
+        count = giltl.is_atomic
+    if count:
+        raise wrap_thread_error(space,
+            "exclusive_atomic block can't be entered inside another atomic block")
+
+    atomic_enter(space)
+
 def atomic_enter(space):
     if space.config.translation.stm:
         from pypy.rlib.rstm import increment_atomic
diff --git a/pypy/module/thread/test/test_atomic.py b/pypy/module/thread/test/test_atomic.py
--- a/pypy/module/thread/test/test_atomic.py
+++ b/pypy/module/thread/test/test_atomic.py
@@ -6,10 +6,42 @@
 
     def test_simple(self):
         import thread
+        for atomic in thread.atomic, thread.exclusive_atomic:
+            with atomic:
+                pass
+            try:
+                with atomic:
+                    raise ValueError
+            except ValueError:
+                pass
+
+    def test_nest_composable_atomic(self):
+        import thread
         with thread.atomic:
-            pass
+            with thread.atomic:
+                pass
+
+    def test_nest_composable_below_exclusive(self):
+        import thread
+        with thread.exclusive_atomic:
+            with thread.atomic:
+                with thread.atomic:
+                    pass
+
+    def test_nest_exclusive_fails(self):
+        import thread
+        try:
+            with thread.exclusive_atomic:
+                with thread.exclusive_atomic:
+                    pass
+        except thread.error, e:
+            assert e.message == "exclusive_atomic block can't be entered inside another atomic block"
+
+    def test_nest_exclusive_fails2(self):
+        import thread
         try:
             with thread.atomic:
-                raise ValueError
-        except ValueError:
-            pass
+                with thread.exclusive_atomic:
+                    pass
+        except thread.error, e:
+            assert e.message == "exclusive_atomic block can't be entered inside another atomic block"


More information about the pypy-commit mailing list