Author: Tobias Weber <tobias_webe...@gmx.de> Branch: c8-fix-starvation Changeset: r2097:c9b8371e72df Date: 2017-07-10 17:11 +0200 http://bitbucket.org/pypy/stmgc/changeset/c9b8371e72df/
Log: Fetch detached trx more often during wait to become inevitable diff --git a/c8/stm/core.c b/c8/stm/core.c --- a/c8/stm/core.c +++ b/c8/stm/core.c @@ -1571,7 +1571,7 @@ void _stm_become_inevitable(const char *msg) { - int num_waits = 0; + int num_waits = 1; timing_become_inevitable(); @@ -1582,42 +1582,42 @@ if (msg != MSG_INEV_DONT_SLEEP) { dprintf(("become_inevitable: %s\n", msg)); - if (any_soon_finished_or_inevitable_thread_segment() && - num_waits <= NB_SEGMENTS) { + if (any_soon_finished_or_inevitable_thread_segment()) { #if STM_TESTS /* for tests: another transaction */ stm_abort_transaction(); /* is already inevitable, abort */ #endif + signal_commit_to_inevitable_transaction(); + s_mutex_lock(); if (any_soon_finished_or_inevitable_thread_segment() && - !safe_point_requested()) { - - signal_commit_to_inevitable_transaction(); + !safe_point_requested() && + num_waits <= NB_SEGMENTS) { /* wait until C_SEGMENT_FREE_OR_SAFE_POINT_REQ is signalled */ EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE); - if (!cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ, 0.00001)) { - s_mutex_unlock(); - /* 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. */ - intptr_t detached = fetch_detached_transaction(); - if (detached != 0) { - EMIT_WAIT_DONE(); - commit_fetched_detached_transaction(detached); - } - goto retry_from_start; + if (cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ, 0.00001)) { + num_waits++; } - num_waits++; } s_mutex_unlock(); + /* XXX 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. */ + intptr_t detached = fetch_detached_transaction(); + if (detached != 0) { + EMIT_WAIT_DONE(); + commit_fetched_detached_transaction(detached); + EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE); + } goto retry_from_start; } else { EMIT_WAIT_DONE(); if (!_validate_and_turn_inevitable()) { + EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE); goto retry_from_start; } } diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c --- a/c8/stm/nursery.c +++ b/c8/stm/nursery.c @@ -501,7 +501,7 @@ pseg->pub.nursery_mark -= nursery_used; if (pseg->commit_if_not_atomic - // && pseg->transaction_state == TS_INEVITABLE // TODO why does this break the mechanism? + // && pseg->transaction_state == TS_INEVITABLE // TODO why does this break the mechanism? && pseg->pub.running_thread->self_or_0_if_atomic != 0) { // transaction is inevitable, not atomic, and commit has been signalled by waiting thread: commit immediately pseg->pub.nursery_mark = 0; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit