[pypy-commit] pypy stm-gc: The part of the code in the main thread that starts new threads

arigo noreply at buildbot.pypy.org
Sun Feb 19 20:11:07 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52649:cb64c1fa7f40
Date: 2012-02-19 19:12 +0100
http://bitbucket.org/pypy/pypy/changeset/cb64c1fa7f40/

Log:	The part of the code in the main thread that starts new threads must
	not use the GC itself.

diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -45,6 +45,10 @@
                             threadsafe=True)  # release the GIL, but most
                                               # importantly, reacquire it
                                               # around the callback
+c_thread_start_NOGIL = llexternal('RPyThreadStart', [CALLBACK], rffi.LONG,
+                                  _callable=_emulated_start_new_thread,
+                                  _nowrapper=True,  # just call directly
+                                  random_effects_on_gcobjs=False)
 c_thread_get_ident = llexternal('RPyThreadGetIdent', [], rffi.LONG,
                                 _nowrapper=True)    # always call directly
 
diff --git a/pypy/translator/stm/test/targetdemo.py b/pypy/translator/stm/test/targetdemo.py
--- a/pypy/translator/stm/test/targetdemo.py
+++ b/pypy/translator/stm/test/targetdemo.py
@@ -1,7 +1,8 @@
-import time
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.module.thread import ll_thread
-from pypy.rlib import rstm
+from pypy.rlib import rstm, rgc
 from pypy.rlib.debug import debug_print
+from pypy.rpython.annlowlevel import llhelper
 
 
 class Node:
@@ -81,6 +82,27 @@
         rstm.descriptor_done()
 
 
+ at rgc.no_collect     # don't use the gc as long as other threads are running
+def _run():
+    i = 0
+    while i < glob.NUM_THREADS:
+        glob._arg = glob._arglist[i]
+        ll_run_me = llhelper(ll_thread.CALLBACK, run_me)
+        ll_thread.c_thread_start_NOGIL(ll_run_me)
+        ll_thread.acquire_NOAUTO(glob.lock, True)
+        i += 1
+    debug_print("sleeping...")
+    while glob.done < glob.NUM_THREADS:    # poor man's lock
+        _sleep(rffi.cast(rffi.ULONG, 1))
+    debug_print("done sleeping.")
+
+
+# Posix only
+_sleep = rffi.llexternal('sleep', [rffi.ULONG], rffi.ULONG,
+                         _nowrapper=True,
+                         random_effects_on_gcobjs=False)
+
+
 # __________  Entry point  __________
 
 def entry_point(argv):
@@ -94,14 +116,8 @@
     glob.done = 0
     glob.lock = ll_thread.allocate_ll_lock()
     ll_thread.acquire_NOAUTO(glob.lock, True)
-    for i in range(glob.NUM_THREADS):
-        glob._arg = Arg()
-        ll_thread.start_new_thread(run_me, ())
-        ll_thread.acquire_NOAUTO(glob.lock, True)
-    print "sleeping..."
-    while glob.done < glob.NUM_THREADS:    # poor man's lock
-        time.sleep(1)
-    print "done sleeping."
+    glob._arglist = [Arg() for i in range(glob.NUM_THREADS)]
+    _run()
     check_chained_list(glob.anchor.next)
     return 0
 
diff --git a/pypy/translator/stm/test/test_ztranslated.py b/pypy/translator/stm/test/test_ztranslated.py
--- a/pypy/translator/stm/test/test_ztranslated.py
+++ b/pypy/translator/stm/test/test_ztranslated.py
@@ -7,6 +7,6 @@
 
     def test_hello_world(self):
         t, cbuilder = self.compile(targetdemo.entry_point)
-        data = cbuilder.cmdexec('4 5000')
-        assert 'done sleeping.' in data
+        data, dataerr = cbuilder.cmdexec('4 5000', err=True)
+        assert 'done sleeping.' in dataerr
         assert 'check ok!' in data


More information about the pypy-commit mailing list