Author: Armin Rigo <ar...@tunes.org>
Branch: nogil-unsafe-2
Changeset: r90422:643158ba7b39
Date: 2017-02-28 15:31 +0100
http://bitbucket.org/pypy/pypy/changeset/643158ba7b39/

Log:    progress

diff --git a/rpython/memory/gctransform/shadowstack.py 
b/rpython/memory/gctransform/shadowstack.py
--- a/rpython/memory/gctransform/shadowstack.py
+++ b/rpython/memory/gctransform/shadowstack.py
@@ -104,7 +104,7 @@
         self.rootstackhook(collect_stack_root,
                            gcdata.root_stack_base, gcdata.root_stack_top)
 
-    def need_thread_support(self, gctransformer, getfn):
+    def need_thread_support_WITH_GIL(self, gctransformer, getfn):
         from rpython.rlib import rthread    # xxx fish
         gcdata = self.gcdata
         # the interfacing between the threads and the GC is done via
@@ -218,6 +218,49 @@
                                            annmodel.s_None,
                                            minimal_transform=False)
 
+    def need_thread_support(self, gctransformer, getfn):  # NO GIL VERSION
+        from rpython.rlib import rthread
+        gcdata = self.gcdata
+        # the interfacing between the threads and the GC is done via
+        # two completely ad-hoc operations at the moment:
+        # gc_thread_run and gc_thread_die.  See docstrings below.
+
+        tl_shadowstack = rthread.ThreadLocalField(llmemory.Address,
+                                                  'shadowstack')
+
+        def thread_setup():
+            allocate_shadow_stack()
+
+        def thread_run():
+            # If it's the first time we see this thread, allocate
+            # a shadowstack.
+            if tl_shadowstack.get_or_make_raw() == llmemory.NULL:
+                allocate_shadow_stack()
+
+        def allocate_shadow_stack():
+            root_stack_depth = 163840
+            root_stack_size = sizeofaddr * root_stack_depth
+            ss = llmemory.raw_malloc(root_stack_size)
+            if not ss:
+                raise MemoryError
+            tl_shadowstack.setraw(ss)
+        allocate_shadow_stack._dont_inline_ = True
+
+        def thread_die():
+            """Called just before the final GIL release done by a dying
+            thread.  After a thread_die(), no more gc operation should
+            occur in this thread.
+            """
+            p = tl_shadowstack.get_or_make_raw()
+            tl_shadowstack.setraw(llmemory.NULL)
+            llmemory.raw_free(p)
+
+        self.thread_setup = thread_setup
+        self.thread_run_ptr = getfn(thread_run, [], annmodel.s_None,
+                                    inline=True, minimal_transform=False)
+        self.thread_die_ptr = getfn(thread_die, [], annmodel.s_None,
+                                    minimal_transform=False)
+
     def need_stacklet_support(self, gctransformer, getfn):
         from rpython.rlib import _stacklet_shadowstack
         _stacklet_shadowstack.complete_destrptr(gctransformer)
diff --git a/rpython/translator/c/src/thread.h 
b/rpython/translator/c/src/thread.h
--- a/rpython/translator/c/src/thread.h
+++ b/rpython/translator/c/src/thread.h
@@ -2,6 +2,7 @@
 #define __PYPY_THREAD_H
 #include "precommondefs.h"
 #include <assert.h>
+#include <stdlib.h>
 
 #define RPY_TIMEOUT_T long long
 
@@ -41,19 +42,20 @@
 # define RPY_FASTGIL_LOCKED(x)   (x != 0)
 #endif
 
-RPY_EXTERN long rpy_fastgil;
+//RPY_EXTERN long rpy_fastgil;
 
 static inline void _RPyGilAcquire(void) {
-    long old_fastgil = pypy_lock_test_and_set(&rpy_fastgil, 1);
-    if (old_fastgil != 0)
-        RPyGilAcquireSlowPath(old_fastgil);
+//    long old_fastgil = pypy_lock_test_and_set(&rpy_fastgil, 1);
+//    if (old_fastgil != 0)
+//        RPyGilAcquireSlowPath(old_fastgil);
 }
 static inline void _RPyGilRelease(void) {
-    assert(RPY_FASTGIL_LOCKED(rpy_fastgil));
-    pypy_lock_release(&rpy_fastgil);
+//    assert(RPY_FASTGIL_LOCKED(rpy_fastgil));
+//    pypy_lock_release(&rpy_fastgil);
 }
 static inline long *_RPyFetchFastGil(void) {
-    return &rpy_fastgil;
+    abort();
+//    return &rpy_fastgil;
 }
 
 #endif
diff --git a/rpython/translator/c/src/thread_gil.c 
b/rpython/translator/c/src/thread_gil.c
--- a/rpython/translator/c/src/thread_gil.c
+++ b/rpython/translator/c/src/thread_gil.c
@@ -58,13 +58,13 @@
 
 void RPyGilAllocate(void)
 {
-    if (rpy_waiting_threads < 0) {
-        assert(rpy_waiting_threads == -42);
-        rpy_init_mutexes();
+//    if (rpy_waiting_threads < 0) {
+//        assert(rpy_waiting_threads == -42);
+//        rpy_init_mutexes();
 #ifdef HAVE_PTHREAD_ATFORK
-        pthread_atfork(NULL, NULL, rpy_init_mutexes);
+//        pthread_atfork(NULL, NULL, rpy_init_mutexes);
 #endif
-    }
+//    }
 }
 
 static void check_and_save_old_fastgil(long old_fastgil)
diff --git a/rpython/translator/c/test/test_standalone.py 
b/rpython/translator/c/test/test_standalone.py
--- a/rpython/translator/c/test/test_standalone.py
+++ b/rpython/translator/c/test/test_standalone.py
@@ -1427,6 +1427,46 @@
                 and result.count('a') == 1
                 and result.count('d') == 6)
 
+    def test_thread_and_gc_nogil(self):
+        import time, gc
+        from rpython.rlib import rthread, rposix
+
+        def bootstrap():
+            rthread.gc_thread_start()
+            os.write(1, "hi there\n")
+            rthread.gc_thread_die()
+
+        def new_thread():
+            ident = rthread.start_new_thread(bootstrap, ())
+            return ident
+
+        def entry_point(argv):
+            os.write(1, "hello world\n")
+            # start 5 new threads
+            ident1 = new_thread()
+            ident2 = new_thread()
+            ident3 = new_thread()
+            ident4 = new_thread()
+            ident5 = new_thread()
+            # wait for the 5 threads to finish
+            time.sleep(1)
+            gc.collect()
+            return 0
+
+        def runme(no__thread):
+            t, cbuilder = self.compile(entry_point, no__thread=no__thread)
+            data = cbuilder.cmdexec('')
+            assert data.splitlines() == ['hello world',
+                                         '1 ok',
+                                         '2 ok',
+                                         '3 ok',
+                                         '4 ok',
+                                         '5 ok']
+
+        if SUPPORT__THREAD:
+            runme(no__thread=False)
+        runme(no__thread=True)
+
 
 class TestShared(StandaloneTests):
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to