Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit