Author: Tobias Weber <tobias_webe...@gmx.de> Branch: c8-adaptive-trx-length-per-thread Changeset: r2089:136efd31d83f Date: 2017-06-30 21:53 +0200 http://bitbucket.org/pypy/stmgc/changeset/136efd31d83f/
Log: Merge fix for inevitable transaction commit signalling diff --git a/c8/stm/core.c b/c8/stm/core.c --- a/c8/stm/core.c +++ b/c8/stm/core.c @@ -385,6 +385,14 @@ static void readd_wb_executed_flags(void); static void check_all_write_barrier_flags(char *segbase, struct list_s *list); +static void signal_commit_to_inevitable_transaction(void) { + struct stm_priv_segment_info_s* inevitable_segement = get_inevitable_thread_segment(); + if (inevitable_segement != 0) { + // the inevitable thread is still running: set its "please commit" flag (is ignored by the inevitable thread if it is atomic) + inevitable_segement->commit_if_not_atomic = true; + } +} + static void wait_for_inevitable(void) { intptr_t detached = 0; @@ -401,6 +409,8 @@ try to detach an inevitable transaction regularly */ detached = fetch_detached_transaction(); if (detached == 0) { + // the inevitable trx was not detached or it was detached but is atomic + signal_commit_to_inevitable_transaction(); EMIT_WAIT(STM_WAIT_OTHER_INEVITABLE); if (!cond_wait_timeout(C_SEGMENT_FREE_OR_SAFE_POINT_REQ, 0.00001)) goto wait_some_more; @@ -1694,6 +1704,7 @@ stm_spin_loop(); assert(_stm_detached_inevitable_from_thread == 0); + STM_PSEGMENT->commit_if_not_atomic = false; soon_finished_or_inevitable_thread_segment(); STM_PSEGMENT->transaction_state = TS_INEVITABLE; diff --git a/c8/stm/core.h b/c8/stm/core.h --- a/c8/stm/core.h +++ b/c8/stm/core.h @@ -169,6 +169,9 @@ /* For stm_enable_atomic() */ uintptr_t atomic_nesting_levels; + + // TODO signal flag that is checked in throw_away_nursery() for making immediate commit + bool commit_if_not_atomic; }; enum /* safe_point */ { diff --git a/c8/stm/detach.c b/c8/stm/detach.c --- a/c8/stm/detach.c +++ b/c8/stm/detach.c @@ -215,6 +215,7 @@ } } +// TODO write tests, verify is working, verify no overflows with adaptive mode uintptr_t stm_is_atomic(stm_thread_local_t *tl) { assert(STM_SEGMENT->running_thread == tl); diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c --- a/c8/stm/nursery.c +++ b/c8/stm/nursery.c @@ -542,6 +542,11 @@ pseg->pub.nursery_current = (stm_char *)_stm_nursery_start; pseg->pub.nursery_mark -= nursery_used; + if (pseg->commit_if_not_atomic && pseg->pub.running_thread->self_or_0_if_atomic != 0) { + // not atomic and commit signalled by waiting thread: commit immediately + pseg->pub.nursery_mark = 0; + } + /* free any object left from 'young_outside_nursery' */ if (!tree_is_cleared(pseg->young_outside_nursery)) { wlog_t *item; diff --git a/c8/stm/sync.c b/c8/stm/sync.c --- a/c8/stm/sync.c +++ b/c8/stm/sync.c @@ -302,6 +302,19 @@ return false; } +static struct stm_priv_segment_info_s* get_inevitable_thread_segment(void) +{ + struct stm_priv_segment_info_s* segment; + int num; + for (num = 1; num < NB_SEGMENTS; num++) { + segment = get_priv_segment(num); + if (segment->transaction_state == TS_INEVITABLE) { + return segment; + } + } + return 0; +} + __attribute__((unused)) static bool _seems_to_be_running_transaction(void) { diff --git a/c8/stm/sync.h b/c8/stm/sync.h --- a/c8/stm/sync.h +++ b/c8/stm/sync.h @@ -30,6 +30,7 @@ static void release_thread_segment(stm_thread_local_t *tl); static void soon_finished_or_inevitable_thread_segment(void); static bool any_soon_finished_or_inevitable_thread_segment(void); +static struct stm_priv_segment_info_s* get_inevitable_thread_segment(void); enum sync_type_e { STOP_OTHERS_UNTIL_MUTEX_UNLOCK, _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit