Author: Armin Rigo <ar...@tunes.org>
Branch: c7
Changeset: r630:c236694327c2
Date: 2014-01-17 16:06 +0100
http://bitbucket.org/pypy/stmgc/changeset/c236694327c2/

Log:    The basic test_random passes, yuhuu

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,85 +1,120 @@
 from support import *
 import sys, random
+import py
+from cStringIO import StringIO
+
+
+class Exec(object):
+    def __init__(self, test):
+        self.content = {'self': test}
+
+    def do(self, cmd):
+        print >> sys.stderr, cmd
+        exec cmd in globals(), self.content
 
 
 class TestRandom(BaseTest):
 
-    def test_fixed_16_bytes_objects(self):
-        rnd = random.Random(1010)
+    def test_fixed_16_bytes_objects(self, seed=1010):
+        rnd = random.Random(seed)
 
-        N_OBJECTS = 10
-        N_THREADS = 3
-        print >> sys.stderr, 'stm_start_transaction()'
-        stm_start_transaction()
-        plist = [stm_allocate(16) for i in range(N_OBJECTS)]
-        read_sets = [{} for i in range(N_THREADS)]
+        N_OBJECTS = 5
+        N_THREADS = 2
+        ex = Exec(self)
+        ex.do('# initialization')
+        ex.do('stm_start_transaction()')
+        head_state = []
+        for i in range(N_OBJECTS):
+            ex.do('lp%d = stm_allocate(16)' % i)
+            ex.do('stm_set_char(lp%d, %r)' % (i, chr(i)))
+            head_state.append(chr(i))
+            ex.do('stm_push_root(lp%d)' % i)
+        read_sets = [set() for i in range(N_THREADS)]
         write_sets = [{} for i in range(N_THREADS)]
-        active_transactions = {}
+        active_transactions = set()
+        need_abort = set()
 
-        for i in range(N_OBJECTS):
-            print >> sys.stderr, 'p%d = stm_allocate(16)' % i
-        for i in range(N_OBJECTS):
-            print >> sys.stderr, 'p%d[8] = %r' % (i, chr(i))
-            plist[i][8] = chr(i)
-        head_state = [[chr(i) for i in range(N_OBJECTS)]]
-        commit_log = []
-        print >> sys.stderr, 'stm_stop_transaction(False)'
-        stm_stop_transaction(False)
+        ex.do('stm_stop_transaction()')
+        for i in range(N_OBJECTS-1, -1, -1):
+            ex.do('lp%d = stm_pop_root()' % i)
 
-        for i in range(N_THREADS):
-            print >> sys.stderr, 'self.switch(%d)' % i
-            self.switch(i)
         stop_count = 1
+        current_thread = 0
 
-        for i in range(10000):
+        def aborted():
+            active_transactions.remove(n_thread)
+            write_sets[n_thread].clear()
+            read_sets[n_thread].clear()
+            need_abort.discard(n_thread)
+
+        remaining_steps = 200
+        while remaining_steps > 0 or active_transactions:
+            remaining_steps -= 1
             n_thread = rnd.randrange(0, N_THREADS)
-            print >> sys.stderr, '#\nself.switch(%d)' % n_thread
-            self.switch(n_thread)
+            if n_thread != current_thread:
+                ex.do('#')
+                current_thread = n_thread
+                if n_thread in need_abort:
+                    ex.do('py.test.raises(Conflict, self.switch, %d)' % 
n_thread)
+                    aborted()
+                    continue
+                ex.do('self.switch(%d)' % n_thread)
             if n_thread not in active_transactions:
-                print >> sys.stderr, 'stm_start_transaction()'
-                stm_start_transaction()
-                active_transactions[n_thread] = len(commit_log)
+                if remaining_steps <= 0:
+                    continue
+                ex.do('stm_start_transaction()')
+                active_transactions.add(n_thread)
 
             action = rnd.randrange(0, 7)
-            if action < 6:
+            if action < 6 and remaining_steps > 0:
                 is_write = action >= 4
                 i = rnd.randrange(0, N_OBJECTS)
-                print >> sys.stderr, "stm_read(p%d)" % i
-                stm_read(plist[i])
-                got = plist[i][8]
-                print >> sys.stderr, "assert p%d[8] ==" % i,
-                my_head_state = head_state[active_transactions[n_thread]]
-                prev = read_sets[n_thread].setdefault(i, my_head_state[i])
-                print >> sys.stderr, "%r" % (prev,)
-                assert got == prev
+                if i in write_sets[n_thread]:
+                    expected = write_sets[n_thread][i]
+                else:
+                    expected = head_state[i]
+                ex.do("assert stm_get_char(lp%d) == %r" % (i, expected))
+                read_sets[n_thread].add(i)
                 #
                 if is_write:
-                    print >> sys.stderr, 'stm_write(p%d)' % i
-                    stm_write(plist[i])
                     newval = chr(rnd.randrange(0, 256))
-                    print >> sys.stderr, 'p%d[8] = %r' % (i, newval)
-                    plist[i][8] = newval
-                    read_sets[n_thread][i] = write_sets[n_thread][i] = newval
+                    write_write_conflict = False
+                    for t in range(N_THREADS):
+                        if t != n_thread:
+                            write_write_conflict |= i in write_sets[t]
+                    if write_write_conflict:
+                        ex.do('py.test.raises(Conflict, stm_set_char, lp%d, 
%r)'
+                              % (i, newval))
+                        aborted()
+                        continue
+                    else:
+                        ex.do('stm_set_char(lp%d, %r)' % (i, newval))
+                    write_sets[n_thread][i] = newval
             else:
-                src_index = active_transactions.pop(n_thread)
-                conflict = False
-                for i in range(src_index, len(commit_log)):
-                    for j in commit_log[i]:
-                        if j in read_sets[n_thread]:
-                            conflict = True
-                print >> sys.stderr, "stm_stop_transaction(%r) #%d" % (
-                    conflict, stop_count)
-                stop_count += 1
-                stm_stop_transaction(conflict)
-                #
-                if not conflict:
-                    hs = head_state[-1][:]
-                    for i, newval in write_sets[n_thread].items():
-                        hs[i] = newval
-                        assert plist[i][8] == newval
-                    head_state.append(hs)
-                    commit_log.append(write_sets[n_thread].keys())
-                    print >> sys.stderr, '#', head_state[-1]
-                    print >> sys.stderr, '# log:', commit_log[-1]
+                active_transactions.remove(n_thread)
+                changes = []
+                modified = sorted(write_sets[n_thread])
+                for i in modified:
+                    nval = write_sets[n_thread][i]
+                    changes.append('lp%d=%r' % (i, nval))
+                    head_state[i] = nval
                 write_sets[n_thread].clear()
                 read_sets[n_thread].clear()
+                ex.do('stm_stop_transaction() #%d %s' % (stop_count, ' 
'.join(changes)))
+                stop_count += 1
+
+                for t in range(N_THREADS):
+                    if t != n_thread:
+                        for i in modified:
+                            if i in read_sets[t]:
+                                need_abort.add(t)
+
+    def _make_fun(seed):
+        def test_fun(self):
+            self.test_fixed_16_bytes_objects(seed)
+        test_fun.__name__ = 'test_fixed_16_bytes_objects_%d' % seed
+        return test_fun
+
+    for _seed in range(5000, 5100):
+        _fn = _make_fun(_seed)
+        locals()[_fn.__name__] = _fn
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to