Author: Remi Meier <meier...@student.ethz.ch> Branch: Changeset: r387:9c2b50efb633 Date: 2013-07-11 10:13 +0200 http://bitbucket.org/pypy/stmgc/changeset/9c2b50efb633/
Log: add cache of writeables to demo_random.c and fix a bug diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -52,6 +52,12 @@ // global and per-thread-data time_t default_seed; gcptr shared_roots[SHARED_ROOTS]; + +#define CACHE_MASK 65535 +#define CACHE_ENTRIES ((CACHE_MASK + 1) / sizeof(char *)) +#define CACHE_AT(cache, obj) (*(gcptr *)((char *)(cache) \ + + ((revision_t)(obj) & CACHE_MASK))) + struct thread_data { unsigned int thread_seed; gcptr roots[MAXROOTS]; @@ -61,6 +67,7 @@ int steps_left; int interruptible; int atomic; + revision_t writeable[CACHE_ENTRIES]; }; __thread struct thread_data td; @@ -140,6 +147,7 @@ } } +__thread revision_t temp_cache[CACHE_ENTRIES]; void pop_roots() { int i; @@ -148,6 +156,8 @@ td.roots[i] = stm_pop_root(); check(td.roots[i]); } + /* some objects may have changed positions */ + memset(td.writeable, 0, sizeof(td.writeable)); } void del_root(int idx) @@ -227,6 +237,7 @@ if (p != NULL) { check(p); w = stm_write_barrier(p); + CACHE_AT(td.writeable, w) = w; check(w); assert(is_private(w)); } @@ -298,6 +309,8 @@ void setup_thread() { int i; + memset(&td, 0, sizeof(struct thread_data)); + td.thread_seed = default_seed++; td.steps_left = STEPS_PER_THREAD; td.interruptible = 0; @@ -395,7 +408,10 @@ break; case 7: // set 'p' as *next in one of the roots check(_r); - w_r = (nodeptr)write_barrier(_r); + if (CACHE_AT(td.writeable, _r) == _r) + w_r = (nodeptr)_r; + else + w_r = (nodeptr)write_barrier(_r); check((gcptr)w_r); check(p); w_r->next = (struct node*)p; @@ -454,7 +470,10 @@ assert(w_t->id == stm_id((gcptr)_t)); } else { - w_t = (nodeptr)write_barrier(_t); + if (CACHE_AT(td.writeable, _t) == _t) + w_t = (nodeptr)_t; + else + w_t = (nodeptr)write_barrier(_t); w_t->id = stm_id((gcptr)w_t); assert(w_t->id == stm_id((gcptr)_t)); } @@ -470,7 +489,10 @@ assert(w_t->hash == stm_hash((gcptr)_t)); } else { - w_t = (nodeptr)write_barrier(_t); + if (CACHE_AT(td.writeable, _t) == _t) + w_t = (nodeptr)_t; + else + w_t = (nodeptr)write_barrier(_t); w_t->hash = stm_hash((gcptr)w_t); assert(w_t->hash == stm_hash((gcptr)_t)); } @@ -538,6 +560,8 @@ td.interruptible = 0; pop_roots(); + + memset(&td.writeable, 0, sizeof(td.writeable)); } @@ -558,6 +582,7 @@ stm_push_root(end_marker); int p = run_me(); + if (p == -1) // maybe restart transaction return get_rand(3) != 1; @@ -567,6 +592,10 @@ int run_me() { gcptr p = NULL; + + // clear cache of writeables: + memset(&td.writeable, 0, sizeof(td.writeable)); + while (td.steps_left-->0 || td.atomic) { if (td.steps_left % 8 == 0) fprintf(stdout, "#"); diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -207,8 +207,8 @@ (revision_t)END_MARKER_ON)) { /* 'item' is a regular, non-null pointer */ visit_if_young(end); - - /* if old, private or protected, this object needs to be + item = *end; + /* if private or protected, this object needs to be traced again in the next minor_collect if it is currently in old_objects_to_trace. Because then it may be seen as write-ready in the view of @@ -216,7 +216,7 @@ pw = write_barrier(); push_root(pw); minor_collect(); pw = pop_root(); // pw still write-ready */ - if (item && item->h_tid & GCFLAG_OLD + if (item && !(item->h_tid & GCFLAG_WRITE_BARRIER) /* not set in obj_to_trace*/ && (item->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED diff --git a/c4/test/test_et.py b/c4/test/test_et.py --- a/c4/test/test_et.py +++ b/c4/test/test_et.py @@ -250,6 +250,25 @@ assert getptr(pr, 0) == q assert getptr(pr, 0) != q2 +def test_write_barrier_after_minor_collect_young_to_old(): + p = nalloc_refs(1) + pw = lib.stm_write_barrier(p) + + lib.stm_push_root(pw) + minor_collect() + r = nalloc(HDR) + pw = lib.stm_pop_root() + + check_nursery_free(p) + assert pw.h_tid & GCFLAG_OLD + rawsetptr(pw, 0, r) + + lib.stm_push_root(pw) + minor_collect() + pw = lib.stm_pop_root() + check_nursery_free(r) + + assert getptr(pw, 0) != r def test_id_young_to_old(): # move out of nursery with shadow original _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit