[pypy-svn] r55295 - pypy/dist/pypy/module/thread/test

arigo at codespeak.net arigo at codespeak.net
Tue May 27 13:42:33 CEST 2008


Author: arigo
Date: Tue May 27 13:42:31 2008
New Revision: 55295

Modified:
   pypy/dist/pypy/module/thread/test/test_ll_thread.py
Log:
Added some tests until I found one that explodes because of bogus
interactions between threads and the framework gc.  Skipped for now.


Modified: pypy/dist/pypy/module/thread/test/test_ll_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/test/test_ll_thread.py	(original)
+++ pypy/dist/pypy/module/thread/test/test_ll_thread.py	Tue May 27 13:42:31 2008
@@ -1,6 +1,6 @@
 
 from pypy.module.thread.ll_thread import *
-from pypy.translator.c.test.test_genc import compile
+from pypy.translator.c.test.test_boehm import AbstractGCTestClass
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.objectmodel import free_non_gc_object
@@ -34,59 +34,135 @@
     could_acquire_again = l.acquire(False)
     assert could_acquire_again
 
-def test_start_new_thread():
-    import time
-    
 
-    class State:
-        pass
-    state = State()
-    
-    class Z:
-        def __init__(self, value):
-            self.value = value
-        def __del__(self):
-            state.freed_counter += 1
-            
-    class Y:
-        _alloc_flavor_ = 'raw'
-
-        def bootstrap(self):
-            state.my_thread_ident = get_ident()
-            assert state.my_thread_ident == get_ident()
-            state.seen_value = self.z.value
-            self.z = None
-            free_non_gc_object(self)
-            state.done = 1
-
-    def g(i):
-        y = Y()
-        y.z = Z(i)
-        start_new_thread(Y.bootstrap, (y,))
-    g._dont_inline_ = True
-
-    def f():
-        main_ident = get_ident()
-        assert main_ident == get_ident()
-        state.freed_counter = 0
-        for i in range(50):
-            state.done = 0
-            state.seen_value = 0
-            g(i)
+class TestUsingBoehm(AbstractGCTestClass):
+    gcpolicy = 'boehm'
+
+    def test_start_new_thread(self):
+        import time
+
+        class State:
+            pass
+        state = State()
+
+        class Z:
+            def __init__(self, value):
+                self.value = value
+            def __del__(self):
+                state.freed_counter += 1
+
+        class Y:
+            _alloc_flavor_ = 'raw'
+
+            def bootstrap(self):
+                state.my_thread_ident = get_ident()
+                assert state.my_thread_ident == get_ident()
+                state.seen_value = self.z.value
+                self.z = None
+                free_non_gc_object(self)
+                state.done = 1
+
+        def g(i):
+            y = Y()
+            y.z = Z(i)
+            start_new_thread(Y.bootstrap, (y,))
+        g._dont_inline_ = True
+
+        def f():
+            main_ident = get_ident()
+            assert main_ident == get_ident()
+            state.freed_counter = 0
+            for i in range(50):
+                state.done = 0
+                state.seen_value = 0
+                g(i)
+                willing_to_wait_more = 1000
+                while not state.done:
+                    willing_to_wait_more -= 1
+                    if not willing_to_wait_more:
+                        raise Exception("thread didn't start?")
+                    time.sleep(0.01)
+                assert state.my_thread_ident != main_ident
+                assert state.seen_value == i
+            # try to force Boehm to do some freeing
+            for i in range(3):
+                llop.gc__collect(lltype.Void)
+            return state.freed_counter
+
+        fn = self.getcompiled(f, [])
+        freed_counter = fn()
+        print freed_counter
+        if self.gcpolicy == 'boehm':
+            assert freed_counter > 0
+        else:
+            assert freed_counter == 50
+
+    def test_gc_locking(self):
+        import time
+
+        class State:
+            pass
+        state = State()
+
+        class Z:
+            def __init__(self, i, j):
+                self.i = i
+                self.j = j
+            def run(self):
+                j = self.j
+                state.gil.acquire(True)
+                assert j == self.j
+                if self.i > 1:
+                    g(self.i-1, self.j * 2)
+                    g(self.i-2, self.j * 2 + 1)
+                else:
+                    state.answers.append(self.i)
+                assert j == self.j
+                state.gil.release()
+                assert j == self.j
+            run._dont_inline_ = True
+
+        class Y(object):
+            _alloc_flavor_ = 'raw'
+            def bootstrap(self):
+                self.z.run()
+                self.z = None
+                free_non_gc_object(self)
+                state.done = 1
+
+        def g(i, j):
+            y = Y()
+            y.z = Z(i, j)
+            start_new_thread(Y.bootstrap, (y,))
+        g._dont_inline_ = True
+
+        def f():
+            state.gil = allocate_lock_NOAUTO()
+            state.answers = []
+            state.finished = 0
+            g(7, 1)
+            done = False
             willing_to_wait_more = 1000
-            while not state.done:
-                willing_to_wait_more -= 1
+            while not done:
                 if not willing_to_wait_more:
-                    raise Exception("thread didn't start?")
+                    raise Exception("didn't get enough answers: got %d,"
+                                    " expected %d" % (len(state.answers),
+                                                      expected))
+                willing_to_wait_more -= 1
+                state.gil.acquire(True)
+                done = len(state.answers) == expected
+                state.gil.release()
                 time.sleep(0.01)
-            assert state.my_thread_ident != main_ident
-            assert state.seen_value == i
-        # try to force Boehm to do some freeing
-        for i in range(3):
-            llop.gc__collect(lltype.Void)
-        return state.freed_counter
-
-    fn = compile(f, [], gcpolicy='boehm')
-    freed_counter = fn()
-    print freed_counter
-    assert freed_counter > 0
+            time.sleep(0.1)
+            return len(state.answers)
+
+        expected = 21
+        fn = self.getcompiled(f, [])
+        answers = fn()
+        assert answers == expected
+
+class TestUsingFramework(TestUsingBoehm):
+    gcpolicy = 'generation'
+
+    def test_gc_locking(self):
+        py.test.skip("in-progress")



More information about the Pypy-commit mailing list