Author: Remi Meier <meier...@student.ethz.ch> Branch: Changeset: r328:6eac0903bcb9 Date: 2013-07-01 12:32 +0200 http://bitbucket.org/pypy/stmgc/changeset/6eac0903bcb9/
Log: add atomic transactions in demo_random diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -60,6 +60,7 @@ int num_roots_outside_perform; int steps_left; int interruptible; + int atomic; }; __thread struct thread_data td; @@ -74,6 +75,24 @@ (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED); } +static void inc_atomic() +{ + assert(td.interruptible); + assert(stm_atomic(0) == td.atomic); + td.atomic++; + stm_atomic(1); + assert(stm_atomic(0) == td.atomic); +} + +static void dec_atomic() +{ + assert(td.interruptible); + assert(stm_atomic(0) == td.atomic); + td.atomic--; + stm_atomic(-1); + assert(stm_atomic(0) == td.atomic); +} + int get_rand(int max) { return (int)(rand_r(&td.thread_seed) % (unsigned int)max); @@ -254,7 +273,8 @@ td.thread_seed = default_seed++; td.steps_left = STEPS_PER_THREAD; td.interruptible = 0; - + td.atomic = 0; + td.num_roots = PREBUILT + NUMROOTS; for (i = 0; i < PREBUILT; i++) { if (i % 3 == 0) { @@ -303,7 +323,7 @@ gcptr simple_events(gcptr p, gcptr _r, gcptr _sr) { nodeptr w_r; - int k = get_rand(8); + int k = get_rand(11); int num = get_rand(td.num_roots); switch (k) { case 0: // remove a root @@ -338,6 +358,18 @@ check(p); w_r->next = (struct node*)p; break; + case 8: + if (td.interruptible) { + inc_atomic(); + } + break; + case 9: + case 10: + /* more likely to be less atomic */ + if (td.atomic) { + dec_atomic(); + } + break; } return p; } @@ -469,7 +501,7 @@ td.num_roots = td.num_roots_outside_perform; // done & overwritten by the following pop_roots(): // copy_roots(td.roots_outside_perform, td.roots, td.num_roots); - + td.atomic = 0; // may be set differently on abort // refresh td.roots: gcptr end_marker = stm_pop_root(); assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF); @@ -490,14 +522,26 @@ int run_me() { gcptr p = NULL; - while (td.steps_left-->0) { + while (td.steps_left-->0 || td.atomic) { if (td.steps_left % 8 == 0) fprintf(stdout, "#"); p = do_step(p); - if (p == (gcptr)-1) - return -1; + if (p == (gcptr)-1) { + if (td.atomic) { + // can't break, well, we could return to perform_transaction + // while being atomic. (TODO) + // may be true when major gc requested: + // assert(stm_should_break_transaction() == 0); + assert(stm_atomic(0) == td.atomic); + p = NULL; + } + else { + assert(stm_atomic(0) == 0); + return -1; + } + } } return 0; } diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -906,6 +906,8 @@ long stm_atomic(long delta) { struct tx_descriptor *d = thread_descriptor; + if (delta) // no atomic-checks + dprintf(("stm_atomic(%lu)\n", delta)); d->atomic += delta; assert(d->atomic >= 0); update_reads_size_limit(d); diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -198,9 +198,6 @@ return (revision_t)p; } - /* XXX: think about if p->h_original needs a volatile read - and if we need a memory fence (smp_wmb())... */ - spinlock_acquire(d->public_descriptor->collection_lock, 'I'); /* old objects must have an h_original xOR be the original itself. @@ -222,7 +219,6 @@ gcptr O = stmgc_duplicate_old(p); p->h_original = (revision_t)O; p->h_tid |= GCFLAG_HAS_ID; - O->h_tid |= GCFLAG_PUBLIC; if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)p->h_revision; _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit