예제 #1
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;
}
예제 #2
0
파일: intset.c 프로젝트: digideskio/tinystm
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;
}