[pypy-commit] stmgc default: Tweak tweak tweak: a deadlock was possible there
arigo
noreply at buildbot.pypy.org
Thu Jun 18 18:35:52 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1862:ee0e63d791cb
Date: 2015-06-18 18:36 +0200
http://bitbucket.org/pypy/stmgc/changeset/ee0e63d791cb/
Log: Tweak tweak tweak: a deadlock was possible there
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -495,6 +495,33 @@
static void readd_wb_executed_flags(void);
static void check_all_write_barrier_flags(char *segbase, struct list_s *list);
+static void wait_for_inevitable(void)
+{
+ intptr_t detached = 0;
+
+ s_mutex_lock();
+ if (safe_point_requested()) {
+ /* XXXXXX if the safe point below aborts, in
+ _validate_and_attach(), 'new' leaks */
+ enter_safe_point_if_requested();
+ }
+ else if (STM_PSEGMENT->last_commit_log_entry->next == INEV_RUNNING) {
+ /* loop until C_SEGMENT_FREE_OR_SAFE_POINT_REQ is signalled, but
+ try to detach an inevitable transaction regularly */
+ while (1) {
+ detached = fetch_detached_transaction();
+ if (detached != 0)
+ break;
+ if (cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ, 0.00001))
+ break;
+ }
+ }
+ s_mutex_unlock();
+
+ if (detached != 0)
+ commit_fetched_detached_transaction(detached);
+}
+
/* This is called to do stm_validate() and then attach 'new' at the
head of the 'commit_log_root' chained list. This function sleeps
and retries until it succeeds or aborts.
@@ -523,24 +550,10 @@
#endif
if (STM_PSEGMENT->last_commit_log_entry->next == INEV_RUNNING) {
- s_mutex_lock();
- if (safe_point_requested()) {
- /* XXXXXX if the safe point below aborts, 'new' leaks */
- enter_safe_point_if_requested();
- }
- else if (STM_PSEGMENT->last_commit_log_entry->next == INEV_RUNNING) {
- cond_wait(C_SEGMENT_FREE_OR_SAFE_POINT_REQ);
- }
- s_mutex_unlock();
+ wait_for_inevitable();
goto retry_from_start; /* redo _stm_validate() now */
}
- intptr_t detached = fetch_detached_transaction();
- if (detached != 0) {
- commit_fetched_detached_transaction(detached);
- goto retry_from_start;
- }
-
/* we must not remove the WB_EXECUTED flags before validation as
it is part of a condition in import_objects() called by
copy_bk_objs_in_page_from to not overwrite our modifications.
@@ -1564,12 +1577,31 @@
timing_become_inevitable(); /* for tests: another transaction */
stm_abort_transaction(); /* is already inevitable, abort */
#endif
+
+ intptr_t detached = 0;
+
s_mutex_lock();
if (any_soon_finished_or_inevitable_thread_segment() &&
!safe_point_requested()) {
- cond_wait(C_SEGMENT_FREE_OR_SAFE_POINT_REQ);
+
+ /* wait until C_SEGMENT_FREE_OR_SAFE_POINT_REQ is signalled */
+ while (!cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ,
+ 0.000054321)) {
+ /* try to detach another inevitable transaction, but
+ only after waiting a bit. This is necessary to avoid
+ deadlocks in some situations, which are hopefully
+ not too common. We don't want two threads constantly
+ detaching each other. */
+ detached = fetch_detached_transaction();
+ if (detached != 0)
+ break;
+ }
}
s_mutex_unlock();
+
+ if (detached != 0)
+ commit_fetched_detached_transaction(detached);
+
num_waits++;
goto retry_from_start;
}
More information about the pypy-commit
mailing list