grt_bool_t hashtable_find(grt_word_t val) {
  unsigned bucket = compute_hash(val);
  grt_word_t *loc = (grt_word_t*) &table[bucket];
  node_t *p;
  stm_start();
  stm_open_for_read(table_proc, loc);
  stm_read(table_proc, loc, (grt_word_t*) &p);
  grt_bool_t result = find_node_stm(val, p) == 0 ? GRT_FALSE : GRT_TRUE;
  stm_commit();
  return result;
}
Beispiel #2
0
sigjmp_buf *
tm_start(TXPARAMS stm_tx_attr_t attr)
{
    TX_GET;

    if (!tx->software) {
        return hytm_start(TXARGS attr);
    } else {
        return stm_start(TXARGS attr);
    }
}
grt_bool_t hashtable_insert(grt_word_t val) {
  unsigned bucket = compute_hash(val);
  node_t *p, *q;
  stm_start();
  grt_word_t *loc = (grt_word_t*) &table[bucket];
  stm_open_for_read(table_proc, loc);
  stm_read(table_proc, loc, (grt_word_t*) &p);
  if (find_node_stm(val, p)) {
    stm_commit();
    return GRT_TRUE;
  }
  q = (node_t*) stm_alloc(table_proc, sizeof(node_t));
  loc = (grt_word_t*) &q->next;
  stm_open_for_write(table_proc, loc);
  stm_write(table_proc, (grt_word_t) p, loc);
  loc = (grt_word_t*) &q->val;
  stm_open_for_write(table_proc, loc);
  stm_write(table_proc, val, loc);
  loc = (grt_word_t*) &table[bucket];
  stm_open_for_write(table_proc, loc);
  stm_write(table_proc, (grt_word_t) q, loc);
  stm_commit();
  return GRT_FALSE;
}
Beispiel #4
0
static void test1load(int ro)
{
  uint64_t m_s[MEASURE_NB];
  uint64_t m_r[MEASURE_NB];
  uint64_t m_c[MEASURE_NB];
  uint64_t m_rdtsc;
  uint64_t start;
  uint64_t min;
  double avg;
  uint64_t med;
  unsigned long i;
  stm_tx_attr_t _a = {{.read_only = ro}};

  m_rdtsc = ~0UL;
  for (i = 0; i < MEASURE_NB; i++) {
    start = rdtsc();
    start = rdtsc() - start;
    if (start < m_rdtsc)
      m_rdtsc = start;
  } 

  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e;
    start = rdtsc();
    _e = stm_start(_a);
    m_s[i] = rdtsc() - start;
    sigsetjmp(*_e, 0); 
    stm_load(&global_ctr[0]);
    stm_inc_clock();
    stm_commit();
  }

  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e = stm_start(_a);
    sigsetjmp(*_e, 0); 
    start = rdtsc();
    stm_load(&global_ctr[0]);
    m_r[i] = rdtsc() - start;
    stm_inc_clock();
    stm_commit();
  }
  
  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e = stm_start(_a);
    sigsetjmp(*_e, 0); 
    stm_load(&global_ctr[0]);
    stm_inc_clock();
    start = rdtsc();
    stm_commit();
    m_c[i] = rdtsc() - start;
  }
 
  remove_cst_cost(m_s, MEASURE_NB, m_rdtsc);
  remove_cst_cost(m_r, MEASURE_NB, m_rdtsc);
  remove_cst_cost(m_c, MEASURE_NB, m_rdtsc);

  if (ro) 
    printf("RO transaction - 1 load\n");
  else
    printf("RW transaction - 1 load\n");

  printf("%12s %12s %12s %12s\n", "", "min", "avg", "med");
  stats(m_s, MEASURE_NB, &min, &avg, &med); 
  printf("%12s %12lu %12.2f %12lu\n", "start", (unsigned long)min, avg, (unsigned long)med);
  stats(m_r, MEASURE_NB, &min, &avg, &med); 
  printf("%12s %12lu %12.2f %12lu\n", "load", (unsigned long)min, avg, (unsigned long)med);
  stats(m_c, MEASURE_NB, &min, &avg, &med); 
  printf("%12s %12lu %12.2f %12lu\n", "commit", (unsigned long)min, avg, (unsigned long)med);
}
Beispiel #5
0
static void testnloadnstore(size_t load_nb, size_t store_nb)
{
  uint64_t m_s[MEASURE_NB];
  uint64_t m_r[MEASURE_NB];
  uint64_t m_w[MEASURE_NB];
  uint64_t m_c[MEASURE_NB];
  uint64_t m_rdtsc;
  uint64_t start;
  uint64_t min;
  double avg;
  uint64_t med;
  unsigned long i;
  size_t j;
  stm_tx_attr_t _a = {{.read_only = 0}};

  m_rdtsc = ~0UL;
  for (i = 0; i < MEASURE_NB; i++) {
    start = rdtsc();
    start = rdtsc() - start;
    if (start < m_rdtsc)
      m_rdtsc = start;
  } 

  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e;
    start = rdtsc();
    _e = stm_start(_a);
    m_s[i] = rdtsc() - start;
    sigsetjmp(*_e, 0); 
    for (j = 0; j < load_nb; j++)
      stm_load(&global_ctr[j]);
    for (j = 0; j < store_nb; j++)
      stm_store(&global_ctr[j], (stm_word_t)0);
    stm_inc_clock();
    stm_commit();
  }

  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e = stm_start(_a);
    sigsetjmp(*_e, 0); 
    start = rdtsc();
    for (j = 0; j < load_nb; j++)
      stm_load(&global_ctr[j]);
    m_r[i] = rdtsc() - start;
    for (j = 0; j < store_nb; j++)
      stm_store(&global_ctr[j], (stm_word_t)0);
    stm_inc_clock();
    stm_commit();
  }
  
  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e = stm_start(_a);
    sigsetjmp(*_e, 0); 
    for (j = 0; j < load_nb; j++)
      stm_load(&global_ctr[j]);
    start = rdtsc();
    for (j = 0; j < store_nb; j++)
      stm_store(&global_ctr[j], (stm_word_t)0);
    m_w[i] = rdtsc() - start;
    stm_inc_clock();
    stm_commit();
  }
  
  for (i = 0; i < MEASURE_NB; i++) {
    sigjmp_buf *_e = stm_start(_a);
    sigsetjmp(*_e, 0); 
    for (j = 0; j < load_nb; j++)
      stm_load(&global_ctr[j]);
    for (j = 0; j < store_nb; j++)
      stm_store(&global_ctr[j], (stm_word_t)0);
    stm_inc_clock();
    start = rdtsc();
    stm_commit();
    m_c[i] = rdtsc() - start;
  }
 
  remove_cst_cost(m_s, MEASURE_NB, m_rdtsc);
  remove_cst_cost(m_r, MEASURE_NB, m_rdtsc);
  remove_cst_cost(m_w, MEASURE_NB, m_rdtsc);
  remove_cst_cost(m_c, MEASURE_NB, m_rdtsc);

  printf("RW transaction - %lu load - %lu store\n", (unsigned long)load_nb, (unsigned long)store_nb);

  printf("%12s %12s %12s %12s\n", "", "min", "avg", "med");
  stats(m_s, MEASURE_NB, &min, &avg, &med); 
  printf("%12s %12lu %12.2f %12lu\n", "start", (unsigned long)min, avg, (unsigned long)med);
  stats(m_r, MEASURE_NB, &min, &avg, &med); 
  if (load_nb)
    printf("%12s %12lu %12.2f %12lu\n", "load", (unsigned long)min/load_nb, avg/load_nb, (unsigned long)med/load_nb);
  stats(m_w, MEASURE_NB, &min, &avg, &med); 
  if (store_nb)
    printf("%12s %12lu %12.2f %12lu\n", "store", (unsigned long)min/store_nb, avg/store_nb, (unsigned long)med/store_nb);
  stats(m_c, MEASURE_NB, &min, &avg, &med); 
  printf("%12s %12lu %12.2f %12lu\n", "commit", (unsigned long)min, avg, (unsigned long)med);
}
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;
}
Beispiel #7
0
void run() {

  unsigned i, time;
  gasnett_tick_t start, end;

  hash_map_create(params[HASHMAP_SIZE], (grt_bool_t) params[ON_PTHREAD]);
  grt_barrier();

#ifdef LOCKS
  grt_lock_state_t state;
#endif
  for (i = 0; i < MY_NUM_OPS; ++i) {
    grt_word_t key = keys[i], val = values[i];
#ifdef LOCKS
    hash_t hash = compute_hash(key);
    hash_map_lock(hash.proc, hash.offset, WRITE, &state);
#endif
    hash_map_insert(key, val);
#ifdef LOCKS
    hash_map_unlock(hash.proc, hash.offset);
#endif
  }

  BARRIER();

  start = gasnett_ticks_now();

#ifdef LOCKS
  grt_lock_state_t state1, state2;
#endif
  for (i = 0; i < MY_NUM_OPS; ++i) {
    unsigned idx = grt_random_next() * MY_NUM_OPS;
    grt_word_t key1 = keys[i];
    unsigned second_idx = grt_random_next() * MY_NUM_OPS;
    grt_word_t key2 = keys[second_idx];
#ifdef LOCKS
    lock(key1, key2, &state1, &state2);
#endif
    grt_word_t val1, val2;
#ifndef LOCKS
#ifndef NOLOCKS
    stm_start(grt_id);
#endif
#endif
    grt_bool_t found1 = hash_map_find(key1, &val1);
    grt_bool_t found2 = hash_map_find(key2, &val2);
    hash_map_insert(key1, val2);
    hash_map_insert(key2, val1);
#ifndef LOCKS
#ifndef NOLOCKS
    stm_commit(grt_id);
#endif
#endif
#if LOCKS
    unlock(key1, key2);
#endif
  }

  end = gasnett_ticks_now();
  time = ((unsigned) gasnett_ticks_to_us(end - start));
  printf("processor %u: execution time=%f us\n", 
	 grt_id, (double) time);
  fflush(stdout);
  grt_write(0, time, &times[grt_id]);

  BARRIER();

  if (grt_id == 0) {
    time = 0, max_time = 0;
    for (i = 0; i < grt_num_procs; ++i) {
      gasnett_tick_t this_time = times[i];
      time += this_time;
      if (this_time >= max_time) max_time = this_time;
    }
    time_per_op = ((float) time) / params[NUM_OPS];
    printf("total CPU time=%f us\n", (double) time);
    printf("time per operation=%f us\n", time_per_op);
    printf("max time=%f us\n", (double) max_time);
  }

  BARRIER();

  hash_map_destroy();

  BARRIER();

}
Beispiel #8
0
sigjmp_buf *
hytm_start(TXPARAMS stm_tx_attr_t attr)
{
    TX_GET;
    unsigned long err;

    tx->retries = 0;
    /* Set status */
    UPDATE_STATUS(tx->status, TX_ACTIVE);
    stm_check_quiesce(tx);
    /* copy attributes if need to switch to software mode */
    tx->attr = attr;
    tx->start = rdtsc();

hytm_restart:
    /* All registers are lost when ASF aborts, thus we discard registers */
    asm volatile (ASF_SPECULATE
                  :"=a" (err)
                  :
                  :"memory","rbp","rbx","rcx","rdx","rsi","rdi",
                  "r8", "r9","r10","r11","r12","r13","r14","r15" );

    tx = tls_get_tx();
    if (unlikely(asf_status_code(err) != 0)) {
        /* Set status to ABORTED */
        SET_STATUS(tx->status, TX_ABORTED);
        tx->retries++;
        /* Error management */
        if (asf_status_code(err) == ASF_STATUS_CONTENTION) {
            if (tx->retries > ASF_ABORT_THRESHOLD) {
                /* There is too many conflicts, software will not help, start irrevocability. */
                stm_set_irrevocable(TXARGS 1);  /* Set irrevocable serial */
#if defined(TM_DTMC) || defined(TM_GCC)
                stm_set_irrevocable(TXARGS -1); /* Acquire irrevocability */
                UPDATE_STATUS(tx->status, TX_IRREVOCABLE);
                LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */
#else /* ! defined(TM_DTMC) && ! defined(TM_GCC) */
                /* Non-tm compiler doesn't have path without instrumentation. */
                tx->software = 1;
#endif /* ! defined(TM_DTMC) && ! defined(TM_GCC) */
            }
        } else if (asf_status_code(err) == ASF_STATUS_ABORT) {
            if (asf_abort_code(err) == ASF_FORCE_SOFTWARE) {
                tx->software = 1;
#ifdef IRREVOCABLE_ENABLED
            } else if(asf_abort_code(err) == ASF_RETRY_IRREVOCABLE) {
# if defined(TM_DTMC) || defined(TM_GCC)
                if (tx->irrevocable != 0) {
                    stm_set_irrevocable(TXARGS -1);
                    UPDATE_STATUS(tx->status, TX_IRREVOCABLE);
                    LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */
                }
# else /* ! defined(TM_DTMC) || defined(TM_GCC) */
                /* Non-tm compiler doesn't have path without instrumentation. */
                tx->software = 1;
# endif /* ! defined(TM_DTMC) || defined(TM_GCC) */
#endif /* IRREVOCABLE_ENABLED */
            } else {
                if (tx->retries > ASF_ABORT_THRESHOLD) {
                    tx->software = 1;
                }
            }
        } else {
            /* Other cases are critical and needs software mode */
            tx->software = 1;
        }
        if (tx->software) {
            /* Start a software transaction (it cannot use attr since the register/stack can be corrupted) */
            stm_start(TXARGS tx->attr);
            /* Restoring the context */
#if defined(TM_DTMC)
            LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */
#else /* ! defined(TM_DTMC) */
            LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */
#endif /* ! defined(TM_DTMC) */
        } else {
            uint64_t cur = (uint64_t)rdtsc();
            uint64_t wait = cur + (random() % (cur - tx->start)); /* XXX random but maybe not reliable */
            /* Waiting... */
            while (rdtsc() < wait);
            UPDATE_STATUS(tx->status, TX_ACTIVE);
            /* Check quiesce before to restart */
            stm_check_quiesce(tx);
            goto hytm_restart;
        }
    }

    /* Reset write set */
    tx->w_set.nb_entries = 0;

    if (tx->retries > 0) {
        /* Restoring registers for retry */
#if defined(TM_DTMC)
        LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */
#else /* ! defined(TM_DTMC) */
        LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */
#endif /* ! defined(TM_DTMC) */
    }

    return &tx->env;
}