Exemplo n.º 1
0
/*
 * Called upon transaction abort.
 */
static void mod_cb_on_abort(TXPARAMS void *arg)
{
  mod_cb_info_t *icb;
  mod_cb_entry_t *ccb;

  if (!mod_cb_initialized) {
    fprintf(stderr, "Module mod_cb not initialized\n");
    exit(1);
  }

  icb = (mod_cb_info_t *)stm_get_specific(TXARGS mod_cb_key);
  assert(icb != NULL);

  /* Call abort callback */
  while ((ccb = icb->abort) != NULL) {
    icb->abort->f(icb->abort->arg);
    icb->abort = ccb->next;
    free(ccb);
  }
  /* Free commit callback */
  while ((ccb = icb->commit) != NULL) {
    icb->commit = ccb->next;
    free(ccb);
  }
}
Exemplo n.º 2
0
/*
 * Called by the CURRENT thread to allocate memory within a transaction.
 */
void *stm_malloc(TXPARAMS size_t size)
{
  /* Memory will be freed upon abort */
  mod_mem_info_t *mi;
  mod_mem_block_t *mb;

  if (!mod_mem_initialized) {
    fprintf(stderr, "Module mod_mem not initialized\n");
    exit(1);
  }

  mi = (mod_mem_info_t *)stm_get_specific(TXARGS mod_mem_key);
  assert(mi != NULL);

  /* Round up size */
  if (sizeof(stm_word_t) == 4) {
    size = (size + 3) & ~(size_t)0x03;
  } else {
    size = (size + 7) & ~(size_t)0x07;
  }

  if ((mb = (mod_mem_block_t *)malloc(sizeof(mod_mem_block_t))) == NULL) {
    perror("malloc");
    exit(1);
  }
  if ((mb->addr = malloc(size)) == NULL) {
    perror("malloc");
    exit(1);
  }
  mb->next = mi->allocated;
  mi->allocated = mb;

  return mb->addr;
}
Exemplo n.º 3
0
static void mod_free_record(void *addr, void (*rev_func)(void*))
{
  /* Memory disposal is delayed until commit */
  mod_alloc_info_t *mi;
  mod_alloc_block_t *mb;

  if (!mod_alloc_initialized) {
    fprintf(stderr, "Module mod_alloc not mod_alloc_initialized\n");
    exit(1);
  }

  mi = (mod_alloc_info_t *)stm_get_specific(mod_alloc_key);
  assert(mi != NULL);

  /* Overwrite to prevent inconsistent reads */
  /* TODO delete operators doesn't give the allocated size */
  /* Acquire lock and update version number */
  stm_store2(addr, 0, 0);
  /* Schedule for removal */
  if ((mb = (mod_alloc_block_t *)malloc(sizeof(mod_alloc_block_t))) == NULL) {
    perror("malloc");
    exit(1);
  }
  mb->addr = addr;
  mb->rev_func = rev_func;
  mb->next = mi->freed;
  mi->freed = mb;
}
Exemplo n.º 4
0
/*
 * Called upon transaction abort.
 */
static void mod_alloc_on_abort(void *arg)
{
  mod_alloc_info_t *mi;
  mod_alloc_block_t *mb, *next;

  mi = (mod_alloc_info_t *)stm_get_specific(mod_alloc_key);
  assert (mi != NULL);

  /* Dispose of memory allocated during transaction */
  if (mi->allocated != NULL) {
    mb = mi->allocated;
    while (mb != NULL) {
      next = mb->next;
      mb->rev_func(mb->addr);
      free(mb);
      mb = next;
    }
    mi->allocated = NULL;
  }

  /* Keep memory freed during transaction */
  if (mi->freed != NULL) {
    mb = mi->freed;
    while (mb != NULL) {
      next = mb->next;
      free(mb);
      mb = next;
    }
    mi->freed = NULL;
  }
}
Exemplo n.º 5
0
/*
 * Return statistics about current thread.
 */
int stm_get_local_stats(TXPARAMS const char *name, void *val)
{
  mod_stats_data_t *stats;

  if (!mod_stats_initialized) {
    fprintf(stderr, "Module mod_stats not initialized\n");
    exit(1);
  }

  stats = (mod_stats_data_t *)stm_get_specific(TXARGS mod_stats_key);
  assert(stats != NULL);

  if (strcmp("nb_commits", name) == 0) {
    *(unsigned long *)val = stats->commits;
    return 1;
  }
  if (strcmp("nb_aborts", name) == 0) {
    *(unsigned long *)val = stats->retries_acc;
    return 1;
  }
  if (strcmp("nb_retries_avg", name) == 0) {
    *(double *)val = (double)stats->retries_acc / stats->retries_cnt;
    return 1;
  }
  if (strcmp("nb_retries_min", name) == 0) {
    *(unsigned long *)val = stats->retries_min;
    return 1;
  }
  if (strcmp("nb_retries_max", name) == 0) {
    *(unsigned long *)val = stats->retries_max;
    return 1;
  }

  return 0;
}
Exemplo n.º 6
0
/*
 * Called upon thread deletion.
 */
static void mod_stats_on_thread_exit(TXPARAMS void *arg)
{
  mod_stats_data_t *stats;
  unsigned long max, min;

  stats = (mod_stats_data_t *)stm_get_specific(TXARGS mod_stats_key);
  assert(stats != NULL);

  ATOMIC_FETCH_ADD_FULL(&mod_stats_global.commits, stats->commits);
  ATOMIC_FETCH_ADD_FULL(&mod_stats_global.retries_cnt, stats->retries_cnt);
  ATOMIC_FETCH_ADD_FULL(&mod_stats_global.retries_acc, stats->retries_acc);
retry_max:
  max = ATOMIC_LOAD(&mod_stats_global.retries_max);
  if (stats->retries_max > max) {
    if (ATOMIC_CAS_FULL(&mod_stats_global.retries_max, max, stats->retries_max) == 0)
      goto retry_max;
  }
retry_min:
  min = ATOMIC_LOAD(&mod_stats_global.retries_min);
  if (stats->retries_min < min) {
    if (ATOMIC_CAS_FULL(&mod_stats_global.retries_min, min, stats->retries_min) == 0)
      goto retry_min;
  }

  free(stats);
}
Exemplo n.º 7
0
/*
 * Called upon transaction abort.
 */
static void mod_stats_on_abort(TXPARAMS void *arg)
{
  mod_stats_data_t *stats;

  stats = (mod_stats_data_t *)stm_get_specific(TXARGS mod_stats_key);
  assert(stats != NULL);

  stats->retries++;
}
static void mod_order_on_precommit(void *arg)
{
  stm_word_t my_ts, current_ts;
  my_ts = (stm_word_t)stm_get_specific(mod_order_key);
  /* Wait its turn... */
  do {
    current_ts = ATOMIC_LOAD(&mod_order_ts_commit);
    /* Check that we are not killed to keep the liveness, the transaction will
     * abort before to commit. Note that if the kill feature is not present, the
     * transaction must abort if it is not its turn to guarantee progress. */
    if (stm_killed())
      return;
  } while (current_ts != my_ts);
}
Exemplo n.º 9
0
/*
 * Called upon transaction commit.
 */
static void mod_stats_on_commit(TXPARAMS void *arg)
{
  mod_stats_data_t *stats;

  stats = (mod_stats_data_t *)stm_get_specific(TXARGS mod_stats_key);
  assert(stats != NULL);
  stats->commits++;
  stats->retries_acc += stats->retries;
  stats->retries_cnt++;
  if (stats->retries_min > stats->retries)
    stats->retries_min = stats->retries;
  if (stats->retries_max < stats->retries)
    stats->retries_max = stats->retries;
  stats->retries = 0;
}
Exemplo n.º 10
0
/*
 * Called by the CURRENT thread to free memory within a transaction.
 */
void stm_free2(TXPARAMS void *addr, size_t idx, size_t size)
{
  /* Memory disposal is delayed until commit */
  mod_mem_info_t *mi;
  mod_mem_block_t *mb;
  stm_word_t *a;

  if (!mod_mem_initialized) {
    fprintf(stderr, "Module mod_mem not mod_mem_initialized\n");
    exit(1);
  }

  mi = (mod_mem_info_t *)stm_get_specific(TXARGS mod_mem_key);
  assert(mi != NULL);

  /* TODO: if block allocated in same transaction => no need to overwrite */
  if (size > 0) {
    /* Overwrite to prevent inconsistent reads */
    if (sizeof(stm_word_t) == 4) {
      idx = (idx + 3) >> 2;
      size = (size + 3) >> 2;
    } else {
Exemplo n.º 11
0
static void mod_alloc_record(void *ptr, void (*rev_func)(void*))
{
  /* Memory will be freed upon abort */
  mod_alloc_info_t *mi;
  mod_alloc_block_t *mb;

  if (!mod_alloc_initialized) {
    fprintf(stderr, "Module mod_alloc not initialized\n");
    exit(1);
  }

  mi = (mod_alloc_info_t *)stm_get_specific(mod_alloc_key);
  assert(mi != NULL);

  if ((mb = (mod_alloc_block_t *)malloc(sizeof(mod_alloc_block_t))) == NULL) {
    perror("malloc");
    exit(1);
  }
  mb->addr = ptr;
  mb->rev_func = rev_func;
  mb->next = mi->allocated;
  mi->allocated = mb;
}
Exemplo n.º 12
0
/*
 * Register commit callback for the CURRENT transaction.
 */
int stm_on_commit(TXPARAMS void (*on_commit)(void *arg), void *arg)
{
  mod_cb_info_t *icb;
  mod_cb_entry_t *ccb;
  if (!mod_cb_initialized) {
    fprintf(stderr, "Module mod_cb not initialized\n");
    exit(1);
  }

  icb = (mod_cb_info_t *)stm_get_specific(TXARGS mod_cb_key);
  assert(icb != NULL);

  if ((ccb = malloc(sizeof(mod_cb_entry_t))) == NULL) {
    perror("mod_cb: cannot allocate memory");
    exit(1);
  }
  ccb->f = on_commit;
  ccb->arg = arg;
  ccb->next = icb->commit;
  
  icb->commit = ccb;

  return 1;
}
Exemplo n.º 13
0
/*
 * Called upon thread deletion.
 */
static void mod_alloc_on_thread_exit(void *arg)
{
  free(stm_get_specific(mod_alloc_key));
}
Exemplo n.º 14
0
/*
 * Called upon thread deletion.
 */
static void mod_cb_on_thread_exit(TXPARAMS void *arg)
{
  free(stm_get_specific(TXARGS mod_cb_key));
}