Author: Armin Rigo <ar...@tunes.org> Branch: stm-gc Changeset: r52355:a8cf7f197ec1 Date: 2012-02-10 16:10 +0100 http://bitbucket.org/pypy/pypy/changeset/a8cf7f197ec1/
Log: Replace in_main_thread() with in_transaction(). diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py --- a/pypy/rpython/memory/gc/stmgc.py +++ b/pypy/rpython/memory/gc/stmgc.py @@ -297,7 +297,7 @@ # @dont_inline def _stm_write_barrier_global(obj): - if stm_operations.in_main_thread(): + if not stm_operations.in_transaction(): return obj # we need to find of make a local copy hdr = self.header(obj) diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py --- a/pypy/rpython/memory/gc/test/test_stmgc.py +++ b/pypy/rpython/memory/gc/test/test_stmgc.py @@ -26,8 +26,8 @@ def setup_size_getter(self, getsize_fn): self._getsize_fn = getsize_fn - def in_main_thread(self): - return self.threadnum == 0 + def in_transaction(self): + return self.threadnum != 0 def set_tls(self, tls, in_main_thread): assert lltype.typeOf(tls) == llmemory.Address @@ -149,6 +149,7 @@ self.gc.stm_operations.threadnum = threadnum if threadnum not in self.gc.stm_operations._tls_dict: self.gc.setup_thread(False) + self.gc.start_transaction() def gcsize(self, S): return (llmemory.raw_malloc_usage(llmemory.sizeof(self.gc.HDR)) + llmemory.raw_malloc_usage(llmemory.sizeof(S))) diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c --- a/pypy/translator/stm/src_stm/et.c +++ b/pypy/translator/stm/src_stm/et.c @@ -81,6 +81,7 @@ if there is an inevitable transaction running */ static volatile unsigned long global_timestamp = 2; static __thread struct tx_descriptor *thread_descriptor = NULL; +static __thread struct tx_descriptor *active_thread_descriptor = NULL; static long (*rpython_get_size)(void*); /************************************************************/ @@ -114,7 +115,7 @@ { unsigned int c; int i; - struct tx_descriptor *d = thread_descriptor; + struct tx_descriptor *d = active_thread_descriptor; d->num_spinloops[num]++; //printf("tx_spinloop(%d)\n", num); @@ -132,11 +133,6 @@ #endif } -static _Bool is_main_thread(struct tx_descriptor *d) -{ - return d->my_lock_word == 0; -} - static _Bool is_inevitable(struct tx_descriptor *d) { return d->setjmp_buf == NULL; @@ -268,7 +264,7 @@ /*** increase the abort count and restart the transaction */ static void tx_abort(int reason) { - struct tx_descriptor *d = thread_descriptor; + struct tx_descriptor *d = active_thread_descriptor; assert(!is_inevitable(d)); d->num_aborts[reason]++; #ifdef RPY_STM_DEBUG_PRINT @@ -459,12 +455,16 @@ #define STM_READ_WORD(SIZE, TYPE) \ TYPE stm_read_int##SIZE(void* addr, long offset) \ { \ - struct tx_descriptor *d = thread_descriptor; \ + struct tx_descriptor *d = active_thread_descriptor; \ volatile orec_t *o = get_orec(addr); \ owner_version_t ovt; \ \ assert(sizeof(TYPE) == SIZE); \ \ + /* XXX try to remove this check from the main path */ \ + if (d == NULL) \ + return *(TYPE *)(((char *)addr) + offset); \ + \ if ((o->tid & GCFLAG_WAS_COPIED) != 0) \ { \ /* Look up in the thread-local dictionary. */ \ @@ -477,10 +477,6 @@ not_found:; \ } \ \ - /* XXX try to remove this check from the main path */ \ - if (is_main_thread(d)) \ - return *(TYPE *)(((char *)addr) + offset); \ - \ STM_DO_READ(TYPE tmp = *(TYPE *)(((char *)addr) + offset)); \ return tmp; \ } @@ -492,11 +488,11 @@ void stm_copy_transactional_to_raw(void *src, void *dst, long size) { - struct tx_descriptor *d = thread_descriptor; + struct tx_descriptor *d = active_thread_descriptor; volatile orec_t *o = get_orec(src); owner_version_t ovt; - assert(!is_main_thread(d)); + assert(d != NULL); /* don't copy the header */ src = ((char *)src) + sizeof(orec_t); @@ -507,9 +503,10 @@ } -static struct tx_descriptor *descriptor_init(_Bool is_main_thread) +static struct tx_descriptor *descriptor_init() { assert(thread_descriptor == NULL); + assert(active_thread_descriptor == NULL); if (1) /* for hg diff */ { struct tx_descriptor *d = malloc(sizeof(struct tx_descriptor)); @@ -519,21 +516,15 @@ PYPY_DEBUG_START("stm-init"); #endif - if (is_main_thread) - { - d->my_lock_word = 0; - } - else - { - /* initialize 'my_lock_word' to be a unique negative number */ - d->my_lock_word = (owner_version_t)d; - if (!IS_LOCKED(d->my_lock_word)) - d->my_lock_word = ~d->my_lock_word; - assert(IS_LOCKED(d->my_lock_word)); - } + /* initialize 'my_lock_word' to be a unique negative number */ + d->my_lock_word = (owner_version_t)d; + if (!IS_LOCKED(d->my_lock_word)) + d->my_lock_word = ~d->my_lock_word; + assert(IS_LOCKED(d->my_lock_word)); /*d->spinloop_counter = (unsigned int)(d->my_lock_word | 1);*/ thread_descriptor = d; + /* active_thread_descriptor stays NULL */ #ifdef RPY_STM_DEBUG_PRINT if (PYPY_HAVE_DEBUG_PRINTS) fprintf(PYPY_DEBUG_FILE, "thread %lx starting\n", @@ -548,6 +539,7 @@ { struct tx_descriptor *d = thread_descriptor; assert(d != NULL); + assert(active_thread_descriptor == NULL); thread_descriptor = NULL; @@ -593,12 +585,13 @@ assert(d != NULL); d->setjmp_buf = buf; d->start_time = (/*d->last_known_global_timestamp*/ global_timestamp) & ~1; + active_thread_descriptor = d; } static long commit_transaction(void) { - struct tx_descriptor *d = thread_descriptor; - assert(!is_main_thread(d)); + struct tx_descriptor *d = active_thread_descriptor; + assert(d != NULL); // if I don't have writes, I'm committed if (!redolog_any_entry(&d->redolog)) @@ -612,6 +605,7 @@ } d->num_commits++; common_cleanup(d); + active_thread_descriptor = NULL; return d->start_time; } @@ -657,6 +651,7 @@ // reset all lists common_cleanup(d); + active_thread_descriptor = NULL; return d->end_time; } @@ -666,6 +661,7 @@ jmp_buf _jmpbuf; volatile long v_counter = 0; long counter; + assert(active_thread_descriptor == NULL); setjmp(_jmpbuf); begin_transaction(&_jmpbuf); counter = v_counter; @@ -681,8 +677,8 @@ global_timestamp and global_timestamp cannot be incremented by another thread. We set the lowest bit in global_timestamp to 1. */ - struct tx_descriptor *d = thread_descriptor; - if (d == NULL || is_main_thread(d)) + struct tx_descriptor *d = active_thread_descriptor; + if (d == NULL) return; #ifdef RPY_STM_DEBUG_PRINT @@ -742,7 +738,10 @@ { struct tx_descriptor *d = thread_descriptor; if (d == NULL) + return -1; + if (active_thread_descriptor == NULL) return 0; + assert(d == active_thread_descriptor); if (!is_inevitable(d)) return 1; else @@ -756,9 +755,10 @@ } -void stm_set_tls(void *newtls, long is_main_thread) +void stm_set_tls(void *newtls, long in_main_thread) { - struct tx_descriptor *d = descriptor_init(is_main_thread); + /* 'in_main_thread' is ignored so far */ + struct tx_descriptor *d = descriptor_init(); d->rpython_tls_object = newtls; } @@ -785,7 +785,8 @@ void stm_tldict_add(void *key, void *value) { - struct tx_descriptor *d = thread_descriptor; + struct tx_descriptor *d = active_thread_descriptor; + assert(d != NULL); redolog_insert(&d->redolog, key, value); } @@ -806,10 +807,25 @@ rpython_get_size = getsize_fn; } -long stm_in_main_thread(void) +long stm_in_transaction(void) { - struct tx_descriptor *d = thread_descriptor; - return is_main_thread(d); + struct tx_descriptor *d = active_thread_descriptor; + return d != NULL; +} + +void _stm_activate_transaction(long activate) +{ + assert(thread_descriptor != NULL); + if (activate) + { + assert(active_thread_descriptor == NULL); + active_thread_descriptor = thread_descriptor; + } + else + { + assert(active_thread_descriptor != NULL); + active_thread_descriptor = NULL; + } } #endif /* PYPY_NOT_MAIN_FILE */ diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h --- a/pypy/translator/stm/src_stm/et.h +++ b/pypy/translator/stm/src_stm/et.h @@ -46,6 +46,8 @@ 2: in an inevitable transaction */ long stm_thread_id(void); /* returns a unique thread id, or 0 if descriptor_init() was not called */ +long stm_in_transaction(void); +void _stm_activate_transaction(long); /************************************************************/ diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py --- a/pypy/translator/stm/stmgcintf.py +++ b/pypy/translator/stm/stmgcintf.py @@ -15,7 +15,9 @@ setup_size_getter = smexternal('stm_setup_size_getter', [GETSIZE], lltype.Void) - in_main_thread = smexternal('stm_in_main_thread', [], lltype.Signed) + in_transaction = smexternal('stm_in_transaction', [], lltype.Signed) + _activate_transaction = smexternal('_stm_activate_transaction', + [lltype.Signed], lltype.Void) set_tls = smexternal('stm_set_tls', [llmemory.Address, lltype.Signed], lltype.Void) diff --git a/pypy/translator/stm/test/targetdemo.py b/pypy/translator/stm/test/targetdemo.py --- a/pypy/translator/stm/test/targetdemo.py +++ b/pypy/translator/stm/test/targetdemo.py @@ -14,6 +14,7 @@ LENGTH = 5000 USE_MEMORY = False anchor = Node(-1) + lock = ll_thread.allocate_ll_lock() glob = Global() class Arg: diff --git a/pypy/translator/stm/test/test_stmgcintf.py b/pypy/translator/stm/test/test_stmgcintf.py --- a/pypy/translator/stm/test/test_stmgcintf.py +++ b/pypy/translator/stm/test/test_stmgcintf.py @@ -30,16 +30,23 @@ class TestStmGcIntf: + _in_transaction = False def setup_method(self, meth): TLS = getattr(meth, 'TLS', DEFAULT_TLS) s = lltype.malloc(TLS, flavor='raw', immortal=True) self.tls = s a = llmemory.cast_ptr_to_adr(s) - in_main_thread = getattr(meth, 'in_main_thread', True) + in_transaction = getattr(meth, 'in_transaction', False) + in_main_thread = getattr(meth, 'in_main_thread', not in_transaction) stm_operations.set_tls(a, int(in_main_thread)) + if in_transaction: + stm_operations._activate_transaction(1) + self._in_transaction = True def teardown_method(self, meth): + if self._in_transaction: + stm_operations._activate_transaction(0) stm_operations.del_tls() def test_set_get_del(self): @@ -60,6 +67,7 @@ stm_operations.tldict_add(a3, a4) assert stm_operations.tldict_lookup(a3) == a4 assert stm_operations.tldict_lookup(a1) == a2 + test_tldict.in_transaction = True def test_tldict_large(self): content = {} @@ -74,7 +82,7 @@ a2 = rffi.cast(llmemory.Address, random.randrange(2000, 9999)) stm_operations.tldict_add(a1, a2) content[key] = a2 - return content + test_tldict_large.in_transaction = True def get_callback(self): def callback(tls, key, value): @@ -101,6 +109,7 @@ stm_operations.tldict_enum(p_callback) assert (seen == [(a1, a2), (a3, a4)] or seen == [(a3, a4), (a1, a2)]) + test_enum_tldict_nonempty.in_transaction = True def stm_read_case(self, flags, copied=False): # doesn't test STM behavior, but just that it appears to work @@ -136,7 +145,7 @@ assert res == 42042 res = self.stm_read_case(stmgc.GCFLAG_WAS_COPIED, copied=True) assert res == 84084 - test_stm_read_word_transactional_thread.in_main_thread = False + test_stm_read_word_transactional_thread.in_transaction = True def test_stm_read_int1(self): S2 = lltype.Struct('S2', ('hdr', stmgc.StmGC.HDR), @@ -186,11 +195,16 @@ # lltype.free(s2, flavor='raw') lltype.free(s1, flavor='raw') - test_stm_copy_transactional_to_raw.in_main_thread = False + test_stm_copy_transactional_to_raw.in_transaction = True - def test_in_main_thread(self): - assert stm_operations.in_main_thread() + def test_in_transaction(self): + assert stm_operations.in_transaction() + test_in_transaction.in_transaction = True - def test_not_in_main_thread(self): - assert not stm_operations.in_main_thread() - test_not_in_main_thread.in_main_thread = False + def test_not_in_transaction(self): + assert not stm_operations.in_transaction() + test_not_in_transaction.in_main_thread = False + + def test_not_in_transaction_main(self): + assert not stm_operations.in_transaction() + test_not_in_transaction.in_main_thread = True _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit