[pypy-commit] stmgc c7-refactor: switch from classes to functions because...

Remi Meier noreply at buildbot.pypy.org
Mon Feb 24 13:51:00 CET 2014


Author: Remi Meier
Branch: c7-refactor
Changeset: r822:ccff4094a83c
Date: 2014-02-24 13:51 +0100
http://bitbucket.org/pypy/stmgc/changeset/ccff4094a83c/

Log:	switch from classes to functions because...

diff --git a/c7/test/test_random.py b/c7/test/test_random.py
--- a/c7/test/test_random.py
+++ b/c7/test/test_random.py
@@ -1,8 +1,6 @@
 from support import *
 import sys, random
 import py
-from cStringIO import StringIO
-
 
 
 
@@ -299,242 +297,234 @@
                        trs.objs_in_conflict)
 
 
-# ========== STM OPERATIONS ==========
+###################################################################
+###################################################################
+######################## STM OPERATIONS ###########################
+###################################################################
+###################################################################
 
-class Operation(object):
-    def do(self, ex, global_state, thread_state):
-        raise NotImplemented
 
-class OpStartTransaction(Operation):
-    def do(self, ex, global_state, thread_state):
-        thread_state.start_transaction()
-        #
-        ex.do('self.start_transaction()')
-        thread_state.reload_roots(ex)
-        #
-        # assert that everything known is old:
-        old_objs = thread_state.saved_roots
-        for o in old_objs:
-            ex.do("assert not is_in_nursery(%s)" % o)
+def op_start_transaction(ex, global_state, thread_state):
+    thread_state.start_transaction()
+    #
+    ex.do('self.start_transaction()')
+    thread_state.reload_roots(ex)
+    #
+    # assert that everything known is old:
+    old_objs = thread_state.saved_roots
+    for o in old_objs:
+        ex.do("assert not is_in_nursery(%s)" % o)
 
 
-class OpCommitTransaction(Operation):
-    def do(self, ex, global_state, thread_state):
-        #
-        # push all new roots
-        ex.do("# push new objs before commit:")
-        thread_state.push_roots(ex)
-        aborts = thread_state.commit_transaction()
-        #
-        if aborts:
-            thread_state.abort_transaction()
-        ex.do(raising_call(aborts, "self.commit_transaction"))
+def op_commit_transaction(ex, global_state, thread_state):
+    #
+    # push all new roots
+    ex.do("# push new objs before commit:")
+    thread_state.push_roots(ex)
+    aborts = thread_state.commit_transaction()
+    #
+    if aborts:
+        thread_state.abort_transaction()
+    ex.do(raising_call(aborts, "self.commit_transaction"))
 
-class OpAbortTransaction(Operation):
-    def do(self, ex, global_state, thread_state):
-        trs = thread_state.transaction_state
-        if trs.inevitable:
-            return
-        trs.set_must_abort()
+def op_abort_transaction(ex, global_state, thread_state):
+    trs = thread_state.transaction_state
+    if trs.inevitable:
+        return
+    trs.set_must_abort()
+    thread_state.abort_transaction()
+    ex.do('self.abort_transaction()')
+
+def op_become_inevitable(ex, global_state, thread_state):
+    trs = thread_state.transaction_state
+    global_state.check_if_can_become_inevitable(trs)
+
+    thread_state.push_roots(ex)
+    ex.do(raising_call(trs.check_must_abort(),
+                       "stm_become_inevitable"))
+    if trs.check_must_abort():
         thread_state.abort_transaction()
-        ex.do('self.abort_transaction()')
-
-class OpBecomeInevitable(Operation):
-    def do(self, ex, global_state, thread_state):
-        trs = thread_state.transaction_state
-        global_state.check_if_can_become_inevitable(trs)
-
-        thread_state.push_roots(ex)
-        ex.do(raising_call(trs.check_must_abort(),
-                           "stm_become_inevitable"))
-        if trs.check_must_abort():
-            thread_state.abort_transaction()
-        else:
-            trs.inevitable = True
-            thread_state.pop_roots(ex)
-            thread_state.reload_roots(ex)
-
-
-class OpAllocate(Operation):
-    def do(self, ex, global_state, thread_state):
-        size = global_state.rnd.choice([
-            "16",
-            "SOME_MEDIUM_SIZE+16",
-            #"SOME_LARGE_SIZE+16",
-        ])
-        r = global_state.get_new_root_name(False, size)
-        thread_state.push_roots(ex)
-
-        ex.do('%s = stm_allocate(%s)' % (r, size))
-        thread_state.transaction_state.add_root(r, 0, True)
-
-        thread_state.pop_roots(ex)
-        thread_state.reload_roots(ex)
-        thread_state.register_root(r)
-
-class OpAllocateRef(Operation):
-    def do(self, ex, global_state, thread_state):
-        num = str(global_state.rnd.randrange(1, 100))
-        r = global_state.get_new_root_name(True, num)
-        thread_state.push_roots(ex)
-        ex.do('%s = stm_allocate_refs(%s)' % (r, num))
-        thread_state.transaction_state.add_root(r, "ffi.NULL", True)
-
-        thread_state.pop_roots(ex)
-        thread_state.reload_roots(ex)
-        thread_state.register_root(r)
-
-class OpMinorCollect(Operation):
-    def do(self, ex, global_state, thread_state):
-        thread_state.push_roots(ex)
-        ex.do('stm_minor_collect()')
+    else:
+        trs.inevitable = True
         thread_state.pop_roots(ex)
         thread_state.reload_roots(ex)
 
 
-class OpForgetRoot(Operation):
-    def do(self, ex, global_state, thread_state):
-        r = thread_state.forget_random_root()
-        if thread_state.transaction_state.inevitable:
-            ex.do('# inevitable forget %s' % r)
+def op_allocate(ex, global_state, thread_state):
+    size = global_state.rnd.choice([
+        "16",
+        "SOME_MEDIUM_SIZE+16",
+        #"SOME_LARGE_SIZE+16",
+    ])
+    r = global_state.get_new_root_name(False, size)
+    thread_state.push_roots(ex)
+
+    ex.do('%s = stm_allocate(%s)' % (r, size))
+    thread_state.transaction_state.add_root(r, 0, True)
+
+    thread_state.pop_roots(ex)
+    thread_state.reload_roots(ex)
+    thread_state.register_root(r)
+
+def op_allocate_ref(ex, global_state, thread_state):
+    num = str(global_state.rnd.randrange(1, 100))
+    r = global_state.get_new_root_name(True, num)
+    thread_state.push_roots(ex)
+    ex.do('%s = stm_allocate_refs(%s)' % (r, num))
+    thread_state.transaction_state.add_root(r, "ffi.NULL", True)
+
+    thread_state.pop_roots(ex)
+    thread_state.reload_roots(ex)
+    thread_state.register_root(r)
+
+def op_minor_collect(ex, global_state, thread_state):
+    thread_state.push_roots(ex)
+    ex.do('stm_minor_collect()')
+    thread_state.pop_roots(ex)
+    thread_state.reload_roots(ex)
+
+
+def op_forget_root(ex, global_state, thread_state):
+    r = thread_state.forget_random_root()
+    if thread_state.transaction_state.inevitable:
+        ex.do('# inevitable forget %s' % r)
+    else:
+        ex.do('# forget %s' % r)
+
+def op_write(ex, global_state, thread_state):
+    r = thread_state.get_random_root()
+    trs = thread_state.transaction_state
+    is_ref = global_state.has_ref_type(r)
+    #
+    # check for possible write-write conflict:
+    was_written = False
+    try:
+        # HACK to avoid calling write_root() just yet because we have to
+        # undo it in case of the exception :(
+        was_written = r in trs.write_set
+        trs.write_set.add(r)
+        global_state.check_for_write_write_conflicts(trs)
+    except WriteWriteConflictNotTestable:
+        if not was_written:
+            trs.write_set.remove(r)
+        ex.do("# writing to %s produces an untestable write-write" % r)
+        ex.do("# conflict between an inevitable and a normal transaction :(")
+        return
+    #
+    # decide on a value to write
+    if is_ref:
+        v = thread_state.get_random_root()
+    else:
+        v = ord(global_state.rnd.choice("abcdefghijklmnop"))
+    assert trs.write_root(r, v) is not None
+    #
+    aborts = trs.check_must_abort()
+    if aborts:
+        thread_state.abort_transaction()
+    offset = global_state.get_root_size(r) + " - 1"
+    if is_ref:
+        ex.do(raising_call(aborts, "stm_set_ref", r, offset, v))
+        if not aborts:
+            ex.do(raising_call(False, "stm_set_ref", r, "0", v))
+    else:
+        ex.do(raising_call(aborts, "stm_set_char", r, repr(chr(v)), offset))
+        if not aborts:
+            ex.do(raising_call(False, "stm_set_char", r, repr(chr(v)), "HDR"))
+
+def op_read(ex, global_state, thread_state):
+    r = thread_state.get_random_root()
+    trs = thread_state.transaction_state
+    v = trs.read_root(r)
+    #
+    offset = global_state.get_root_size(r) + " - 1"
+    if global_state.has_ref_type(r):
+        if v in thread_state.saved_roots or v in global_state.prebuilt_roots:
+            # v = root known to this transaction; or prebuilt
+            ex.do("assert stm_get_ref(%s, %s) == %s" % (r, offset, v))
+            ex.do("assert stm_get_ref(%s, 0) == %s" % (r, v))
+        elif v != "ffi.NULL":
+            # if v came from this transaction: re-add it to saved_roots because
+            #     it survived by being referenced by another saved root
+            # if v is from a different transaction:
+            #     we fish its value from somewhere and add it to our known roots
+            global_trs = global_state.committed_transaction_state
+            if v not in trs.values:
+                # not from this transaction AND not known at the start of this
+                # transaction
+                trs.add_root(v, global_trs.values[v], False)
+                ex.do("# get %r from other thread" % v)
+            elif v not in global_trs.values:
+                # created and forgotten earlier in this thread
+                ex.do("# revive %r in this thread" % v)
+            else:
+                # created in an earlier transaction, now also known here
+                ex.do("# register %r in this thread" % v)
+            #
+            ex.do("%s = stm_get_ref(%s, %s)" % (v, r, offset))
+            ex.do("%s = stm_get_ref(%s, 0)" % (v, r))
+            thread_state.register_root(v)
         else:
-            ex.do('# forget %s' % r)
+            # v is NULL; we still need to read it (as it should be in the read-set):
+            ex.do("assert stm_get_ref(%s, %s) == %s" % (r,offset,v))
+            ex.do("assert stm_get_ref(%s, 0) == %s" % (r,v))
+    else:
+        ex.do("assert stm_get_char(%s, %s) == %s" % (r, offset, repr(chr(v))))
+        ex.do("assert stm_get_char(%s, HDR) == %s" % (r, repr(chr(v))))
 
-class OpWrite(Operation):
-    def do(self, ex, global_state, thread_state):
-        r = thread_state.get_random_root()
-        trs = thread_state.transaction_state
-        is_ref = global_state.has_ref_type(r)
+def op_assert_size(ex, global_state, thread_state):
+    r = thread_state.get_random_root()
+    size = global_state.get_root_size(r)
+    if global_state.has_ref_type(r):
+        ex.do("assert stm_get_obj_size(%s) == %s" % (r, size + " * WORD + HDR"))
+    else:
+        ex.do("assert stm_get_obj_size(%s) == %s" % (r, size))
+
+def op_assert_modified(ex, global_state, thread_state):
+    trs = thread_state.transaction_state
+    modified = trs.get_old_modified()
+    ex.do("# modified = %s" % modified)
+    ex.do("modified = modified_objects()")
+    if not modified:
+        ex.do("assert modified == []")
+    else:
+        saved = [m for m in modified
+                 if m in thread_state.saved_roots or m in global_state.prebuilt_roots]
+        ex.do("assert {%s}.issubset(set(modified))" % (
+            ", ".join(saved)
+        ))
+
+
+def op_switch_thread(ex, global_state, thread_state, new_thread_state=None):
+    if new_thread_state is None:
+        new_thread_state = global_state.rnd.choice(global_state.thread_states)
+
+    if new_thread_state != thread_state:
+        if thread_state.transaction_state:
+            thread_state.push_roots(ex)
+        ex.do('#')
         #
