Author: Armin Rigo <ar...@tunes.org> Branch: c8-gil-like Changeset: r1805:ea72e4a504fd Date: 2015-06-11 16:22 +0200 http://bitbucket.org/pypy/stmgc/changeset/ea72e4a504fd/
Log: in-progress diff --git a/c8/demo/demo_random.c b/c8/demo/demo_random.c --- a/c8/demo/demo_random.c +++ b/c8/demo/demo_random.c @@ -57,9 +57,16 @@ } +long check_size(long size) +{ + assert(size >= sizeof(struct node_s)); + assert(size <= sizeof(struct node_s) + 4096*70); + return size; +} + ssize_t stmcb_size_rounded_up(struct object_s *ob) { - return ((struct node_s*)ob)->my_size; + return check_size(((struct node_s*)ob)->my_size); } void stmcb_trace(struct object_s *obj, void visit(object_t **)) @@ -69,7 +76,8 @@ /* and the same value at the end: */ /* note, ->next may be the same as last_next */ - nodeptr_t *last_next = (nodeptr_t*)((char*)n + n->my_size - sizeof(void*)); + nodeptr_t *last_next = (nodeptr_t*)((char*)n + check_size(n->my_size) + - sizeof(void*)); assert(n->next == *last_next); @@ -113,36 +121,36 @@ } } -void reload_roots() -{ - int i; - assert(td.num_roots == td.num_roots_at_transaction_start); - for (i = td.num_roots_at_transaction_start - 1; i >= 0; i--) { - if (td.roots[i]) - STM_POP_ROOT(stm_thread_local, td.roots[i]); - } - - for (i = 0; i < td.num_roots_at_transaction_start; i++) { - if (td.roots[i]) - STM_PUSH_ROOT(stm_thread_local, td.roots[i]); - } -} - void push_roots() { int i; + assert(td.num_roots_at_transaction_start <= td.num_roots); for (i = td.num_roots_at_transaction_start; i < td.num_roots; i++) { if (td.roots[i]) STM_PUSH_ROOT(stm_thread_local, td.roots[i]); } + STM_SEGMENT->no_safe_point_here = 0; } void pop_roots() { int i; - for (i = td.num_roots - 1; i >= td.num_roots_at_transaction_start; i--) { - if (td.roots[i]) + STM_SEGMENT->no_safe_point_here = 1; + + assert(td.num_roots_at_transaction_start <= td.num_roots); + for (i = td.num_roots - 1; i >= 0; i--) { + if (td.roots[i]) { STM_POP_ROOT(stm_thread_local, td.roots[i]); + assert(td.roots[i]); + } + } + + fprintf(stderr, "stm_is_inevitable() = %d\n", (int)stm_is_inevitable()); + for (i = 0; i < td.num_roots_at_transaction_start; i++) { + if (td.roots[i]) { + fprintf(stderr, "root %d: %p\n", i, td.roots[i]); + STM_PUSH_ROOT(stm_thread_local, td.roots[i]); + } } } @@ -150,6 +158,7 @@ { int i; assert(idx >= td.num_roots_at_transaction_start); + assert(idx < td.num_roots); for (i = idx; i < td.num_roots - 1; i++) td.roots[i] = td.roots[i + 1]; @@ -158,6 +167,7 @@ void add_root(objptr_t r) { + assert(td.num_roots_at_transaction_start <= td.num_roots); if (r && td.num_roots < MAXROOTS) { td.roots[td.num_roots++] = r; } @@ -184,7 +194,8 @@ nodeptr_t n = (nodeptr_t)p; /* and the same value at the end: */ - nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + n->my_size - sizeof(void*)); + nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + + check_size(n->my_size) - sizeof(void*)); assert(n->next == *last_next); n->next = (nodeptr_t)v; *last_next = (nodeptr_t)v; @@ -196,7 +207,8 @@ nodeptr_t n = (nodeptr_t)p; /* and the same value at the end: */ - nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + n->my_size - sizeof(void*)); + nodeptr_t TLPREFIX *last_next = (nodeptr_t TLPREFIX *)((stm_char*)n + + check_size(n->my_size) - sizeof(void*)); OPT_ASSERT(n->next == *last_next); return n->next; @@ -229,7 +241,7 @@ sizeof(struct node_s) + (get_rand(100000) & ~15), sizeof(struct node_s) + 4096, sizeof(struct node_s) + 4096*70}; - size_t size = sizes[get_rand(4)]; + size_t size = check_size(sizes[get_rand(4)]); p = stm_allocate(size); nodeptr_t n = (nodeptr_t)p; n->sig = SIGNATURE; @@ -240,7 +252,6 @@ n->next = NULL; *last_next = NULL; pop_roots(); - /* reload_roots not necessary, all are old after start_transaction */ break; case 4: // read and validate 'p' read_barrier(p); @@ -306,7 +317,9 @@ stm_become_inevitable(&stm_thread_local, "please"); pop_roots(); return NULL; - } else if (get_rand(240) == 1) { + } else if (0 && // XXXXXXXXXXXXXXXXXXXXX + + get_rand(240) == 1) { push_roots(); stm_become_globally_unique_transaction(&stm_thread_local, "really"); fprintf(stderr, "[GUT/%d]", (int)STM_SEGMENT->segment_num); @@ -352,13 +365,16 @@ td.num_roots = td.num_roots_at_transaction_start; p = NULL; pop_roots(); /* does nothing.. */ - reload_roots(); while (td.steps_left-->0) { if (td.steps_left % 8 == 0) fprintf(stdout, "#"); - assert(p == NULL || ((nodeptr_t)p)->sig == SIGNATURE); + int local_seg = STM_SEGMENT->segment_num; + int p_sig = p == NULL ? 0 : ((nodeptr_t)p)->sig; + + assert(p == NULL || p_sig == SIGNATURE); + (void)local_seg; p = do_step(p); @@ -366,7 +382,9 @@ push_roots(); long call_fork = (arg != NULL && *(long *)arg); - if (call_fork == 0) { /* common case */ + if (1 || // XXXXXXXXXXXXXXXX + + call_fork == 0) { /* common case */ if (get_rand(100) < 50) { stm_leave_transactional_zone(&stm_thread_local); /* Nothing here; it's unlikely that a different thread @@ -386,7 +404,6 @@ td.num_roots = td.num_roots_at_transaction_start; p = NULL; pop_roots(); - reload_roots(); } else { /* run a fork() inside the transaction */ diff --git a/c8/stm/detach.c b/c8/stm/detach.c --- a/c8/stm/detach.c +++ b/c8/stm/detach.c @@ -32,6 +32,7 @@ void _stm_leave_noninevitable_transactional_zone(void) { + dprintf(("leave_noninevitable_transactional_zone\n")); _stm_become_inevitable(MSG_INEV_DONT_SLEEP); /* did it work? */ @@ -61,11 +62,13 @@ disappear. XXX could be done even earlier, as soon as we have read the shadowstack inside the minor collection. */ STM_SEGMENT->running_thread = NULL; + + _core_commit_transaction(); + + write_fence(); assert(_stm_detached_inevitable_from_thread == -1); _stm_detached_inevitable_from_thread = 0; - - _core_commit_transaction(); } void _stm_reattach_transaction(intptr_t old, stm_thread_local_t *tl) @@ -75,6 +78,7 @@ if (old == -1) { /* busy-loop: wait until _stm_detached_inevitable_from_thread is reset to a value different from -1 */ + dprintf(("reattach_transaction: busy wait...\n")); while (_stm_detached_inevitable_from_thread == -1) spin_loop(); diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c --- a/c8/stm/nursery.c +++ b/c8/stm/nursery.c @@ -309,6 +309,7 @@ else assert(finalbase <= ssbase && ssbase <= current); + dprintf(("collect_roots_in_nursery:\n")); while (current > ssbase) { --current; uintptr_t x = (uintptr_t)current->ss; @@ -320,6 +321,7 @@ else { /* it is an odd-valued marker, ignore */ } + dprintf((" %p: %p -> %p\n", current, (void *)x, current->ss)); } minor_trace_if_young(&tl->thread_local_obj); @@ -519,6 +521,7 @@ static void _do_minor_collection(bool commit) { dprintf(("minor_collection commit=%d\n", (int)commit)); + assert(!STM_SEGMENT->no_safe_point_here); STM_PSEGMENT->minor_collect_will_commit_now = commit; diff --git a/c8/stm/setup.c b/c8/stm/setup.c --- a/c8/stm/setup.c +++ b/c8/stm/setup.c @@ -137,6 +137,9 @@ setup_detach(); set_gs_register(get_segment_base(0)); + + dprintf(("nursery: %p -> %p\n", (void *)NURSERY_START, + (void *)NURSERY_END)); } void stm_teardown(void) diff --git a/c8/stm/sync.c b/c8/stm/sync.c --- a/c8/stm/sync.c +++ b/c8/stm/sync.c @@ -383,6 +383,7 @@ break; /* no safe point requested */ dprintf(("enter safe point\n")); + assert(!STM_SEGMENT->no_safe_point_here); assert(STM_SEGMENT->nursery_end == NSE_SIGPAUSE); assert(pause_signalled); @@ -397,6 +398,7 @@ cond_wait(C_REQUEST_REMOVED); STM_PSEGMENT->safe_point = SP_RUNNING; timing_event(STM_SEGMENT->running_thread, STM_WAIT_DONE); + assert(!STM_SEGMENT->no_safe_point_here); dprintf(("left safe point\n")); } } diff --git a/c8/stmgc.h b/c8/stmgc.h --- a/c8/stmgc.h +++ b/c8/stmgc.h @@ -40,6 +40,7 @@ struct stm_segment_info_s { uint8_t transaction_read_version; + uint8_t no_safe_point_here; /* set from outside, triggers an assert */ int segment_num; char *segment_base; stm_char *nursery_current; @@ -420,10 +421,12 @@ far more efficient than constantly starting and committing transactions. */ +#include <stdio.h> static inline void stm_enter_transactional_zone(stm_thread_local_t *tl) { intptr_t old; atomic_exchange(&_stm_detached_inevitable_from_thread, old, -1); if (old == (intptr_t)tl) { + fprintf(stderr, "stm_enter_transactional_zone fast path\n"); _stm_detached_inevitable_from_thread = 0; } else { @@ -434,10 +437,13 @@ } static inline void stm_leave_transactional_zone(stm_thread_local_t *tl) { assert(STM_SEGMENT->running_thread == tl); - if (stm_is_inevitable()) + if (stm_is_inevitable()) { + fprintf(stderr, "stm_leave_transactional_zone fast path\n"); _stm_detach_inevitable_transaction(tl); - else + } + else { _stm_leave_noninevitable_transactional_zone(); + } } /* stm_force_transaction_break() is in theory equivalent to @@ -461,8 +467,9 @@ assert(STM_SEGMENT->running_thread == tl); if (!stm_is_inevitable()) _stm_become_inevitable(msg); - /* now, we're running the inevitable transaction, so: */ - assert(_stm_detached_inevitable_from_thread == 0); + /* now, we're running the inevitable transaction, so this var should + be 0 (but can occasionally be -1 for a tiny amount of time) */ + assert(((_stm_detached_inevitable_from_thread + 1) & ~1) == 0); } /* Forces a safe-point if needed. Normally not needed: this is diff --git a/duhton-c8/duhton.c b/duhton-c8/duhton.c --- a/duhton-c8/duhton.c +++ b/duhton-c8/duhton.c @@ -41,7 +41,8 @@ printf("))) "); fflush(stdout); } - stm_start_inevitable_transaction(&stm_thread_local); + stm_enter_transactional_zone(&stm_thread_local); + stm_become_inevitable(&stm_thread_local, "starting point"); DuObject *code = Du_Compile(filename, interactive); if (code == NULL) { @@ -58,7 +59,7 @@ //stm_collect(0); /* hack... */ //_du_restore1(stm_thread_local_obj); - stm_commit_transaction(); + stm_leave_transactional_zone(&stm_thread_local); Du_TransactionRun(); if (!interactive) diff --git a/duhton-c8/glob.c b/duhton-c8/glob.c --- a/duhton-c8/glob.c +++ b/duhton-c8/glob.c @@ -713,11 +713,12 @@ //stm_collect(0); /* hack... */ //_du_restore1(stm_thread_local_obj); - stm_commit_transaction(); + stm_leave_transactional_zone(&stm_thread_local); Du_TransactionRun(); - stm_start_inevitable_transaction(&stm_thread_local); + stm_enter_transactional_zone(&stm_thread_local); + stm_become_inevitable(&stm_thread_local, "run-transactions finished"); return Du_None; } @@ -809,7 +810,8 @@ /* prebuilt objs stay on the shadowstack forever */ stm_register_thread_local(&stm_thread_local); - stm_start_inevitable_transaction(&stm_thread_local); + stm_enter_transactional_zone(&stm_thread_local); + stm_become_inevitable(&stm_thread_local, "initialization"); all_threads_count = num_threads; all_threads = (pthread_t*)malloc(sizeof(pthread_t) * num_threads); @@ -857,7 +859,7 @@ DuFrame_SetBuiltinMacro(Du_Globals, "pair?", du_pair); DuFrame_SetBuiltinMacro(Du_Globals, "assert", du_assert); DuFrame_SetSymbolStr(Du_Globals, "None", Du_None); - stm_commit_transaction(); + stm_leave_transactional_zone(&stm_thread_local); } void Du_Finalize(void) diff --git a/duhton-c8/transaction.c b/duhton-c8/transaction.c --- a/duhton-c8/transaction.c +++ b/duhton-c8/transaction.c @@ -58,14 +58,14 @@ if (TLOBJ == NULL) return; - stm_start_inevitable_transaction(&stm_thread_local); + stm_enter_transactional_zone(&stm_thread_local); DuConsObject *root = du_pending_transactions; _du_write1(root); root->cdr = TLOBJ; TLOBJ = NULL; - stm_commit_transaction(); + stm_leave_transactional_zone(&stm_thread_local); run_all_threads(); } _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit