Beispiel #1
0
void * _ITM_calloc(size_t nm, size_t size)
{
  stm_tx_t *tx = tls_get_tx();
  if (tx == NULL || !stm_active_tx(tx))
    return calloc(nm, size);
  return stm_calloc_tx(tx, nm, size);
}
Beispiel #2
0
_ITM_transaction * _ITM_CALL_CONVENTION _ITM_getTransaction(void)
{
  struct stm_tx *tx = tls_get_tx();
  if (unlikely(tx == NULL)) {
    /* Thread not initialized: must create transaction */
    tx = abi_init_thread();
  }

  return (_ITM_transaction *)tx;
}
Beispiel #3
0
void _ITM_free(void *ptr)
{
  stm_tx_t *tx = tls_get_tx();
  if (tx == NULL || !stm_active_tx(tx)) {
    free(ptr);
    return;
  }
#ifdef NO_WRITE_ON_FREE
  stm_free_tx(tx, ptr, 0);
#else
  stm_free_tx(tx, ptr, block_size(ptr));
#endif
}
Beispiel #4
0
static INLINE stm_tx_t *
abi_init_thread(void)
{
  stm_tx_t *tx = tls_get_tx();
  if (tx == NULL) {
    /* Make sure that the main initilization is done */
    if (ATOMIC_LOAD(&global_abi.status) != ABI_INITIALIZED)
      _ITM_initializeProcess();
    //t->thread_id = (int)ATOMIC_FETCH_INC_FULL(&global_abi.thread_counter);
    tx = stm_init_thread();
  }
  return tx;
}
Beispiel #5
0
static INLINE stm_tx_t *
abi_init_thread(void)
{
  stm_tx_t *tx = tls_get_tx();
  if (tx == NULL) {
    /* Make sure that the main initilization is done */
    if (ATOMIC_LOAD(&global_abi.status) != ABI_INITIALIZED)
      _ITM_initializeProcess();
    //t->thread_id = (int)ATOMIC_FETCH_INC_FULL(&global_abi.thread_counter);
    tx = stm_init_thread();
#ifdef STACK_CHECK
    get_stack_attr(&t->stack_addr_low, &t->stack_addr_high);
#endif /* STACK_CHECK */
  }
  return tx;
}
Beispiel #6
0
/*
 * Catch signal (to emulate non-faulting load).
 */
static void
signal_catcher(int sig)
{
  sigset_t block_signal;
  stm_tx_t *tx = tls_get_tx();

  /* A fault might only occur upon a load concurrent with a free (read-after-free) */
  PRINT_DEBUG("Caught signal: %d\n", sig);

  /* TODO: TX_KILLED should be also allowed */
  if (tx == NULL || tx->attr.no_retry || GET_STATUS(tx->status) != TX_ACTIVE) {
    /* There is not much we can do: execution will restart at faulty load */
    fprintf(stderr, "Error: invalid memory accessed and no longjmp destination\n");
    exit(1);
  }

  /* Unblock the signal since there is no return to signal handler */
  sigemptyset(&block_signal);
  sigaddset(&block_signal, sig);
  pthread_sigmask(SIG_UNBLOCK, &block_signal, NULL);

  /* Will cause a longjmp */
  stm_rollback(tx, STM_ABORT_SIGNAL);
}
Beispiel #7
0
/*
 * Get current transaction descriptor.
 */
_CALLCONV stm_tx_t *
stm_current_tx(void)
{
    return tls_get_tx();
}
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;
}