-        # check for possible write-write conflict:
-        was_written = False
-        try:
-            # HACK to avoid calling write_root() just yet because we have to
-            # undo it in case of the exception :(
-            was_written = r in trs.write_set
-            trs.write_set.add(r)
-            global_state.check_for_write_write_conflicts(trs)
-        except WriteWriteConflictNotTestable:
-            if not was_written:
-                trs.write_set.remove(r)
-            ex.do("# writing to %s produces an untestable write-write" % r)
-            ex.do("# conflict between an inevitable and a normal transaction :(")
-            return
+        trs = new_thread_state.transaction_state
+        conflicts = trs is not None and trs.check_must_abort()
+        ex.thread_num = new_thread_state.num
         #
-        # decide on a value to write
-        if is_ref:
-            v = thread_state.get_random_root()
+        ex.do(raising_call(conflicts,
+                           "self.switch", new_thread_state.num))
+        if conflicts:
+            new_thread_state.abort_transaction()
         else:
-            v = ord(global_state.rnd.choice("abcdefghijklmnop"))
-        assert trs.write_root(r, v) is not None
-        #
-        aborts = trs.check_must_abort()
-        if aborts:
-            thread_state.abort_transaction()
-        offset = global_state.get_root_size(r) + " - 1"
-        if is_ref:
-            ex.do(raising_call(aborts, "stm_set_ref", r, offset, v))
-            if not aborts:
-                ex.do(raising_call(False, "stm_set_ref", r, "0", v))
-        else:
-            ex.do(raising_call(aborts, "stm_set_char", r, repr(chr(v)), offset))
-            if not aborts:
-                ex.do(raising_call(False, "stm_set_char", r, repr(chr(v)), "HDR"))
+            new_thread_state.pop_roots(ex)
+            new_thread_state.reload_roots(ex)
 
-class OpRead(Operation):
-    def do(self, ex, global_state, thread_state):
-        r = thread_state.get_random_root()
-        trs = thread_state.transaction_state
-        v = trs.read_root(r)
-        #
-        offset = global_state.get_root_size(r) + " - 1"
-        if global_state.has_ref_type(r):
-            if v in thread_state.saved_roots or v in global_state.prebuilt_roots:
-                # v = root known to this transaction; or prebuilt
-                ex.do("assert stm_get_ref(%s, %s) == %s" % (r, offset, v))
-                ex.do("assert stm_get_ref(%s, 0) == %s" % (r, v))
-            elif v != "ffi.NULL":
-                # if v came from this transaction: re-add it to saved_roots because
-                #     it survived by being referenced by another saved root
-                # if v is from a different transaction:
-                #     we fish its value from somewhere and add it to our known roots
-                global_trs = global_state.committed_transaction_state
-                if v not in trs.values:
-                    # not from this transaction AND not known at the start of this
-                    # transaction
-                    trs.add_root(v, global_trs.values[v], False)
-                    ex.do("# get %r from other thread" % v)
-                elif v not in global_trs.values:
-                    # created and forgotten earlier in this thread
-                    ex.do("# revive %r in this thread" % v)
-                else:
-                    # created in an earlier transaction, now also known here
-                    ex.do("# register %r in this thread" % v)
-                #
-                ex.do("%s = stm_get_ref(%s, %s)" % (v, r, offset))
-                ex.do("%s = stm_get_ref(%s, 0)" % (v, r))
-                thread_state.register_root(v)
-            else:
-                # v is NULL; we still need to read it (as it should be in the read-set):
-                ex.do("assert stm_get_ref(%s, %s) == %s" % (r,offset,v))
-                ex.do("assert stm_get_ref(%s, 0) == %s" % (r,v))
-        else:
-            ex.do("assert stm_get_char(%s, %s) == %s" % (r, offset, repr(chr(v))))
-            ex.do("assert stm_get_char(%s, HDR) == %s" % (r, repr(chr(v))))
+    return new_thread_state
 
-class OpAssertSize(Operation):
-    def do(self, ex, global_state, thread_state):
-        r = thread_state.get_random_root()
-        size = global_state.get_root_size(r)
-        if global_state.has_ref_type(r):
-            ex.do("assert stm_get_obj_size(%s) == %s" % (r, size + " * WORD + HDR"))
-        else:
-            ex.do("assert stm_get_obj_size(%s) == %s" % (r, size))
 
-class OpAssertModified(Operation):
-    def do(self, ex, global_state, thread_state):
-        trs = thread_state.transaction_state
-        modified = trs.get_old_modified()
-        ex.do("# modified = %s" % modified)
-        ex.do("modified = modified_objects()")
-        if not modified:
-            ex.do("assert modified == []")
-        else:
-            saved = [m for m in modified
-                     if m in thread_state.saved_roots or m in global_state.prebuilt_roots]
-            ex.do("assert {%s}.issubset(set(modified))" % (
-                ", ".join(saved)
-            ))
+###################################################################
+###################################################################
+####################### TEST GENERATION ###########################
+###################################################################
+###################################################################
 
 
-class OpSwitchThread(Operation):
-    def do(self, ex, global_state, thread_state, new_thread_state=None):
-        if new_thread_state is None:
-            new_thread_state = global_state.rnd.choice(global_state.thread_states)
-
-        if new_thread_state != thread_state:
-            if thread_state.transaction_state:
-                thread_state.push_roots(ex)
-            ex.do('#')
-            #
-            trs = new_thread_state.transaction_state
-            conflicts = trs is not None and trs.check_must_abort()
-            ex.thread_num = new_thread_state.num
-            #
-            ex.do(raising_call(conflicts,
-                               "self.switch", new_thread_state.num))
-            if conflicts:
-                new_thread_state.abort_transaction()
-            else:
-                new_thread_state.pop_roots(ex)
-                new_thread_state.reload_roots(ex)
-
-        return new_thread_state
-
-
-
-# ========== TEST GENERATION ==========
-
 class TestRandom(BaseTest):
 
     def test_fixed_16_bytes_objects(self, seed=1010):
@@ -567,28 +557,28 @@
 
         # random steps:
         possible_actions = [
-            OpAllocate,
-            OpAllocateRef, OpAllocateRef,
-            OpWrite, OpWrite, OpWrite,
-            OpRead, OpRead, OpRead, OpRead, OpRead, OpRead, OpRead, OpRead,
-            OpCommitTransaction,
-            OpAbortTransaction,
-            OpForgetRoot,
-            OpBecomeInevitable,
-            OpAssertSize,
-            #OpAssertModified,
-            OpMinorCollect,
+            op_allocate,
+            op_allocate_ref, op_allocate_ref,
+            op_write, op_write, op_write,
+            op_read, op_read, op_read, op_read, op_read, op_read, op_read, op_read,
+            op_commit_transaction,
+            op_abort_transaction,
+            op_forget_root,
+            op_become_inevitable,
+            op_assert_size,
+            #op_assert_modified,
+            op_minor_collect,
         ]
         for _ in range(200):
             # make sure we are in a transaction:
-            curr_thread = OpSwitchThread().do(ex, global_state, curr_thread)
+            curr_thread = op_switch_thread(ex, global_state, curr_thread)
 
             if curr_thread.transaction_state is None:
-                OpStartTransaction().do(ex, global_state, curr_thread)
+                op_start_transaction(ex, global_state, curr_thread)
 
             # do something random
             action = rnd.choice(possible_actions)
-            action().do(ex, global_state, curr_thread)
+            action(ex, global_state, curr_thread)
 
         # to make sure we don't have aborts in the test's teardown method,
         # we will simply stop all running transactions
@@ -596,12 +586,12 @@
             if ts.transaction_state is not None:
                 if curr_thread != ts:
                     ex.do('#')
-                    curr_thread = OpSwitchThread().do(ex, global_state, curr_thread,
-                                                      new_thread_state=ts)
+                    curr_thread = op_switch_thread(ex, global_state, curr_thread,
+                                                  new_thread_state=ts)
 
                 # could have aborted in the switch() above:
                 if curr_thread.transaction_state:
-                    OpCommitTransaction().do(ex, global_state, curr_thread)
+                    op_commit_transaction(ex, global_state, curr_thread)
 
 
 


More information about the pypy-commit mailing list