static void abi_exit_thread(struct stm_tx *tx) { if (tx == NULL) return; stm_exit_thread(); }
void *count(void *ptr) { long i, max = MAX_COUNT/NUM_THREADS; int tid = ((struct tdata *) ptr)->tid; int c; stm_init_thread(); for (i=0; i < max; i++) { TM_START(0, 0); c = stm_load_int(&counter); if (i % 10 == 0) { c++; stm_store_int(&counter, c); } TM_COMMIT; } printf("End %d counter: %d\n", tid, counter); stm_exit_thread(); }
static void abi_exit_thread(struct stm_tx *tx) { if (tx == NULL) return; #if 0 /* FIXME disable during refactoring */ if (getenv("ITM_STATISTICS") != NULL) { stats_t * ts = malloc(sizeof(stats_t)); #ifdef TLS thread_abi_t *t = thread_abi; #else /* ! TLS */ thread_abi_t *t = pthread_getspecific(thread_abi); #endif /* ! TLS */ ts->thread_id = t->thread_id; stm_get_local_stats("nb_commits", &ts->nb_commits); stm_get_local_stats("nb_aborts", &ts->nb_aborts); stm_get_local_stats("nb_retries_avg", &ts->nb_retries_avg); stm_get_local_stats("nb_retries_min", &ts->nb_retries_min); stm_get_local_stats("nb_retries_max", &ts->nb_retries_max); /* Register thread-statistics to global */ do { ts->next = (stats_t *)ATOMIC_LOAD(&thread_stats); } while (ATOMIC_CAS_FULL(&thread_stats, ts->next, ts) == 0); /* ts will be freed on _ITM_finalizeProcess. */ #ifdef TLS thread_abi = NULL; #else /* ! TLS */ pthread_setspecific(thread_abi, NULL); #endif /* Free thread_abi_t structure. */ free(t); } #endif stm_exit_thread(); #ifdef TM_DTMC /* Free the saved stack */ tanger_stm_free_stack(); #endif }
int main(int argc, char **argv) { /* Init STM */ stm_init(); mod_mem_init(0); /* Create transaction */ stm_init_thread(); /* Testing */ test1load(1); test1load(0); testnload(1, 100); testnload(0, 100); testnloadnstore(100, 20); testnloadnstore(100, 20); /* Free transaction */ stm_exit_thread(); /* Cleanup STM */ stm_exit(); return 0; }
void *test(void *v) { unsigned int seed; int i, n, irrevocable, serial; long l; sigjmp_buf *e; thread_data_t *d = (thread_data_t *)v; seed = (unsigned int)time(0); stm_init_thread(); while (stop == 0) { irrevocable = (rand_r(&seed) < RAND_MAX / 100 * d->irrevocable_percent ? 1 : 0); serial = (rand_r(&seed) < RAND_MAX / 2 ? 1 : 0); // irrevocable=1; // serial=1; e = stm_start(NULL); if (e != NULL) sigsetjmp(*e, 0); if (irrevocable == 4) { /* Aborted while in irrevocable mode => error */ fprintf(stderr, "ERROR: aborted while in irrevocable mode\n"); exit(1); } for (n = rand_r(&seed) % NB_SHUFFLES; n > 0; n--) { i = rand_r(&seed) % NB_ELEMENTS; stm_store_long(&data[i], stm_load_long(&data[i]) + 1); i = rand_r(&seed) % NB_ELEMENTS; stm_store_long(&data[i], stm_load_long(&data[i]) - 1); } if (irrevocable) { if (irrevocable == 3) { /* Already tried entering irrevocable mode once => error */ fprintf(stderr, "ERROR: failed entering irrevocable mode upon retry\n"); exit(1); } irrevocable++; if (!stm_set_irrevocable(serial)) { fprintf(stderr, "ERROR: cannot enter irrevocable mode\n"); exit(1); } irrevocable = 4; /* Once in irrevocable mode, we cannot abort */ if (serial) { /* No other transaction can execute concurrently */ for (i = 0, l = 0; i < NB_ELEMENTS; i++) l += data[i]; assert(l == 0); for (i = 0; i < NB_ELEMENTS; i++) data[i] = 0; nb_irrevocable_serial++; } else { /* Non-conflicting transactions can execute concurrently */ for (i = 0, l = 0; i < NB_ELEMENTS; i++) l += stm_load_long(&data[i]); assert(l == 0); for (i = 0; i < NB_ELEMENTS; i++) stm_store_long(&data[i], 0); nb_irrevocable_parallel++; } } for (i = 0, l = 0; i < NB_ELEMENTS; i++) l += stm_load_long(&data[i]); assert(l == 0); stm_commit(); } stm_get_stats("nb_aborts", &d->nb_aborts); stm_get_stats("nb_aborts_1", &d->nb_aborts_1); stm_get_stats("nb_aborts_2", &d->nb_aborts_2); stm_get_stats("nb_aborts_locked_read", &d->nb_aborts_locked_read); stm_get_stats("nb_aborts_locked_write", &d->nb_aborts_locked_write); stm_get_stats("nb_aborts_validate_read", &d->nb_aborts_validate_read); stm_get_stats("nb_aborts_validate_write", &d->nb_aborts_validate_write); stm_get_stats("nb_aborts_validate_commit", &d->nb_aborts_validate_commit); stm_get_stats("nb_aborts_invalid_memory", &d->nb_aborts_invalid_memory); stm_get_stats("nb_aborts_killed", &d->nb_aborts_killed); stm_get_stats("locked_reads_ok", &d->locked_reads_ok); stm_get_stats("locked_reads_failed", &d->locked_reads_failed); stm_get_stats("max_retries", &d->max_retries); stm_exit_thread(); return NULL; }