Author: Remi Meier <remi.me...@gmail.com> Branch: c7 Changeset: r628:1030cba5f19d Date: 2014-01-17 15:49 +0100 http://bitbucket.org/pypy/stmgc/changeset/1030cba5f19d/
Log: fix race condition in abort diff --git a/c7/core.c b/c7/core.c --- a/c7/core.c +++ b/c7/core.c @@ -87,7 +87,7 @@ static uintptr_t index_page_never_used; static struct stm_list_s *volatile pending_updates; static uint8_t flag_page_private[NB_PAGES]; /* xxx_PAGE constants above */ - +static uint8_t write_locks[READMARKER_END - READMARKER_START]; /************************************************************/ uintptr_t _stm_reserve_page(void); @@ -318,23 +318,23 @@ static void push_modified_to_other_threads() { + /* WE HAVE THE EXCLUSIVE LOCK HERE */ + struct stm_list_s *modified = _STM_TL2->modified_objects; char *local_base = _STM_TL2->thread_base; char *remote_base = get_thread_base(1 - _STM_TL2->thread_num); bool conflicted = 0; - char *t0_base = get_thread_base(0); STM_LIST_FOREACH( modified, ({ if (!conflicted) conflicted = _stm_was_read_remote(remote_base, item); - + /* clear the write-lock */ - struct object_s *t0_obj = (struct object_s*) - REAL_ADDRESS(t0_base, item); - assert(t0_obj->stm_write_lock); - t0_obj->stm_write_lock = 0; + uintptr_t lock_idx = (((uintptr_t)item) >> 4) - READMARKER_START; + assert(write_locks[lock_idx]); + write_locks[lock_idx] = 0; char *src = REAL_ADDRESS(local_base, item); char *dst = REAL_ADDRESS(remote_base, item); @@ -377,13 +377,10 @@ /* privatize if SHARED_PAGE */ _stm_privatize(pagenum); - /* lock the object for writing in thread 0's page */ - uintptr_t t0_offset = (uintptr_t)obj; - char* t0_addr = get_thread_base(0) + t0_offset; - struct object_s *t0_obj = (struct object_s *)t0_addr; - - int previous; - while ((previous = __sync_lock_test_and_set(&t0_obj->stm_write_lock, 1))) { + /* claim the write-lock for this object */ + uintptr_t lock_idx = (((uintptr_t)obj) >> 4) - READMARKER_START; + uint8_t previous; + while ((previous = __sync_lock_test_and_set(&write_locks[lock_idx], 1))) { stm_abort_transaction(); /* XXX: only abort if we are younger */ spin_loop(); @@ -710,6 +707,7 @@ { munmap(object_pages, TOTAL_MEMORY); memset(flag_page_private, 0, sizeof(flag_page_private)); + memset(write_locks, 0, sizeof(write_locks)); pthread_rwlock_destroy(&rwlock_shared); object_pages = NULL; } @@ -924,32 +922,30 @@ struct stm_list_s *modified = _STM_TL2->modified_objects; char *local_base = _STM_TL2->thread_base; char *remote_base = get_thread_base(1 - _STM_TL2->thread_num); - char *t0_base = get_thread_base(0); STM_LIST_FOREACH( modified, ({ /* note: same as push_modified_to... but src/dst swapped XXX: unify both... */ + char *dst = REAL_ADDRESS(local_base, item); char *src = REAL_ADDRESS(remote_base, item); size_t size = stmcb_size((struct object_s*)src); memcpy(dst, src, size); - + /* copying from the other thread re-added the WRITE_BARRIER flag */ assert(item->stm_flags & GCFLAG_WRITE_BARRIER); + + /* write all changes to the object before we release the + write lock below */ + write_fence(); - struct object_s *t0_obj = (struct object_s*) - REAL_ADDRESS(t0_base, item); - if (t0_base != local_base) { - /* clear the write-lock (WE have modified the obj) */ - assert(t0_obj->stm_write_lock); - t0_obj->stm_write_lock = 0; - } else { - /* done by the memcpy */ - assert(!t0_obj->stm_write_lock); - } + /* clear the write-lock */ + uintptr_t lock_idx = (((uintptr_t)item) >> 4) - READMARKER_START; + assert(write_locks[lock_idx]); + write_locks[lock_idx] = 0; })); } diff --git a/c7/test/support.py b/c7/test/support.py --- a/c7/test/support.py +++ b/c7/test/support.py @@ -335,6 +335,6 @@ stm_start_safe_point() lib._stm_restore_local_state(thread_num) if lib._stm_is_in_transaction(): - stm_stop_safe_point() + stm_stop_safe_point() # can raise Conflict _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit