[pypy-commit] stmgc default: Managed to get an almost reliable way to check if two operations do or don't conflict. Will use it

arigo noreply at buildbot.pypy.org
Thu Oct 2 14:37:31 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r1439:5eb7fdfb8edf
Date: 2014-10-02 14:37 +0200
http://bitbucket.org/pypy/stmgc/changeset/5eb7fdfb8edf/

Log:	Managed to get an almost reliable way to check if two operations do
	or don't conflict. Will use it to check more complex demos.

diff --git a/hashtable/stmcheck.py b/hashtable/stmcheck.py
new file mode 100644
--- /dev/null
+++ b/hashtable/stmcheck.py
@@ -0,0 +1,47 @@
+import py
+import thread, time, sys
+from __pypy__.thread import *
+
+try:
+    from pypyjit import set_param
+except ImportError:
+    def set_param(value):
+        pass
+
+
+class Conflict(Exception):
+    pass
+
+
+def check_no_conflict(function_list, repeat=10000):
+    set_param("off")
+    #
+    def fn(index):
+        function = function_list[index]
+        sys.stdout.write("*** start %d ***\n" % index)
+        reset_longest_abort_info()
+        hint_commit_soon()
+        i = 0
+        while i < repeat:
+            function()
+            i += 1
+        hint_commit_soon()
+        abort_info = longest_abort_info()
+        with atomic:
+            abort_infos.append(abort_info)
+            if len(abort_infos) == count:
+                finished.release()
+    #
+    abort_infos = []
+    finished = thread.allocate_lock()
+    finished.acquire()
+    count = len(function_list)
+    tlist = [thread.start_new_thread(fn, (i,)) for i in range(count)]
+    finished.acquire()
+    for i in range(count):
+        print 'thread %d: %r' % (i, abort_infos[i])
+    if abort_infos != [None] * count:
+        raise Conflict
+
+def check_conflict(*args, **kwds):
+    py.test.raises(Conflict, check_no_conflict, *args, **kwds)
diff --git a/hashtable/test_stmcheck.py b/hashtable/test_stmcheck.py
new file mode 100644
--- /dev/null
+++ b/hashtable/test_stmcheck.py
@@ -0,0 +1,31 @@
+import stmcheck
+
+
+def test_no_conflict():
+    def t1():
+        pass
+    def t2():
+        pass
+    stmcheck.check_no_conflict([t1, t2])
+
+def test_obvious_conflict():
+    lst = [0]
+    def t1():
+        lst[0] += 1
+    stmcheck.check_conflict([t1, t1])
+
+def test_no_conflict_if_writing_to_different_lists():
+    lst = [[0], [0]]
+    def t1():
+        lst[0][0] += 1
+    def t2():
+        lst[1][0] += 1
+    stmcheck.check_no_conflict([t1, t2])
+
+def test_conflict_even_if_writing_to_different_offsets():
+    lst = [0, 0]
+    def t1():
+        lst[0] += 1
+    def t2():
+        lst[1] += 1
+    stmcheck.check_conflict([t1, t2])


More information about the pypy-commit mailing list