コード例 #1
0
ファイル: clone.c プロジェクト: HPDCS/stmEnergyOptimization
void * _ITM_CALL_CONVENTION
_ITM_getTMCloneOrIrrevocable (void *ptr)
{
  // if the function (ptr) have a TM version, give the pointer to the TM function 
  // otherwise, set transaction to irrevocable mode
  void *ret = find_clone (ptr);
  if (ret)
    return ret;

  /* TODO Check we are in an active transaction */
  //  if (stm_current_tx() != NULL && stm_is_active(tx))
    /* GCC always use implicit transaction descriptor */
    stm_set_irrevocable(1);

  return ptr;
}
コード例 #2
0
ファイル: abi.c プロジェクト: nmldiegues/proteustm
void _ITM_CALL_CONVENTION _ITM_changeTransactionMode(TX_ARGS
                              _ITM_transactionState __mode,
                              const _ITM_srcLocation *__loc)
{
  /* FIXME: it seems there is a problem with irrevocable and intel c */
  switch (__mode) {
    case modeSerialIrrevocable:
      stm_set_irrevocable(1);
      /* TODO a_runUninstrumentedCode must be set at rollback! */
      break;
    case modeObstinate:
    case modeOptimistic:
    case modePessimistic:
    default:
	fprintf(stderr, "This mode %d is not implemented yet\n", __mode);
  }
}
コード例 #3
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;
}
コード例 #4
0
ファイル: stm.c プロジェクト: kunulee/failsafe_heapo_source
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;
}