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; }
static void *test(void *data) { int op, val, last = -1; thread_data_t *d = (thread_data_t *)data; /* Create transaction */ TM_INIT_THREAD; /* Wait on barrier */ barrier_cross(d->barrier); while (stop == 0) { op = rand_range(100, d->seed); if (op < d->update) { if (d->alternate) { /* Alternate insertions and removals */ if (last < 0) { /* Add random value */ val = rand_range(d->range, d->seed) + 1; if (set_add(d->set, val, d)) { d->diff++; last = val; } d->nb_add++; } else { /* Remove last value */ if (set_remove(d->set, last, d)) d->diff--; d->nb_remove++; last = -1; } } else { /* Randomly perform insertions and removals */ val = rand_range(d->range, d->seed) + 1; if ((op & 0x01) == 0) { /* Add random value */ if (set_add(d->set, val, d)) d->diff++; d->nb_add++; } else { /* Remove random value */ if (set_remove(d->set, val, d)) d->diff--; d->nb_remove++; } } } else { /* Look for random value */ val = rand_range(d->range, d->seed) + 1; if (set_contains(d->set, val, d)) d->nb_found++; d->nb_contains++; } } #ifndef TM_COMPILER 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); #endif /* ! TM_COMPILER */ /* Free transaction */ TM_EXIT_THREAD; return NULL; }