示例#1
0
/*
 * Initialize the transaction descriptor before start or restart.
 */
static inline void stm_prepare(stm_tx_t *tx)
{
 start:
  /* Start timestamp */
  tx->start = tx->end = GET_CLOCK; /* OPT: Could be delayed until first read/write */

  /* Allow extensions */
  tx->can_extend = 1;
  if (tx->start >= VERSION_MAX) {
    /* Block all transactions and reset clock */
    stm_quiesce_barrier(tx, rollover_clock, NULL);
    goto start;
  }
  /* Read/write set */
  tx->w_set.has_writes = 0;
  tx->w_set.nb_entries = 0;
  tx->r_set.nb_entries = 0;


  /* Set status */
  UPDATE_STATUS(tx->status, TX_ACTIVE);

  stm_check_quiesce(tx);
}
示例#2
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;
}