Author: Remi Meier <meier...@student.ethz.ch> Branch: Changeset: r199:b2ce4052626c Date: 2013-06-20 08:40 +0200 http://bitbucket.org/pypy/stmgc/changeset/b2ce4052626c/
Log: demo_random: more checks diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -6,15 +6,19 @@ #include <time.h> #include "stmgc.h" +#include "stmimpl.h" #include "fprintcolor.h" +extern revision_t get_private_rev_num(void); + #define NUMTHREADS 4 #define STEPS 100000 -#define NUMROOTS 10 -#define PREBUILT 3 +#define NUMROOTS 10 // per thread +#define PREBUILT 3 // per thread #define MAXROOTS 1000 -#define SHARED_ROOTS 5 +#define SHARED_ROOTS 5 // shared by threads + // SUPPORT @@ -58,6 +62,9 @@ // helper functions +int classify(gcptr p); +void check(gcptr p); + int get_rand(int max) { return (int)(rand_r(&td.thread_seed) % (unsigned int)max); @@ -81,15 +88,19 @@ void push_roots() { int i; - for (i = 0; i < td.num_roots; i++) + for (i = 0; i < td.num_roots; i++) { + check(td.roots[i]); stm_push_root(td.roots[i]); + } } void pop_roots() { int i; - for (i = td.num_roots - 1; i >= 0; i--) + for (i = td.num_roots - 1; i >= 0; i--) { td.roots[i] = stm_pop_root(); + check(td.roots[i]); + } } void del_root(int idx) @@ -99,15 +110,117 @@ td.roots[i] = td.roots[i + 1]; } -gcptr allocate_node(size_t size, int tid) +nodeptr allocate_node() { - gcptr r; + nodeptr r; push_roots(); - r = stm_allocate(size, tid); + r = (nodeptr)stm_allocate(sizeof(struct node), GCTID_STRUCT_NODE); pop_roots(); return r; } +int is_shared_prebuilt(gcptr p) +{ + int i; + for (i = 0; i < SHARED_ROOTS; i++) + if (shared_roots[i] == p) + return 1; + return 0; +} + +void check_not_free(gcptr p) +{ + assert(p != NULL); + assert((p->h_tid & 0xFFFF) == GCTID_STRUCT_NODE); + if (is_shared_prebuilt(p)) + assert(p->h_tid & GCFLAG_PREBUILT_ORIGINAL); +} + +void check(gcptr p) +{ + if (p != NULL) { + check_not_free(p); + classify(p); // additional asserts + } +} + +gcptr read_barrier(gcptr p) +{ + gcptr r = p; + if (p != NULL) { + check(p); + r = stm_read_barrier(p); + check(r); + } + return r; +} + +gcptr write_barrier(gcptr p) +{ + gcptr w = p; + if (p != NULL) { + check(p); + w = stm_write_barrier(p); + check(w); + } + return w; +} + +int in_nursery(gcptr obj) +{ + struct tx_descriptor *d = thread_descriptor; + int result1 = (d->nursery_base <= (char*)obj && + ((char*)obj) < d->nursery_end); + if (obj->h_tid & GCFLAG_OLD) { + assert(result1 == 0); + } + else { + /* this assert() also fails if "obj" is in another nursery than + the one of the current thread. This is ok, because we + should not see such pointers. */ + assert(result1 == 1); + } + return result1; +} + +static const revision_t C_PRIVATE_FROM_PROTECTED = 1; +static const revision_t C_PRIVATE = 2; +static const revision_t C_STUB = 3; +static const revision_t C_PUBLIC = 4; +static const revision_t C_BACKUP = 5; +static const revision_t C_PROTECTED = 6; +int classify(gcptr p) +{ + int priv_from_prot = (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) != 0; + int private_other = p->h_revision == get_private_rev_num(); + int public = (p->h_tid & GCFLAG_PUBLIC) != 0; + int backup = (p->h_tid & GCFLAG_BACKUP_COPY) != 0; + int stub = (p->h_tid & GCFLAG_STUB) != 0; + assert(priv_from_prot + private_other + public + backup <= 1); + assert(public || !stub); + + if (priv_from_prot) + return C_PRIVATE_FROM_PROTECTED; + if (private_other) + return C_PRIVATE; + if (public) { + if (stub) { + assert(!in_nursery(p)); + } + else { + if (in_nursery(p)) { + assert(p->h_tid & GCFLAG_NURSERY_MOVED); + assert(!(p->h_revision & 1)); + } + return C_PUBLIC; + } + } + if (backup) + return C_BACKUP; + return C_PROTECTED; +} + + // THREAD TESTER @@ -128,7 +241,7 @@ GCTID_STRUCT_NODE); } for (i = PREBUILT; i < PREBUILT + NUMROOTS; i++) { - td.roots[i] = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE); + td.roots[i] = (gcptr)allocate_node(); } } @@ -149,9 +262,6 @@ k = get_rand(14); - if (!p) // some parts expect it to be != 0 - p = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE); - switch (k) { case 0: // remove a root if (num > 0) @@ -162,19 +272,21 @@ p = _r; break; case 2: // add 'p' to roots - if (td.num_roots < MAXROOTS) + if (p && td.num_roots < MAXROOTS) td.roots[td.num_roots++] = p; break; case 3: // allocate fresh 'p' - p = allocate_node(sizeof(struct node), GCTID_STRUCT_NODE); + p = (gcptr)allocate_node(); break; case 4: // set 'p' as *next in one of the roots - w_r = (nodeptr)stm_write_barrier(_r); - // XXX: do I have to read_barrier(p)? + check(_r); + w_r = (nodeptr)write_barrier(_r); + check((gcptr)w_r); + check(p); w_r->next = (struct node*)p; break; case 5: // read and validate 'p' - stm_read_barrier(p); + read_barrier(p); break; case 6: // transaction break if (td.interruptible) @@ -183,25 +295,27 @@ p = NULL; break; case 7: // only do a stm_write_barrier - p = stm_write_barrier(p); + p = write_barrier(p); break; case 8: - p = (gcptr)(((nodeptr)stm_read_barrier(p))->next); + if (p) + p = (gcptr)(((nodeptr)read_barrier(p))->next); break; case 9: // XXX: rare events break; case 10: // only do a stm_read_barrier - p = stm_read_barrier(p); + p = read_barrier(p); break; case 11: - stm_read_barrier(_sr); + read_barrier(_sr); break; case 12: - stm_write_barrier(_sr); + write_barrier(_sr); break; case 13: - w_sr = (nodeptr)stm_write_barrier(_sr); + w_sr = (nodeptr)write_barrier(_sr); w_sr->next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)]; + break; default: break; } _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit