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