Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r236:531e5789c7dd Date: 2013-06-22 15:57 +0200 http://bitbucket.org/pypy/stmgc/changeset/531e5789c7dd/
Log: After a major GC, make sure the other threads abort if the major GC found that they should. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -59,16 +59,23 @@ static pthread_mutex_t mutex_inevitable = PTHREAD_MUTEX_INITIALIZER; -static void inev_mutex_acquire(void) +static void inev_mutex_release(void) +{ + pthread_mutex_unlock(&mutex_inevitable); +} + +static void inev_mutex_acquire(struct tx_descriptor *d) { /* must save roots around this call */ stm_stop_sharedlock(); pthread_mutex_lock(&mutex_inevitable); stm_start_sharedlock(); -} -static void inev_mutex_release(void) -{ - pthread_mutex_unlock(&mutex_inevitable); + if (d->active < 0) + { + inev_mutex_release(); + AbortNowIfDelayed(); + abort(); /* unreachable */ + } } /************************************************************/ @@ -882,6 +889,7 @@ { assert(d->active == 0); stm_start_sharedlock(); + assert(d->active == 0); if (clock_gettime(CLOCK_MONOTONIC, &d->start_real_time) < 0) { d->start_real_time.tv_nsec = -1; @@ -1225,7 +1233,7 @@ { // there is another inevitable transaction CancelLocks(d); spinlock_release(d->public_descriptor->collection_lock); - inev_mutex_acquire(); // wait until released + inev_mutex_acquire(d); // wait until released inev_mutex_release(); spinlock_acquire(d->public_descriptor->collection_lock, 'C'); if (d->public_descriptor->stolen_objects.size != 0) @@ -1284,11 +1292,12 @@ update_reads_size_limit(d); } -static revision_t acquire_inev_mutex_and_mark_global_cur_time(void) +static revision_t acquire_inev_mutex_and_mark_global_cur_time( + struct tx_descriptor *d) { /* must save roots around this call */ revision_t cur_time; - inev_mutex_acquire(); + inev_mutex_acquire(d); while (1) { cur_time = ACCESS_ONCE(global_cur_time); @@ -1312,7 +1321,7 @@ fprintf(stderr, "[%lx] inevitable: %s\n", (long)d->public_descriptor_index, why); - cur_time = acquire_inev_mutex_and_mark_global_cur_time(); + cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); if (d->start_time != cur_time) { d->start_time = cur_time; @@ -1332,7 +1341,7 @@ revision_t cur_time; init_transaction(d); - cur_time = acquire_inev_mutex_and_mark_global_cur_time(); + cur_time = acquire_inev_mutex_and_mark_global_cur_time(d); d->start_time = cur_time; make_inevitable(d); } diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -378,8 +378,8 @@ if (IS_POINTER(v)) { /* has a more recent revision. Oups. */ fprintf(stderr, - "ABRT_COLLECT_MAJOR: %p was read but modified already\n", - obj); + "ABRT_COLLECT_MAJOR %p: %p was read but modified already\n", + d, obj); AbortTransactionAfterCollect(d, ABRT_COLLECT_MAJOR); return; } @@ -410,6 +410,8 @@ */ wlog_t *item; + fprintf(stderr, "fix public_to_private on thread %p\n", d); + G2L_LOOP_FORWARD(d->public_to_private, item) { assert(item->addr->h_tid & GCFLAG_PUBLIC); @@ -419,6 +421,7 @@ (item->val->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)); item->addr->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE; + fprintf(stderr, "\tpublic_to_private: %p\n", item->addr); } G2L_LOOP_END; diff --git a/c4/stmsync.c b/c4/stmsync.c --- a/c4/stmsync.c +++ b/c4/stmsync.c @@ -293,6 +293,8 @@ /* another thread should be waiting in start_exclusivelock(), which takes priority here */ stm_start_sharedlock(); + + AbortNowIfDelayed(); /* if another thread ran a major GC */ } /************************************************************/ diff --git a/c4/test/support.py b/c4/test/support.py --- a/c4/test/support.py +++ b/c4/test/support.py @@ -73,6 +73,7 @@ void stm_start_sharedlock(void); void stm_stop_sharedlock(void); void AbortTransaction(int); + void AbortNowIfDelayed(void); gcptr stm_get_private_from_protected(long index); gcptr stm_get_read_obj(long index); void *STUB_THREAD(gcptr); @@ -416,6 +417,7 @@ lib.stm_stop_sharedlock() self.parallel_locks[1].acquire() lib.stm_start_sharedlock() + lib.AbortNowIfDelayed() print 'wait_while_in_parallel leave' # parallel_locks[0] is acquired, parallel_locks[1] is acquired self.parallel_locks[1].release() @@ -500,9 +502,9 @@ return p.h_tid & GCFLAG_STUB def check_not_free(p): - print >> sys.stderr, "[checking %r..." % p, + #print >> sys.stderr, "[checking %r..." % p, assert 42 < (p.h_tid & 0xFFFF) < 521 - print >> sys.stderr, "ok]" + #print >> sys.stderr, "ok]" def check_nursery_free(p): #assert p.h_tid == p.h_revision == 0 diff --git a/c4/test/test_random.py b/c4/test/test_random.py --- a/c4/test/test_random.py +++ b/c4/test/test_random.py @@ -5,7 +5,7 @@ # a default seed that changes every day, but that can be easily recovered DEFAULT_SEED = int(time.strftime("%y%m%d", time.gmtime())) -DO_MAJOR_COLLECTS = False +DO_MAJOR_COLLECTS = True def setup_function(_): @@ -452,6 +452,7 @@ self.toggle = not threadid self.cond.notify() lib.stm_start_sharedlock() + lib.AbortNowIfDelayed() def wait1(self): self.wait(False) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit