Beispiel #1
0
int
check(account_t *a1,  int thread_id)
{
  int amount=0;
  //lock ordering
  int n1=a1->number;

  //local_lock_read(&gl);
  if (use_locks != 0)
    {
      acquire_read(&local_th_data[thread_id][n1],&the_locks[n1]);
    }

  amount = a1->balance;

  if (use_locks != 0) 
    {
      MEM_BARRIER;
      release_read(cluster_id, &local_th_data[thread_id][n1],&the_locks[n1]);
    }
  //local_unlock_read(&gl);

  return amount;
}
Beispiel #2
0
rc_t
log_core::fetch(lsn_t& ll, void* buf, lsn_t* nxt, const bool forward)
{
    INC_TSTAT(log_fetches);

    lintel::atomic_thread_fence(lintel::memory_order_acquire);
    if (ll < _fetch_buf_end && ll >= _fetch_buf_begin)
    {
        // log record can be found in fetch buffer -- no I/O
        size_t i = ll.hi() - _fetch_buf_first;
        if (_fetch_buffers[i]) {
            logrec_t* rp = (logrec_t*) (_fetch_buffers[i] + ll.lo());
            w_assert1(rp->valid_header(ll));

            if (rp->type() == logrec_t::t_skip)
            {
                if (forward) {
                    ll = lsn_t(ll.hi() + 1, 0);
                    return fetch(ll, buf, nxt, forward);
                }
                else { // backward scan
                    ll = *((lsn_t*) (_fetch_buffers[i] + ll.lo() - sizeof(lsn_t)));
                }

                rp = (logrec_t*) (_fetch_buffers[i] + ll.lo());
                w_assert1(rp->valid_header(ll));
            }

            if (nxt) {
                if (!forward && ll.lo() == 0) {
                    auto p = _storage->get_partition(ll.hi() - 1);
                    *nxt = p ? lsn_t(p->num(), p->get_size()) : lsn_t::null;
                }
                else {
                    if (forward) {
                        *nxt = ll;
                        nxt->advance(rp->length());
                    }
                    else {
                        memcpy(nxt, (char*) rp - sizeof(lsn_t), sizeof(lsn_t));
                    }
                }
            }

            memcpy(buf, rp, rp->length());
            INC_TSTAT(log_buffer_hit);

            return RCOK;
        }
    }

    if (forward && ll >= durable_lsn()) {
        w_assert1(ll == durable_lsn());
        // reading the durable_lsn during recovery yields a skip log record,
        return RC(eEOF);
    }
    if (!forward && ll == lsn_t::null) {
        // for a backward scan, nxt pointer is set to null
        // when the first log record in the first partition is set
        return RC(eEOF);
    }

    auto p = _storage->get_partition(ll.hi());
    if(!p) { return RC(eEOF); }
    W_DO(p->open_for_read());

    logrec_t* rp;
    lsn_t prev_lsn = lsn_t::null;
    DBGOUT3(<< "fetch @ lsn: " << ll);
    W_COERCE(p->read(rp, ll, forward ? nullptr : &prev_lsn));
    w_assert1(rp->valid_header(ll));

    // handle skip log record
    if (rp->type() == logrec_t::t_skip)
    {
        p->release_read();
        if (forward) {
            DBGTHRD(<<"seeked to skip" << ll );
            DBGTHRD(<<"getting next partition.");
            ll = lsn_t(ll.hi() + 1, 0);

            p = _storage->get_partition(ll.hi());
            if(!p) { return RC(eEOF); }

            // re-read
            DBGOUT3(<< "fetch @ lsn: " << ll);
            W_DO(p->open_for_read());
            W_COERCE(p->read(rp, ll));
            w_assert1(rp->valid_header(ll));
        }
        else { // backward scan