[pypy-commit] pypy stm: Progress.

arigo noreply at buildbot.pypy.org
Fri Oct 28 18:30:54 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r48574:3ec86f341cf6
Date: 2011-10-28 14:22 +0200
http://bitbucket.org/pypy/pypy/changeset/3ec86f341cf6/

Log:	Progress.

diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py
--- a/pypy/translator/c/funcgen.py
+++ b/pypy/translator/c/funcgen.py
@@ -226,6 +226,8 @@
                     yield '\tRPyConvertExceptionToCPython();'
                     yield '\treturn NULL;'
                     yield '}'
+                if self.exception_policy == "stm":
+                    yield 'STM_MAKE_INEVITABLE();'
                 retval = self.expr(block.inputargs[0])
                 if self.exception_policy != "exc_helper":
                     yield 'RPY_DEBUG_RETURN();'
@@ -599,6 +601,8 @@
     OP_STM_BEGIN_TRANSACTION = _OP_STM
     OP_STM_COMMIT_TRANSACTION = _OP_STM
     OP_STM_BEGIN_INEVITABLE_TRANSACTION = _OP_STM
+    OP_STM_TRANSACTION_BOUNDARY = _OP_STM
+    OP_STM_DECLARE_VARIABLE = _OP_STM
 
 
     def OP_PTR_NONZERO(self, op):
diff --git a/pypy/translator/stm/_rffi_stm.py b/pypy/translator/stm/_rffi_stm.py
--- a/pypy/translator/stm/_rffi_stm.py
+++ b/pypy/translator/stm/_rffi_stm.py
@@ -26,8 +26,10 @@
 descriptor_init = llexternal('stm_descriptor_init', [], lltype.Void)
 descriptor_done = llexternal('stm_descriptor_done', [], lltype.Void)
 
-#begin_transaction = llexternal('STM_begin_transaction', [], lltype.Void)
-#commit_transaction = llexternal('stm_commit_transaction', [], lltype.Signed)
+begin_transaction = llexternal('STM_begin_transaction', [], lltype.Void)
+begin_inevitable_transaction = llexternal('stm_begin_inevitable_transaction',
+                                          [], lltype.Void)
+commit_transaction = llexternal('stm_commit_transaction', [], lltype.Signed)
 
 stm_read_word = llexternal('stm_read_word', [SignedP], lltype.Signed)
 stm_write_word = llexternal('stm_write_word', [SignedP, lltype.Signed],
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -93,6 +93,17 @@
 def stm_begin_inevitable_transaction(funcgen, op):
     return 'stm_begin_inevitable_transaction();'
 
+def stm_declare_variable(funcgen, op):
+    # this operation occurs only once at the start of a function if
+    # it uses stm_transaction_boundary
+    assert funcgen.exception_policy is None
+    funcgen.exception_policy = 'stm'
+    return 'STM_DECLARE_VARIABLE();'
+
+def stm_transaction_boundary(funcgen, op):
+    assert funcgen.exception_policy == 'stm'
+    return 'STM_TRANSACTION_BOUNDARY();'
+
 
 def op_stm(funcgen, op):
     assert funcgen.db.translator.stm_transformation_applied
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
@@ -738,6 +738,13 @@
 #endif
 }
 
+void stm_try_inevitable_if(jmp_buf *buf)
+{
+  struct tx_descriptor *d = thread_descriptor;
+  if (d && d->setjmp_buf == buf)    /* XXX remove the test for 'd != NULL' */
+    stm_try_inevitable();
+}
+
 void stm_begin_inevitable_transaction(void)
 {
   struct tx_descriptor *d = thread_descriptor;
@@ -780,6 +787,13 @@
   tx_abort(7);     /* manual abort */
 }
 
+void stm_transaction_boundary(jmp_buf* buf)
+{
+  stm_commit_transaction();
+  setjmp(*buf);
+  stm_begin_transaction(buf);
+}
+
 // XXX little-endian only!
 void stm_write_partial_word(int fieldsize, char *base, long offset,
                             unsigned long nval)
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
@@ -20,14 +20,21 @@
 long stm_read_word(long* addr);
 void stm_write_word(long* addr, long val);
 void stm_try_inevitable(void);
+void stm_try_inevitable_if(jmp_buf* buf);
 void stm_begin_inevitable_transaction(void);
 void stm_abort_and_retry(void);
+void stm_transaction_boundary(jmp_buf* buf);
 
+/* for testing only: */
 #define STM_begin_transaction()         ; \
        jmp_buf _jmpbuf;                   \
        setjmp(_jmpbuf);                   \
        stm_begin_transaction(&_jmpbuf)
 
+#define STM_DECLARE_VARIABLE()          jmp_buf jmpbuf
+#define STM_MAKE_INEVITABLE()           stm_try_inevitable_if(&jmpbuf)
+#define STM_TRANSACTION_BOUNDARY()      stm_transaction_boundary(&jmpbuf)
+
 // XXX little-endian only!
 #define STM_read_partial_word(T, base, offset)                          \
     (T)(stm_read_word(                                                  \
diff --git a/pypy/translator/stm/test/test_transform.py b/pypy/translator/stm/test/test_transform.py
--- a/pypy/translator/stm/test/test_transform.py
+++ b/pypy/translator/stm/test/test_transform.py
@@ -43,11 +43,9 @@
 
     def test_no_pointer_operations(self):
         def simplefunc(argv):
-            rstm.begin_transaction()
             i = 0
             while i < 100:
                 i += 3
-            rstm.commit_transaction()
             debug_print(i)
             return 0
         t, cbuilder = self.compile(simplefunc)
@@ -56,12 +54,8 @@
         assert '102' in dataerr.splitlines()
 
     def test_fails_when_nonbalanced_begin(self):
-        def g():
-            rstm.begin_transaction()
-        g._dont_inline_ = True
         def simplefunc(argv):
             rstm.begin_transaction()
-            g()
             return 0
         t, cbuilder = self.compile(simplefunc)
         cbuilder.cmdexec('', expect_crash=True)
@@ -69,14 +63,22 @@
     def test_fails_when_nonbalanced_commit(self):
         def simplefunc(argv):
             rstm.commit_transaction()
+            rstm.commit_transaction()
             return 0
         t, cbuilder = self.compile(simplefunc)
         cbuilder.cmdexec('', expect_crash=True)
 
     def test_begin_inevitable_transaction(self):
         def simplefunc(argv):
+            rstm.commit_transaction()
             rstm.begin_inevitable_transaction()
-            rstm.commit_transaction()
             return 0
         t, cbuilder = self.compile(simplefunc)
         cbuilder.cmdexec('')
+
+    def test_transaction_boundary_1(self):
+        def simplefunc(argv):
+            rstm.transaction_boundary()
+            return 0
+        t, cbuilder = self.compile(simplefunc)
+        cbuilder.cmdexec('')
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -1,5 +1,7 @@
 from pypy.objspace.flow.model import SpaceOperation
 from pypy.translator.stm import _rffi_stm
+from pypy.translator.unsimplify import varoftype
+from pypy.rpython.lltypesystem import lltype
 
 
 class STMTransformer(object):
@@ -8,9 +10,12 @@
         self.translator = translator
 
     def transform(self):
+        for graph in self.translator.graphs:
+            self.seen_transaction_boundary = False
+            self.transform_graph(graph)
+            if self.seen_transaction_boundary:
+                self.add_stm_declare_variable(graph)
         self.add_descriptor_init_stuff()
-        for graph in self.translator.graphs:
-            self.transform_graph(graph)
         self.translator.stm_transformation_applied = True
 
     def transform_block(self, block):
@@ -31,11 +36,19 @@
         from pypy.translator.unsimplify import call_final_function
         def descriptor_init():
             _rffi_stm.descriptor_init()
+            _rffi_stm.begin_inevitable_transaction()
         def descriptor_done():
+            _rffi_stm.commit_transaction()
             _rffi_stm.descriptor_done()
         call_initial_function(self.translator, descriptor_init)
         call_final_function(self.translator, descriptor_done)
 
+    def add_stm_declare_variable(self, graph):
+        block = graph.startblock
+        v = varoftype(lltype.Void)
+        op = SpaceOperation('stm_declare_variable', [], v)
+        block.operations.insert(0, op)
+
     # ----------
 
     def stt_getfield(self, newoperations, op):
@@ -50,6 +63,10 @@
         op1 = SpaceOperation('stm_setfield', op.args, op.result)
         newoperations.append(op1)
 
+    def stt_stm_transaction_boundary(self, newoperations, op):
+        self.seen_transaction_boundary = True
+        newoperations.append(op)
+
 
 def transform_graph(graph):
     # for tests: only transforms one graph


More information about the pypy-commit mailing list