[pypy-commit] stmgc c7-full-profiling: hg merge default

arigo noreply at buildbot.pypy.org
Sat Oct 4 18:16:53 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-full-profiling
Changeset: r1452:ddf145dd0a56
Date: 2014-10-04 18:10 +0200
http://bitbucket.org/pypy/stmgc/changeset/ddf145dd0a56/

Log:	hg merge default

diff --git a/c7/demo/demo2.c b/c7/demo/demo2.c
--- a/c7/demo/demo2.c
+++ b/c7/demo/demo2.c
@@ -296,10 +296,16 @@
 
     stm_setup();
     stm_register_thread_local(&stm_thread_local);
+
+    /* check that we can use stm_start_inevitable_transaction() without
+       any rjbuf on the stack */
+    stm_start_inevitable_transaction(&stm_thread_local);
+    stm_commit_transaction();
+
+
     stm_rewind_jmp_enterframe(&stm_thread_local, &rjbuf);
     stmcb_timing_event = timing_event;
 
-
     setup_list();
 
 
diff --git a/hashtable/design.txt b/hashtable/design.txt
--- a/hashtable/design.txt
+++ b/hashtable/design.txt
@@ -70,5 +70,10 @@
   special-cased in the implementation).  More precisely, len(), keys(),
   clear(), etc., set all the lines' read markers; clear() additionally
   sets all the non-empty lines' write markers (so that it doesn't conflict
-  with another transaction checking that some key is really not in the
+  with another transaction checking that some different key is not in the
   dict).
+
+* We have an additional pair of markers (read and write) for the 'empty'
+  flag.  It is read whenever we check 'bool(dict)'.  It is written only
+  when we are about to commit and the emptiness state changed in this
+  transaction.
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