[pypy-commit] stmgc default: Fix the big slowness that duhton's list_transaction sometimes shows.

arigo noreply at buildbot.pypy.org
Thu Feb 27 00:42:42 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r887:e0e14e5a9b5d
Date: 2014-02-27 00:42 +0100
http://bitbucket.org/pypy/stmgc/changeset/e0e14e5a9b5d/

Log:	Fix the big slowness that duhton's list_transaction sometimes shows.

diff --git a/c7/stm/contention.c b/c7/stm/contention.c
--- a/c7/stm/contention.c
+++ b/c7/stm/contention.c
@@ -82,7 +82,9 @@
 
         /* wait, hopefully until the other thread broadcasts "I'm
            done aborting" (spurious wake-ups are ok). */
+        dprintf(("contention: wait C_SAFE_POINT...\n"));
         cond_wait(C_SAFE_POINT);
+        dprintf(("contention: done\n"));
 
         cond_broadcast(C_RESUME);
 
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -171,7 +171,7 @@
 #endif
     STM_PSEGMENT->shadowstack_at_start_of_transaction = tl->shadowstack;
     STM_PSEGMENT->threadlocal_at_start_of_transaction = tl->thread_local_obj;
-    STM_SEGMENT->nursery_end = NURSERY_END;
+    assert(STM_SEGMENT->nursery_end == NURSERY_END);
 
     dprintf(("start_transaction\n"));
 
@@ -478,12 +478,28 @@
        contention.c, we use a broadcast, to make sure that all threads are
        signalled, including the one that requested an abort, if any.
        Moreover, we wake up any thread waiting for this one to do a safe
-       point, if any.
+       point, if any (in _finish_transaction above).  Finally, it's
+       possible that we reach this place from the middle of a piece of
+       code like wait_for_other_safe_points() which ends in broadcasting
+       C_RESUME; we must make sure to broadcast it.
     */
     cond_broadcast(C_RELEASE_THREAD_SEGMENT);
+    cond_broadcast(C_RESUME);
 
     mutex_unlock();
 
+    /* It seems to be a good idea, at least in some examples, to sleep
+       one microsecond here before retrying.  Otherwise, what was
+       observed is that the transaction very often restarts too quickly
+       for contention.c to react, and before it can do anything, we have
+       again recreated in this thread a similar situation to the one
+       that caused contention.  Anyway, usleep'ing in case of abort
+       doesn't seem like a very bad idea.  If there are more threads
+       than segments, it should also make sure another thread gets the
+       segment next.
+    */
+    usleep(1);
+
     assert(jmpbuf_ptr != NULL);
     assert(jmpbuf_ptr != (stm_jmpbuf_t *)-1);    /* for tests only */
     __builtin_longjmp(*jmpbuf_ptr, 1);
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -323,6 +323,7 @@
     assert(STM_PSEGMENT->safe_point == SP_RUNNING);
 
     while (STM_SEGMENT->nursery_end == NSE_SIGNAL) {
+        dprintf(("collectable_safe_point...\n"));
         STM_PSEGMENT->safe_point = SP_SAFE_POINT_CAN_COLLECT;
         STM_SEGMENT->nursery_end = NURSERY_END;
 
@@ -334,4 +335,5 @@
 
         STM_PSEGMENT->safe_point = SP_RUNNING;
     }
+    dprintf(("collectable_safe_point done\n"));
 }
diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -705,9 +705,11 @@
     int ms = DuInt_AsInt(obj);
 
     struct timeval t;
+    fprintf(stderr, "[sleeping %d ms]\n", ms);
     t.tv_sec = ms / 1000;
     t.tv_usec = (ms % 1000) * 1000;
     select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+    fprintf(stderr, "[slept %d ms]\n", ms);
 
     return Du_None;
 }


More information about the pypy-commit mailing list