[pypy-commit] pypy stm-gc: In-progress. Starting work on the GC/src_stm interface.

arigo noreply at buildbot.pypy.org
Sat Feb 4 18:08:10 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52095:ca1bda35d3ab
Date: 2012-02-04 18:07 +0100
http://bitbucket.org/pypy/pypy/changeset/ca1bda35d3ab/

Log:	In-progress. Starting work on the GC/src_stm interface.

diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -58,7 +58,8 @@
     # gc
     ChoiceOption("gc", "Garbage Collection Strategy",
                  ["boehm", "ref", "marksweep", "semispace", "statistics",
-                  "generation", "hybrid", "markcompact", "minimark", "none"],
+                  "generation", "hybrid", "markcompact", "minimark", "none",
+                  "stmgc"],
                   "ref", requires={
                      "ref": [("translation.rweakref", False), # XXX
                              ("translation.gctransformer", "ref")],
@@ -73,6 +74,8 @@
                                ("translation.gctransformer", "boehm")],
                      "markcompact": [("translation.gctransformer", "framework")],
                      "minimark": [("translation.gctransformer", "framework")],
+                     "stmgc": [("translation.gctransformer", "framework"),
+                               ("translation.gcrootfinder", "none")],   # XXX
                      },
                   cmdline="--gc"),
     ChoiceOption("gctransformer", "GC transformer that is used - internal",
@@ -90,7 +93,7 @@
                default=IS_64_BITS, cmdline="--gcremovetypeptr"),
     ChoiceOption("gcrootfinder",
                  "Strategy for finding GC Roots (framework GCs only)",
-                 ["n/a", "shadowstack", "asmgcc"],
+                 ["n/a", "shadowstack", "asmgcc", "none"],
                  "shadowstack",
                  cmdline="--gcrootfinder",
                  requires={
@@ -103,7 +106,8 @@
     BoolOption("thread", "enable use of threading primitives",
                default=False, cmdline="--thread"),
     BoolOption("stm", "enable use of Software Transactional Memory",
-               default=False, cmdline="--stm"),
+               default=False, cmdline="--stm",
+               requires=[("translation.gc", "stmgc")]),
     BoolOption("sandbox", "Produce a fully-sandboxed executable",
                default=False, cmdline="--sandbox",
                requires=[("translation.thread", False)],
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -440,6 +440,7 @@
                "hybrid": "hybrid.HybridGC",
                "markcompact" : "markcompact.MarkCompactGC",
                "minimark" : "minimark.MiniMarkGC",
+               "stmgc": "stmgc.StmGC",
                }
     try:
         modulename, classname = classes[config.translation.gc].split('.')
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -24,11 +24,6 @@
     return fn
 
 
-class StmOperations(object):
-    def _freeze_(self):
-        return True
-
-
 class StmGC(GCBase):
     _alloc_flavor_ = "raw"
     inline_simple_malloc = True
@@ -50,10 +45,23 @@
                                    ('pending_list', llmemory.Address),
                           )
 
-    def __init__(self, config, stm_operations,
+    TRANSLATION_PARAMS = {
+        'stm_operations': 'use_real_one',
+        'max_nursery_size': 400*1024*1024,      # XXX 400MB
+    }
+
+    def __init__(self, config, stm_operations='use_emulator',
                  max_nursery_size=1024,
                  **kwds):
         GCBase.__init__(self, config, **kwds)
+        #
+        if isinstance(stm_operations, str):
+            assert stm_operations == 'use_real_one', (
+                "XXX not provided so far: stm_operations == %r" % (
+                stm_operations,))
+            from pypy.translator.stm.stmgcintf import StmOperations
+            stm_operations = StmOperations()
+        #
         self.stm_operations = stm_operations
         self.collector = Collector(self)
         self.max_nursery_size = max_nursery_size
@@ -80,7 +88,7 @@
         """Setup a thread.  Allocates the thread-local data structures.
         Must be called only once per OS-level thread."""
         tls = lltype.malloc(self.GCTLS, flavor='raw')
-        self.stm_operations.set_tls(self, llmemory.cast_ptr_to_adr(tls))
+        self.stm_operations.set_tls(llmemory.cast_ptr_to_adr(tls))
         tls.nursery_start = self._alloc_nursery()
         tls.nursery_size  = self.max_nursery_size
         tls.nursery_free  = tls.nursery_start
@@ -107,7 +115,7 @@
         """Teardown a thread.  Call this just before the OS-level thread
         disappears."""
         tls = self.collector.get_tls()
-        self.stm_operations.set_tls(self, NULL)
+        self.stm_operations.del_tls()
         self._free_nursery(tls.nursery_start)
         lltype.free(tls, flavor='raw')
 
@@ -157,6 +165,11 @@
         return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
 
 
+    def malloc_varsize_clear(self, typeid, length, size, itemsize,
+                             offset_to_length):
+        raise NotImplementedError
+
+
     def _malloc_local_raw(self, tls, size):
         # for _stm_write_barrier_global(): a version of malloc that does
         # no initialization of the malloc'ed object
@@ -168,6 +181,10 @@
         return obj
 
 
+    def collect(self, gen=0):
+        raise NotImplementedError
+
+
     @always_inline
     def combine(self, typeid16, flags):
         return llop.combine_ushort(lltype.Signed, typeid16, flags)
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -22,24 +22,26 @@
 
     threadnum = 0          # 0 = main thread; 1,2,3... = transactional threads
 
-    def set_tls(self, gc, tls):
+    def set_tls(self, tls):
         assert lltype.typeOf(tls) == llmemory.Address
+        assert tls
         if self.threadnum == 0:
             assert not hasattr(self, '_tls_dict')
-            assert not hasattr(self, '_gc')
             self._tls_dict = {0: tls}
             self._tldicts = {0: {}}
             self._tldicts_iterators = {}
-            self._gc = gc
             self._transactional_copies = []
         else:
-            assert self._gc is gc
             self._tls_dict[self.threadnum] = tls
             self._tldicts[self.threadnum] = {}
 
     def get_tls(self):
         return self._tls_dict[self.threadnum]
 
+    def del_tls(self):
+        del self._tls_dict[self.threadnum]
+        del self._tldicts[self.threadnum]
+
     def tldict_lookup(self, obj):
         assert lltype.typeOf(obj) == llmemory.Address
         assert obj
@@ -48,6 +50,7 @@
 
     def tldict_add(self, obj, localobj):
         assert lltype.typeOf(obj) == llmemory.Address
+        assert lltype.typeOf(localobj) == llmemory.Address
         tldict = self._tldicts[self.threadnum]
         assert obj not in tldict
         tldict[obj] = localobj
@@ -63,6 +66,7 @@
         except StopIteration:
             state[1] = None
             state[2] = None
+            del self._tldicts_iterators[self.threadnum]
             return False
         state[1] = next_key
         state[2] = next_value
@@ -130,6 +134,7 @@
         config = get_pypy_config(translating=True).translation
         self.gc = self.GCClass(config, FakeStmOperations(),
                                translated_to_c=False)
+        self.gc.stm_operations._gc = self.gc
         self.gc.DEBUG = True
         self.gc.get_size = fake_get_size
         self.gc.trace = fake_trace
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -62,6 +62,7 @@
 #define OTHERINEV_REASONS 5
 
 struct tx_descriptor {
+  void *rpython_tls_object;
   jmp_buf *setjmp_buf;
   owner_version_t start_time;
   owner_version_t end_time;
@@ -481,7 +482,7 @@
 }
 
 
-void stm_descriptor_init(void)
+static struct tx_descriptor *descriptor_init(void)
 {
   assert(thread_descriptor == NULL_TX);
   if (1)  /* for hg diff */
@@ -507,10 +508,11 @@
                                           (long)pthread_self());
       PYPY_DEBUG_STOP("stm-init");
 #endif
+      return d;
     }
 }
 
-void stm_descriptor_done(void)
+static void descriptor_done(void)
 {
   struct tx_descriptor *d = thread_descriptor;
   assert(d != NULL_TX);
@@ -840,4 +842,20 @@
   return d->my_lock_word;
 }
 
+
+void stm_set_tls(void *newtls)
+{
+  descriptor_init()->rpython_tls_object = newtls;
+}
+
+void *stm_get_tls(void)
+{
+  return thread_descriptor->rpython_tls_object;
+}
+
+void stm_del_tls(void)
+{
+  descriptor_done();
+}
+
 #endif  /* PYPY_NOT_MAIN_FILE */
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -11,6 +11,13 @@
 #include <setjmp.h>
 #include "src/commondefs.h"
 
+
+void stm_set_tls(void *);
+void *stm_get_tls(void);
+void stm_del_tls(void);
+
+
+
 #ifdef RPY_STM_ASSERT
 #  define STM_CCHARP1(arg)    char* arg
 #  define STM_EXPLAIN1(info)  info
@@ -20,8 +27,6 @@
 #endif
 
 
-void stm_descriptor_init(void);
-void stm_descriptor_done(void);
 void* stm_perform_transaction(void*(*)(void*, long), void*);
 long stm_read_word(long* addr);
 void stm_write_word(long* addr, long val);
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/stmgcintf.py
@@ -0,0 +1,39 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.translator.stm import _rffi_stm
+
+
+def smexternal(name, args, result):
+    return staticmethod(_rffi_stm.llexternal(name, args, result))
+
+
+class StmOperations(object):
+
+    def _freeze_(self):
+        return True
+
+    set_tls = smexternal('stm_set_tls', [llmemory.Address], lltype.Void)
+    get_tls = smexternal('stm_get_tls', [], llmemory.Address)
+    del_tls = smexternal('stm_del_tls', [], lltype.Void)
+
+    tldict_lookup = smexternal('stm_tldict_lookup', [llmemory.Address],
+                               llmemory.Address)
+    tldict_add = smexternal('stm_tldict_add', [llmemory.Address] * 2,
+                            lltype.Void)
+
+    enum_tldict_start = smexternal('stm_enum_tldict_start', [], lltype.Void)
+    enum_tldict_find_next = smexternal('stm_enum_tldict_find_next', [],
+                                       lltype.Signed)
+    enum_tldict_globalobj = smexternal('stm_enum_tldict_globalobj', [],
+                                       llmemory.Address)
+    enum_tldict_localobj  = smexternal('stm_enum_tldict_localobj', [],
+                                       llmemory.Address)
+
+    stm_read_word = smexternal('stm_read_word',
+                               [llmemory.Address, lltype.Signed],
+                               lltype.Signed)
+
+    stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
+                                               [llmemory.Address,
+                                                llmemory.Address,
+                                                lltype.Signed],
+                                               lltype.Void)
diff --git a/pypy/translator/stm/test/test_stmgcintf.py b/pypy/translator/stm/test/test_stmgcintf.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/test/test_stmgcintf.py
@@ -0,0 +1,14 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.translator.stm.stmgcintf import StmOperations
+
+stm_operations = StmOperations()
+
+
+def test_set_get_del():
+    # assume that they are really thread-local; not checked here
+    s = lltype.malloc(lltype.Struct('S'), flavor='raw')
+    a = llmemory.cast_ptr_to_adr(s)
+    stm_operations.set_tls(a)
+    assert stm_operations.get_tls() == a
+    stm_operations.del_tls()
+    lltype.free(s, flavor='raw')


More information about the pypy-commit mailing list