Author: Remi Meier Branch: Changeset: r1099:ae1a7d62c9a2 Date: 2014-03-27 11:12 +0100 http://bitbucket.org/pypy/stmgc/changeset/ae1a7d62c9a2/
Log: make HTM work sometimes: copy nearly all logic from paper about ruby; don't clean whole nursery on commit, only used parts (always overflowed) diff --git a/c7/demo/Makefile b/c7/demo/Makefile --- a/c7/demo/Makefile +++ b/c7/demo/Makefile @@ -30,3 +30,9 @@ release-%: %.c ${H_FILES} ${C_FILES} clang -I.. -pthread -g -DNDEBUG -O2 $< -o release-$* \ -Wall -Werror ../stmgc.c + + +release-htm-%: %.c ../../htm-c7/stmgc.? ../../htm-c7/htm.h + clang -I.. -pthread -g -DNDEBUG -O2 $< -o release-htm-$* ../../htm-c7/stmgc.c -Wall -DUSE_HTM + + diff --git a/c7/demo/demo2.c b/c7/demo/demo2.c --- a/c7/demo/demo2.c +++ b/c7/demo/demo2.c @@ -4,11 +4,20 @@ #include <pthread.h> #include <semaphore.h> -#include "stmgc.h" +#ifdef USE_HTM +# include "../../htm-c7/stmgc.h" +#else +# include "stmgc.h" +#endif -#define NTHREADS 3 -#define LIST_LENGTH 2000 -#define BUNCH 100 +#define LIST_LENGTH 4000 +#define NTHREADS 2 + +#ifdef USE_HTM +# define BUNCH 200 +#else +# define BUNCH 200 +#endif typedef TLPREFIX struct node_s node_t; typedef node_t* nodeptr_t; @@ -234,6 +243,7 @@ setup_list(); + for (i = 1; i <= NTHREADS; i++) { newthread(demo2, (void*)(uintptr_t)i); } diff --git a/gil-c7/stmgc.c b/gil-c7/stmgc.c --- a/gil-c7/stmgc.c +++ b/gil-c7/stmgc.c @@ -267,10 +267,11 @@ _stm_nursery_base = malloc(NURSERY_SIZE); assert(_stm_nursery_base); _stm_nursery_end = _stm_nursery_base + NURSERY_SIZE; + _stm_nursery_current = _stm_nursery_base; } + memset(_stm_nursery_base, 0, _stm_nursery_current-_stm_nursery_base); _stm_nursery_current = _stm_nursery_base; - memset(_stm_nursery_base, 0, NURSERY_SIZE); } #define WEAKREF_PTR(wr, sz) ((object_t * TLPREFIX *)(((char *)(wr)) + (sz) - sizeof(void*))) @@ -332,6 +333,7 @@ { /* run minor collection */ //fprintf(stderr, "minor collect\n"); + _stm_nursery_current -= size_rounded_up; stm_collect(0); char *p = _stm_nursery_current; diff --git a/htm-c7/stmgc.c b/htm-c7/stmgc.c --- a/htm-c7/stmgc.c +++ b/htm-c7/stmgc.c @@ -7,9 +7,14 @@ stm_thread_local_t *_stm_tloc; struct stm_segment_info_s _stm_segment; +#define TRANSIENT_RETRY_MAX 5 +#define GIL_RETRY_MAX 5 +#define ABORT_GIL_LOCKED 1 +#define smp_spinloop() asm volatile ("pause":::"memory") + static void acquire_gil(stm_thread_local_t *tl) { if (pthread_mutex_lock(&_stm_gil) == 0) { _stm_tloc = tl; @@ -18,32 +23,76 @@ abort(); } +static int spin_and_acquire_gil(stm_thread_local_t *tl) { + int n = 100; + while ((n --> 0) && mutex_locked(&_stm_gil)) { + smp_spinloop(); + } + + if (!mutex_locked(&_stm_gil)) + return 0; + + acquire_gil(tl); + return 1; +} + +static int is_persistent(int status) { + if ((status & XBEGIN_XABORT) && XBEGIN_XABORT_ARG(status) == ABORT_GIL_LOCKED) + return 0; + else if (status & (XBEGIN_MAYBE_RETRY | XBEGIN_NORMAL_CONFLICT)) + return 0; + else if (status == XBEGIN_UNKNOWN) + return 0; + return 1; +} + void stm_start_inevitable_transaction(stm_thread_local_t *tl) { + /* set_transaction_length(pc) */ + if (mutex_locked(&_stm_gil)) { - acquire_gil(tl); - return; + if (spin_and_acquire_gil(tl)) + return; } volatile int status; + volatile int transient_retry_counter = TRANSIENT_RETRY_MAX; + volatile int gil_retry_counter = GIL_RETRY_MAX; + volatile int first_retry = 1; + transaction_retry: - status = xbegin(); if (status == XBEGIN_OK) { if (mutex_locked(&_stm_gil)) - xabort(0); + xabort(ABORT_GIL_LOCKED); /* transaction OK */ } else { - if (status & (XBEGIN_MAYBE_RETRY | XBEGIN_NORMAL_CONFLICT | XBEGIN_XABORT)) { - goto transaction_retry; - } else if (mutex_locked(&_stm_gil)) { + if (first_retry) { + first_retry = 0; + /* adjust_transaction_length(pc) */ + } + + if (mutex_locked(&_stm_gil)) { + gil_retry_counter--; + if (gil_retry_counter > 0) { + if (spin_and_acquire_gil(tl)) + return; + else + goto transaction_retry; + } acquire_gil(tl); - } - else { + } else if (is_persistent(status)) { + acquire_gil(tl); + } else { + /* transient abort */ + transient_retry_counter--; + if (transient_retry_counter > 0) + goto transaction_retry; acquire_gil(tl); } - fprintf(stderr, "failed HTM: %s\n", xbegin_status(status)); + /* fprintf(stderr, "failed HTM: %s, t_retry: %d, gil_retry: %d\n", */ + /* xbegin_status(status), transient_retry_counter, gil_retry_counter); */ } _stm_tloc = tl; @@ -55,10 +104,10 @@ if (mutex_locked(&_stm_gil)) { assert(!xtest()); if (pthread_mutex_unlock(&_stm_gil) != 0) abort(); - //fprintf(stderr, "G"); + fprintf(stderr, "G"); } else { xend(); - fprintf(stderr, "==== Committed HTM ====\n"); + fprintf(stderr, "H"); } } @@ -327,10 +376,11 @@ _stm_nursery_base = malloc(NURSERY_SIZE); assert(_stm_nursery_base); _stm_nursery_end = _stm_nursery_base + NURSERY_SIZE; + _stm_nursery_current = _stm_nursery_base; } + memset(_stm_nursery_base, 0, _stm_nursery_current-_stm_nursery_base); _stm_nursery_current = _stm_nursery_base; - memset(_stm_nursery_base, 0, NURSERY_SIZE); } #define WEAKREF_PTR(wr, sz) ((object_t * TLPREFIX *)(((char *)(wr)) + (sz) - sizeof(void*))) @@ -392,6 +442,7 @@ { /* run minor collection */ //fprintf(stderr, "minor collect\n"); + _stm_nursery_current -= size_rounded_up; stm_collect(0); char *p = _stm_nursery_current; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit