[pypy-commit] pypy nogil-unsafe-2: progress
arigo
pypy.commits at gmail.com
Tue Feb 28 09:32:22 EST 2017
Author: Armin Rigo <arigo at 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):
More information about the pypy-commit
mailing list