Exemple #1
0
w_rc_t    sthread_t::cold_startup()
{

    _class_list = new sthread_list_t(W_LIST_ARG(sthread_t, _class_link),
                                     &_class_list_lock);
    if (_class_list == 0)
        W_FATAL(fcOUTOFMEMORY);

    // initialize the global RNG
    struct timeval now;
    gettimeofday(&now, NULL);
    // Set the seed for the clib random-number generator, which
    // we use to seed the per-thread RNG
    ::srand(now.tv_usec);

    /*
     * Boot the main thread onto the current (system) stack.
     */
    sthread_main_t *main = new sthread_main_t;
    if (!main)
        W_FATAL(fcOUTOFMEMORY);
    me_lval() = _main_thread = main;
    W_COERCE( main->fork() );

    if (me() != main)
        W_FATAL(stINTERNAL);

#if defined(PURIFY)
    /* The main thread is different from all other threads. */
    purify_name_thread(me()->name());
#endif

    return RCOK;
}
Exemple #2
0
sthread_t::sthread_t(priority_t        pr,
                     const char     *nm,
                     unsigned        stack_size)
    : sthread_named_base_t(nm),
      user(0),
      id(_next_id++), // make it match the gdb threads #. Origin 1
      _start_terminate_lock(new pthread_mutex_t),
      _start_cond(new pthread_cond_t),
      _sleeping(false),
      _forked(false),
      _terminated(false),
      _unblock_flag(false),
      _core(0),
      _status(t_virgin),
      _priority(pr),
      _rce(stOK)
{
    if(!_start_terminate_lock || !_start_cond )
        W_FATAL(fcOUTOFMEMORY);

    DO_PTHREAD(pthread_cond_init(_start_cond, NULL));
    DO_PTHREAD(pthread_mutex_init(_start_terminate_lock, NULL));

    _core = new sthread_core_t;
    if (!_core)
        W_FATAL(fcOUTOFMEMORY);
    _core->sthread = (void *)this;  // not necessary, but might
    // be useful for debugging

    /*
     *  Set a valid priority level
     */
    if (_priority > max_priority)
        _priority = max_priority;
    else if (_priority <= min_priority)
        _priority = min_priority;

    /*
     *  Initialize the core.
     */
    DO_PTHREAD(pthread_mutex_init(&_wait_lock, NULL));
    DO_PTHREAD(pthread_cond_init(&_wait_cond, NULL));

    /*
     * stash the procedure (sthread_t::_start)
     * and arg (this)
     * in the core structure, along with
     * status info.
     * and if this is not the _main_thread (running in
     * the system thread, i.e., in an already-running pthread)
     * then create a pthread for it and give it a starting function
     // TODO: should probably merge sthread_core_pthread.cpp in here
     */
    if (sthread_core_init(_core, __start, this, stack_size) == -1) {
        cerr << "sthread_t: cannot initialize thread core" << endl;
        W_FATAL(stINTERNAL);
    }
}
Exemple #3
0
void smthread_t::_initialize_fingerprint()
{
// We can see if we might be getting false positives here.
// If we make the finger print maps unique, we can eliminate that
// possibility.
#define DEBUG_FINGERPRINTS 0
#if DEBUG_FINGERPRINTS
    int tries=0;
    const int trylimit = 50;
    bool bad=true;
    while ( (bad = _try_initialize_fingerprint()) )
    { 
        _uninitialize_fingerprint();
        if(++tries > trylimit) {
            fprintf(stderr, 
    "Could not make non-overlapping fingerprint after %d tries; %d out of %d bits are inuse\n",
            tries, all_fingerprints.num_bits_set(), all_fingerprints.num_bits());
            // note: there's a race here but if servers are
            // creating a pool of threads at start-up, this 
            // is still useful info:
            if(all_fingerprints.is_full()) {
                fprintf(stderr, 
            "collective thread map is full: increase #bits an recompile.\n");
            }
            W_FATAL(smlevel_0::eTHREADMAPFULL);
        }
    }
#else
    (void) _try_initialize_fingerprint();
#endif
}
Exemple #4
0
/*********************************************************************
 *
 *  scan_index_i::finish()
 *
 *  Terminate the scan.
 *
 *********************************************************************/
void 
scan_index_i::finish()
{
    _eof = true;
    switch (ntype)  {
    case t_btree:
    case t_uni_btree:
    case t_mrbtree:
    case t_uni_mrbtree:
    case t_mrbtree_l:
    case t_uni_mrbtree_l:
    case t_mrbtree_p:
    case t_uni_mrbtree_p:
        if (_btcursor)  {
            delete _btcursor;
            _btcursor = 0;
        }
        break;
    case t_bad_ndx_t:
        // error must have occured during init
        break;
    default:
        W_FATAL(eINTERNAL);
    }
}
Exemple #5
0
void
ErrLog::_openlogfile(
    const char *fn      
) 
{
    const char *filename=fn;
    if(strcmp(filename, "-")==0) {
        // std::cerr << "log to stderr" << std::endl;
        _destination = log_to_stderr;
        _file = stderr;
        return;
    }
    if(filename) {
        _destination = log_to_unix_file;
        if(strncmp(filename, "unix:", 5) == 0) {
            filename += 5;
        } else if (strncmp(filename, "shore:", 6) == 0) {
            filename += 6;
        }
        _file = fopen(filename, "a+");
        if(_file == NULL) {
            w_rc_t e = RC(fcOS);
            std::cerr << "Cannot fopen Unix file " << filename << std::endl;
            std::cerr << e << std::endl;
            W_COERCE(e);
        }
    } else {
        std::cerr << "Unknown logging destination." << std::endl;
        W_FATAL(fcINTERNAL);
    }

}
Exemple #6
0
int main(int argc, char **argv)
{
	int i;
	int	threads;

	if (parse_args(argc, argv) == -1)
		return 1;

	if (mix_it_up)
		threads = NumFloatThreads + NumIntThreads;
	else
		threads = NumFloatThreads > NumIntThreads ?
			    NumFloatThreads : NumIntThreads;

	ack = new int[threads];
	if (!ack)
		W_FATAL(fcOUTOFMEMORY);
	worker = new sthread_t *[threads];
	if (!worker)
		W_FATAL(fcOUTOFMEMORY);

	for (i=0; i<NumIntThreads; ++i) {
		ack[i] = 0;
		worker[i] = new int_thread_t(i);
		w_assert1(worker[i]);
		W_COERCE( worker[i]->fork() );
	}

	if (!mix_it_up)
		harvest(NumIntThreads);

	int	base = mix_it_up ? NumIntThreads : 0;
	
	for(i=base ; i < base + NumFloatThreads; ++i){
		ack[i] = 0;
		worker[i] = new float_thread_t(i);
		w_assert1(worker[i]);
		W_COERCE( worker[i]->fork() );
	}
	harvest(mix_it_up ? threads : NumFloatThreads);

	delete [] worker;
	delete [] ack;

	return 0;
}
Exemple #7
0
NORET
w_bitmap_t::w_bitmap_t(uint4_t size)
    : sz(size), mem_alloc(true)
{
    int n = bytesForBits(size);
    ptr = new uint1_t[n] ;
    if (!ptr) W_FATAL(fcOUTOFMEMORY) ; 
}
Exemple #8
0
void normal()
{
    int    i;
    int    n;
    stime_test_t    *raw;

    cout << "============ NORMAL ==================" << endl;

    raw = new stime_test_t[100];
    if (!raw)
        W_FATAL(fcOUTOFMEMORY);
    n = 0;

    /* normal form w/ tod == 0 */
    new (raw + n++) stime_test_t(0, 8);
    new (raw + n++) stime_test_t(0, -8);
    new (raw + n++) stime_test_t(0, hires + 8);
    new (raw + n++) stime_test_t(0, -hires - 9);

    /* normal form w/ non-zero tod */
    new (raw + n++) stime_test_t(tod, 8);
    new (raw + n++) stime_test_t(tod, hires + 8);
    new (raw + n++) stime_test_t(-tod, -8);
    new (raw + n++) stime_test_t(-tod, -hires - 8);

    /* sign correction w/out normal */
    new (raw + n++) stime_test_t(tod, 9);
    new (raw + n++) stime_test_t(tod, -9);
    new (raw + n++) stime_test_t(-tod, -9);
    new (raw + n++) stime_test_t(-tod, 9);

    /* sign correction w/ normal */
    new (raw + n++) stime_test_t(tod, hires + 7);
    new (raw + n++) stime_test_t(tod, -hires - 7);
    new (raw + n++) stime_test_t(-tod, -hires - 7);
    new (raw + n++) stime_test_t(-tod, hires + 7);

    for (i = 0; i < n; i++) {
        stime_test_t    _norm, norm;

        _norm = norm = raw[i];

        _norm._normalize();
        norm.normalize();

        W_FORM(cout)("[%d] == ", i);
        cout << raw[i];
        cout << " to " << _norm;
        if (norm != _norm)
            cout << " AND " << norm << "   XXX";

        cout << endl;
    }
        
    delete [] raw;
}
Exemple #9
0
void arithmetic()
{
    int    i;
    int    n;
    stime_pair    *raw;

    cout << "============ ARITHMETIC ==================" << endl;

    raw = new stime_pair[100];
    if (!raw)
        W_FATAL(fcOUTOFMEMORY);
    n = 0;

    raw[n].l = stime_test_t(0,  8);
    raw[n++].r = stime_test_t(0,  5);

    raw[n].l = stime_test_t(1, hires-7);
    raw[n++].r = stime_test_t(1, 8);

    raw[n].l = stime_test_t(1, hires-7);
    raw[n++].r = stime_test_t(0, 8);

    raw[n].l = stime_test_t(1, 8);
    raw[n++].r = stime_test_t(-2, -9);

    cout << "================== add / subtract =============" << endl;
    for (i = 0; i < n; i++) {
        W_FORM(cout)("[%d] => ", i);
        cout << raw[i].l << " op ";
        cout << raw[i].r << ": ";

        cout << " +: " << (stime_test_t)(raw[i].l + raw[i].r);
        cout << ", +': " << (stime_test_t)(raw[i].r + raw[i].l);
        cout << ", -: " << (stime_test_t)(raw[i].l - raw[i].r);
        cout << ", -': " << (stime_test_t)(raw[i].r - raw[i].l);

        cout << endl;
    }

    cout << "================== scaling ==============" << endl;
    for (i = 0; i < n; i++) {
        W_FORM(cout)("[%d] => ", i);
        cout << raw[i].l;

        cout << "  * " << (stime_test_t)(raw[i].l * 2);
        cout << "  *' " << (stime_test_t)(raw[i].l * 2.0);

        cout << "  / " << (stime_test_t)(raw[i].l / 2);
        cout << "  /' " << (stime_test_t)(raw[i].l / 2.0);

        cout << endl;
    }

        
    delete [] raw;
}
Exemple #10
0
/*********************************************************************
 *
 *  chkpt_m::spawn_chkpt_thread()
 *
 *  Fork the checkpoint thread.
 *
 *********************************************************************/
void
chkpt_m::spawn_chkpt_thread()
{
    w_assert1(_chkpt_thread == 0);
    if (smlevel_0::log)  {
        /* Create thread (1) to take checkpoints */
        _chkpt_thread = new chkpt_thread_t;
        if (! _chkpt_thread)  W_FATAL(eOUTOFMEMORY);
        W_COERCE(_chkpt_thread->fork());
    }
}
Exemple #11
0
shpid_t lg_tag_chunks_h::_pid(uint4_t pid_num) const
{
    FUNC(lg_tag_chunks_h::_pid);
    for (int i = 0; i < _cref.chunk_cnt; i++) {
        if (_cref.chunks[i].npages > pid_num) {
            return _cref.chunks[i].pid(pid_num);
        }
        pid_num -= _cref.chunks[i].npages;
    }
    W_FATAL(smlevel_0::eINTERNAL);
    return 0;  // keep compiler quiet
}
Exemple #12
0
void
ErrLog::_init2()
{
    ErrLogInfo *ei;
    if((ei = _tab.search(this->_ident)) == 0) {
		ei = new ErrLogInfo(this);
		_tab.put_in_order(ei); // not really ordered
    } else {
		std::cerr <<  "An ErrLog called " << _ident << " already exists." << std::endl;
		W_FATAL(fcINTERNAL);
    }
}
Exemple #13
0
rc_t
lid_m::generate_new_volid(lvid_t& lvid)
{
    FUNC(lid_m::_generate_new_volid);
    /*
     * For now the logical volume ID will consists of
     * the machine network address and the current time-of-day.
     *
     * Since the time of day resolution is in seconds,
     * we protect this function with a mutex to guarantee we
     * don't generate duplicates.
     */
    static long  last_time = 0;
    const int    max_name = 100;
    char         name[max_name+1];

    // Mutex only for generating new volume ids.
    static queue_based_block_lock_t lidmgnrt_mutex;
    CRITICAL_SECTION(cs, lidmgnrt_mutex);

#ifdef HAVE_UTSNAME
    struct        utsname uts;
    if (uname(&uts) == -1) return RC(eOS);
    strncpy(name, uts.nodename, max_name);
#else
    if (gethostname(name, max_name)) return RC(eOS);
#endif

    struct hostent* hostinfo = gethostbyname(name);

    if (!hostinfo)
        W_FATAL(eINTERNAL);

    memcpy(&lvid.high, hostinfo->h_addr, sizeof(lvid.high));
    DBG( << "lvid " << lvid );

    /* XXXX generating ids fast enough can create a id time sequence
       that grows way faster than real time!  This could be a problem!
       Better time resolution than seconds does exist, might be worth
       using it.  */
    stime_t curr_time = stime_t::now();

    if (curr_time.secs() > last_time)
            last_time = curr_time.secs();
    else
            last_time++;

    lvid.low = last_time;

    return RCOK;
}
Exemple #14
0
void doErrorTests()
{
        if (TestAssert) {
                OUT << endl << "** Generating an assertion failure." << endl;
                FLUSHOUT;
                w_assert1(false);
        }

        if (TestFatal) {
                OUT << endl << "** Generating a fatal error." << endl;
                FLUSHOUT;
                W_FATAL(fcINTERNAL);
        }
}
Exemple #15
0
/*********************************************************************
 *
 *  logrec_t::type_str()
 *
 *  Return a string describing the type of the log record.
 *
 *********************************************************************/
const char*
logrec_t::get_type_str(kind_t type)
{
    switch (type)  {
#        include "logstr_gen.cpp"
    default:
      return 0;
    }

    /*
     *  Not reached.
     */
    W_FATAL(eINTERNAL);
    return 0;
}
Exemple #16
0
void 
smthread_t::attach_xct(xct_t* x)
{
    // can't attach more than one xct to a thread
    // if called from sm, caller should have checked for this already, 
    // but if called from vas directly, we need to check.
    if(tcb().xct != NULL) {
        W_FATAL(smlevel_0::eTWOTRANS);
    }

    tcb().xct = x;
    x->attach_thread();
    // descends to xct_impl::attach_thread()
    // which grabs the 1thread mutex, calls new_xct, releases the mutex.
}
Exemple #17
0
void
bf_prefetch_thread_t::new_state(int i, prefetch_event_t e)
{
    FUNC(bf_prefetch_thread_t::new_state);
    // ASSUMES CALLER HAS THE MUTEX

    prefetch_status_t        nw;
    prefetch_status_t        old;
    bf_prefetch_thread_t::frame_info &inf = _info[i];
    old = inf._status;
    if( (nw = _table[old][e]) == pf_fatal) {
        std::cerr << "Bad transition for state " << int(old)
                << " and event " << int(e)
                <<std::endl;
        W_FATAL(fcINTERNAL);
    }
    DBGTHRD(<< " change : _table[" << int(old) << "," << int(e)
        << "] ->" << int(nw));

    inf._status = nw;
    if(old != nw) {
        switch(nw) {
        case pf_failure:
            w_assert3(_fix_error.is_error());
            _fix_error_i = i;
            break;
        case pf_grabbed:
            w_assert3(_n == 2);
            DBGTHRD(<<"BUMPING INDEX from " << _f 
                << " to " << (1-_f)
                );
            _f = 1-_f;
            break;
        case pf_init:
            if(old != pf_failure) {
                inf._page.unfix();
            }
            break;
        case pf_available:
            // Must unfix because the fetching thread
            // cannot do so.
            inf._page.unfix();
            break;
        default:
            break;
        }
    }
}
Exemple #18
0
/* check all threads */
void sthread_t::check_all_stacks(const char *file, int line)
{
    w_list_i<sthread_t, queue_based_lock_t> i(*_class_list);
    unsigned    corrupt = 0;

    while (i.next())  {
        if (! i.curr()->isStackOK(file, line))
            corrupt++;
    }

    if (corrupt > 0) {
        cerr << "sthread_t::check_all: " << corrupt
             << " thread stacks, dieing" << endl;
        W_FATAL(fcINTERNAL);
    }
}
Exemple #19
0
w_rc_t sthread_t::set_priority(priority_t priority)
{
    CRITICAL_SECTION(cs, _wait_lock);
    _priority = priority;

    // in this statement, <= is used to keep gcc -Wall quiet
    if (_priority <= min_priority) _priority = min_priority;
    if (_priority > max_priority) _priority = max_priority;

    if (_status == t_ready)  {
        cerr << "sthread_t::set_priority()  :- "
             << "cannot change priority of ready thread" << endl;
        W_FATAL(stINTERNAL);
    }

    return RCOK;
}
Exemple #20
0
void 
smthread_t::detach_xct(xct_t* x)
{
    // Had better have a thread from which to detach.
    // if called from sm, caller should have checked for this already, 
    // but if called from vas directly, we need to check.
    if(tcb().xct == NULL) {
        W_FATAL(smlevel_0::eNOTRANS);
    }

    DBGTHRD(<<"detach: ");


    // descends to xct_impl::detach_thread()
    // which grabs the 1thread mutex, calls no_xct, releases the mutex.
    x->detach_thread();
    tcb().xct = NULL;
}
int main(int argc, char* argv[])
{
        smthread_main_t *smtu = new smthread_main_t(argc, argv);
        if (!smtu)
                W_FATAL(fcOUTOFMEMORY);

        w_rc_t e = smtu->fork();
        if(e.is_error()) {
            cerr << "error forking thread: " << e <<endl;
            return 1;
        }
        e = smtu->join();
        if(e.is_error()) {
            cerr << "error forking thread: " << e <<endl;
            return 1;
        }

        int        rv = smtu->retval;
        delete smtu;

        return rv;
}
Exemple #22
0
/*********************************************************************
 *
 *  chkpt_m::take()
 *
 *  Take a checkpoint. A Checkpoint consists of:
 *    1. Checkpoint Begin Log    (chkpt_begin)
 *    2. Checkpoint Device Table Log(s) (chkpt_dev_tab)
 *        -- all mounted devices
 *    3. Checkpoint Buffer Table Log(s)  (chkpt_bf_tab)
 *        -- dirty page entries in bf and their recovery lsn
 *    4. Checkpoint Transaction Table Log(s) (chkpt_xct_tab)
 *        -- active transactions and their first lsn
 *    5. Checkpoint Prepared Transactions (optional)
 *        -- prepared transactions and their locks
 *         (using the same log records that prepare does)
 *    6. Checkpoint End Log (chkpt_end)
 *
 *********************************************************************/
void chkpt_m::take()
{
    FUNC(chkpt_m::take);
    if (! log)   {
        /*
         *  recovery facilities disabled ... do nothing
         */
        return;
    }
    INC_TSTAT(log_chkpt_cnt);
    
    /*
     *  Allocate a buffer for storing log records
     */
    w_auto_delete_t<logrec_t> logrec(new logrec_t);

    /*
     * checkpoints are fuzzy
     * but must be serialized wrt each other.
     *
     * Acquire the mutex to serialize prepares and
     * checkpoints. 
     *
     * NB: EVERYTHING BETWEEN HERE AND RELEASING THE MUTEX
     * MUST BE W_COERCE (not W_DO).
     */
    chkpt_serial_m::chkpt_acquire();
 retry:
    
    /*
     * FRJ: We must somehow guarantee that the log always has space to
     * accept checkpoints.  We impose two constraints to this end:
     *
     * 1. We cap the total space checkpoints are allowed to consume in
     *    any one log partition. This is a good idea anyway because
     *    checkpoint size is linear in the number of dirty buffer pool
     *    pages -- ~2MB per GB of dirty data -- and yet the utility of
     *    checkpoints drops off quickly as the dirty page count
     *    increases -- log analysis and recovery must start at the lsn
     *    of the oldest dirty page regardless of how recent the
     *    checkpoint was.
     *
     * 2. No checkpoint may depend on more than /max_openlog-1/ log
     *    partitions. In other words, every checkpoint completion must
     *    leave at least one log partition available.
     *
     * We use these two constraints, together with log reservations,
     * to guarantee the ability to reclaim log space if the log
     * becomes full. The log maintains, on our behalf, a reservation
     * big enough for two maximally-sized checkpoints (ie the dirty
     * page table lists every page in the buffer pool). Every time we
     * reclaim a log segment this reservation is topped up atomically.
     */
#define LOG_INSERT(constructor_call, rlsn)            \
    do {                            \
    new (logrec) constructor_call;                \
    W_COERCE( log->insert(*logrec, rlsn) );            \
    if(!log->consume_chkpt_reservation(logrec->length())) {    \
        W_FATAL(eOUTOFLOGSPACE);                \
    }                            \
    } while(0)
    
    /* if current partition is max_openlog then the oldest lsn we can
       tolerate is 2.0. We must flush all pages dirtied before that
       time and must wait until all transactions with an earlier
       start_lsn have ended (at worst they will abort if the log fills
       up before they can commit).

       TODO: use smlevel_0::log_warn_callback to notify the VAS in
       case old transactions are't currently active for some reason.

       Also, remember the current checkpoint count so we can see
       whether we get raced...
     */
// #warning "TODO use log_warn_callback in case old transactions aren't logging right now"
    long curr_pnum = log->curr_lsn().file();
    long too_old_pnum = std::max(0l, curr_pnum - max_openlog+1);
    if(!log->verify_chkpt_reservation()) {
    /* Yikes! The log can't guarantee that we'll be able to
       complete any checkpoint after this one, so we must reclaim
       space even if the log doesn't seem to be full.
    */
		long too_old_pnum = log->global_min_lsn().file();
		if(too_old_pnum == curr_pnum) {
			// how/why did they reserve so much log space???
			W_FATAL(eOUTOFLOGSPACE);
		}
	}

	/* We cannot proceed if any transaction has a too-low start_lsn;
	   wait for them to complete before continuing.
	   
	   WARNING: we have to wake any old transactions which are waiting
	   on locks, or we risk deadlocks where the lock holder waits on a
	   full log while the old transaction waits on the lock.
	 */
	lsn_t oldest_valid_lsn = log_m::first_lsn(too_old_pnum+1);
	old_xct_tracker tracker;
    { 
    xct_i it(true); // do acquire the xlist_mutex...
    while(xct_t* xd=it.next()) {
        lsn_t const &flsn = xd->first_lsn();
        if(flsn.valid() && flsn < oldest_valid_lsn) {
			// poison the transaction and add it to the list...
			xd->force_nonblocking();
			tracker.track(xd);
        }
    }
    }

    /* release the chkpt_serial to do expensive stuff

       We'll record the current checkpoint count so we can detect
       whether we get raced during the gap.
     */
    long chkpt_stamp = _chkpt_count;
    chkpt_serial_m::chkpt_release();

    
    // clear out all too-old pages
    W_COERCE(bf->force_until_lsn(oldest_valid_lsn, false));

    /* hopefully the page cleaning took long enough that the old
       transactions all ended...
     */
    if(!tracker.finished())
       tracker.wait_for_all();

    // raced?
    chkpt_serial_m::chkpt_acquire();
    if(_chkpt_count != chkpt_stamp)
    goto retry;
    
    /*
     *  Finally, we're ready to start the actual checkpoint!
     *
     *  Write a Checkpoint Begin Log and record its lsn in master
     */
    lsn_t master;
    LOG_INSERT(chkpt_begin_log(io->GetLastMountLSN()), &master);

    /*
     *  Checkpoint the buffer pool dirty page table, and record
     *  minimum of the recovery lsn of all dirty pages.
     *
     *  We could do this (very slow) operation before grabbing the
     *  checkpoint mutex because all pages can do is get younger by
     *  being flushed; no page can become older than the min_rec_lsn
     *  we record here ... however, we have to serialize checkpoints
     *  because, although they are fuzzy, they cannot intermingle.
     *  One must complete before another starts. Recovery relies
     *  on it.  Either everyone uses wakeup_and_take or they (dismount,
     *  mount, etc) wait on this.
     *
     *  The srv_log does wakeup_and_take() whenever a new partition is
     *  opened, and it might be that a checkpoint is spanning a 
     *  partition.
     */
    lsn_t min_rec_lsn = lsn_t::max;
    {
        int     bfsz = bf->npages();
        const     int chunk = chkpt_bf_tab_t::max;

        w_auto_delete_array_t<lpid_t> pid(new lpid_t[chunk]);
        w_auto_delete_array_t<lsn_t> rec_lsn(new lsn_t[chunk]);
        w_assert1(pid && rec_lsn);

        int total_count = 0;
        for (int i = 0; i < bfsz; )  {
            /*
             *  Loop over all buffer pages
             */
            int count = chunk;
            // Have the minimum rec_lsn of the bunch
            // returned iff it's less than the value passed in
            W_COERCE( bf->get_rec_lsn(i, count, pid, rec_lsn, min_rec_lsn) );
            if (count)  {
                total_count+= count;


                /*
                 *  Write a Buffer Table Log
                 */
                LOG_INSERT(chkpt_bf_tab_log(count, pid, rec_lsn), 0);
            }
        }
        //fprintf(stderr, "Checkpoint found %d dirty pages\n", total_count);
    }


    /*
     *  Checkpoint the dev mount table
     */
    {
        /*
         *  Log the mount table in "max loggable size" chunks.
         */
        // XXX casts due to enums
        const int chunk = (int)max_vols > (int)chkpt_dev_tab_t::max 
            ? (int)chkpt_dev_tab_t::max : (int)max_vols;
        int dev_cnt = io->num_vols();

        int    i;
        char        **devs;
        devs = new char *[chunk];
        if (!devs)
            W_FATAL(fcOUTOFMEMORY);
        for (i = 0; i < chunk; i++) {
            devs[i] = new char[max_devname+1];
            if (!devs[i])
                W_FATAL(fcOUTOFMEMORY);
        }
        vid_t        *vids;
        vids = new vid_t[chunk];
        if (!vids)
            W_FATAL(fcOUTOFMEMORY);

        for (i = 0; i < dev_cnt; i += chunk)  {
            
            int ret;
            W_COERCE( io->get_vols(i, MIN(dev_cnt - i, chunk),
                          devs, vids, ret));
            if (ret)  {
                /*
                 *  Write a Checkpoint Device Table Log
                 */
                // XXX The bogus 'const char **' cast is for visual c++
                LOG_INSERT(chkpt_dev_tab_log(ret, (const char **) devs, vids), 0);
            }
        }
        delete [] vids;
        for (i = 0; i < chunk; i++)
            delete [] devs[i];
        delete [] devs;
    }


    /*
     *  Checkpoint the transaction table, and record
     *  minimum of first_lsn of all transactions.
     */
    lsn_t min_xct_lsn = lsn_t::max;
    {
        const int    chunk = chkpt_xct_tab_t::max;
        tid_t        youngest = xct_t::youngest_tid();
        w_auto_delete_array_t<tid_t> tid(new tid_t[chunk]);
        w_auto_delete_array_t<xct_state_t> state(new xct_state_t[chunk]);
        w_auto_delete_array_t<lsn_t> last_lsn(new lsn_t[chunk]);
        w_auto_delete_array_t<lsn_t> undo_nxt(new lsn_t[chunk]);

        /* Keep the transaction list static while we write the state of
           prepared transactions.  Without the lock the list could change
           underneath this checkpoint. Note that we are using the
           iterator without locking because we own the lock.

           FRJ: even though xct_i now locks in a fully safe way, we
           want to hold the mutex longer than it's in scope so we
           continue using manual locking.
        */
        xct_i x(true); // true -> acquire the mutex

        const xct_t* xd = 0;
        do {
            int i = 0;
            while (i < chunk && (xd = x.next()))  {
                /*
                 *  Loop over all transactions and record only
                 *  xcts that dirtied something.
                 *  Skip those that have ended but not yet
                 *  been destroyed.
                 */
                if( xd->state() == xct_t::xct_ended) {
                   continue;
                }
                if (xd->first_lsn().valid())  {
                    tid[i] = xd->tid();
                    state[i] = xd->state();
                    //
                    // NOTE: aborting xcts are installed as active -
                    // they will be aborted on restart if not ended
                    // by the time we restart.
                    if (state[i] == xct_t::xct_aborting) 
                        state[i] = xct_t::xct_active;
                    //

                    if (state[i] == xct_t::xct_prepared)  {
                        DBG(<< tid[i] <<" is prepared -- logging as active");
                        state[i] = xct_t::xct_active;
                    }
                    //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    // don't worry - it
                    // will be prepared in the next section.
                    // this just makes recovery debug-checking
                    // a little easier
                    /////////////////////////////////////////

                    last_lsn[i] = xd->last_lsn();
                    undo_nxt[i] = xd->undo_nxt();
                    
                    if (min_xct_lsn > xd->first_lsn())
                        min_xct_lsn = xd->first_lsn();

                    i++;
                }
            }

            /*
            // We *always* have to write this record, because we have
            // to record the youngest xct!!!! NEH
            // if (i)  
            */
            {
                /*
                 *  Write a Transaction Table Log
                 */
        LOG_INSERT(chkpt_xct_tab_log(youngest, i, tid, state,
                                   last_lsn, undo_nxt), 0);
            }
        } while (xd);
Exemple #23
0
/*********************************************************************
 *
 *  scan_index_i::_fetch(key, klen, el, elen, skip)
 *
 *  Fetch current entry into "key" and "el". If "skip" is true,
 *  advance the scan to the next qualifying entry.
 *
 *********************************************************************/
rc_t
scan_index_i::_fetch(
    vec_t*         key, 
    smsize_t*         klen, 
    vec_t*         el, 
    smsize_t*         elen,
    bool         skip)
{
    // Check if error condition occured.
    if (_error_occurred.is_error()) {
        if(_error_occurred.err_num() == eBADCMPOP) {
            _eof = true;
            return RCOK;
        }
        return w_rc_t(_error_occurred);
    }

    SM_PROLOGUE_RC(scan_index_i::_fetch, in_xct, read_only, 0);

    /*
     *  Check if scan is terminated.
     */
    if (_finished)  {
        return RC(eBADSCAN);
    }
    if (_eof)  {
        return RC(eEOF);
    }
    w_assert1(xct()->tid() == tid);
    switch (ntype)  {
    case t_btree:
    case t_uni_btree:
    case t_mrbtree:
    case t_uni_mrbtree:
    case t_mrbtree_l:
    case t_uni_mrbtree_l:
    case t_mrbtree_p:
    case t_uni_mrbtree_p:
        if (skip) {
            /*
             *  Advance cursor.
             */
            do {
                DBG(<<"");
                W_DO( bt->fetch(*_btcursor, _bIgnoreLatches) );
                if(_btcursor->eof()) break;
            } while (_skip_nulls && (_btcursor->klen() == 0));
        }
        break;

    case t_bad_ndx_t:
    default:
        W_FATAL(eINTERNAL);
    }

    /*
     *  Copy result to user buffer.
     */
    if (_btcursor->eof())  {
        DBG(<<"eof");
        _eof = true;
    } else {
Exemple #24
0
TEST (ThreadTest1, All)
{
    int i;

    if (NumThreads) {
            ack = new int[NumThreads];
            if (!ack)
                    W_FATAL(fcOUTOFMEMORY);

            worker = new worker_thread_t *[NumThreads];
            if (!worker)
                    W_FATAL(fcOUTOFMEMORY);

            /* print some stuff */
            for(i=0; i<NumThreads; ++i) {
                        OUT << "creating i= " << i << endl; FLUSHOUT;
                    ack[i] = 0;
                    worker[i] = new worker_thread_t(i);
                    EXPECT_TRUE(worker[i] != NULL);
                    EXPECT_FALSE(worker[i]->fork().is_error());
                        OUT << "forked i= " << i << endl; FLUSHOUT;
            }

            if (DumpThreads) {
                        OUT << "";
                    sthread_t::dumpall("dump", _out);
                        FLUSHOUT;
                }

                ::usleep(2);

            for(i=0; i<NumThreads; ++i) {
                        OUT << "joining i= " << i << endl; FLUSHOUT;

                    EXPECT_FALSE( worker[i]->join().is_error() );
                    EXPECT_TRUE(ack[i] != 0);
                    if (DumpThreads) {
                            OUT << "Thread Done:"
                                    <<  endl << *worker[i] << endl;
                                FLUSHOUT;
                        }
                        OUT << "deleting thread i= " << i << endl; FLUSHOUT;
                    delete worker[i];
                    worker[i] = 0;
            }

            delete [] worker;
            delete [] ack;
    }

        ::usleep(2);

    if (PongTimes || PongGames)
            playPong();

        ::usleep(2);

    if (SleepTime) {
                OUT << "SleepTime " << SleepTime << endl; FLUSHOUT;
            timer_thread_t* timer_thread = new timer_thread_t;
            EXPECT_TRUE(timer_thread != NULL);
            EXPECT_FALSE( timer_thread->fork().is_error() );
                OUT << "Timer thread forked " << endl; FLUSHOUT;
            EXPECT_FALSE( timer_thread->join().is_error() );
                OUT << "Timer thread joined " << endl; FLUSHOUT;
            if (DumpThreads) {
                    OUT << "Timer Thread Done:" << endl
                            << *timer_thread << endl;
                        FLUSHOUT;
                }
            delete timer_thread;
    }

    if (StackOverflow) {
            overflow_thread_t *overflow = new overflow_thread_t;
            EXPECT_TRUE(overflow != NULL);
                OUT << "forking overflow_thread_t " << endl; FLUSHOUT;
            EXPECT_FALSE(overflow->fork().is_error());
            EXPECT_FALSE(overflow->join().is_error());
            delete overflow;
    }

    if (TestAssert || TestFatal) {
                if (TestErrorInThread) {
                        error_thread_t *error = new error_thread_t;
                        EXPECT_TRUE (error != NULL);
                        OUT << "forking error_thread_t " << endl; FLUSHOUT;
                        EXPECT_FALSE(error->fork().is_error());
                        EXPECT_FALSE(error->join().is_error());
                        delete error;
                }
                else {
                        OUT << "Errors testing in main thread" << endl;
                        FLUSHOUT;
                        doErrorTests();
                }
    }

    if (verbose) {
        sthread_t::dump_stats(cout);
        }
}
Exemple #25
0
/*********************************************************************
 *
 *  scan_index_i::_init(cond, b1, c2, b2)
 *
 *  Initialize a scan. Called by all constructors.
 *
 *  Of which there is only 1, and it uses mode=SH
 *
 *********************************************************************/
void 
scan_index_i::_init(
    cmp_t                 cond, 
    const cvec_t&         bound,
    cmp_t                 c2, 
    const cvec_t&         b2,
    lock_mode_t           mode,
    const bool            bIgnoreLatches)
{
    _finished = false;

    /*
     *  Determine index and kvl lock modes.
     */
    lock_mode_t index_lock_mode;
    concurrency_t key_lock_level;

    //  _cc was passed in on constructor
    //  Disallow certain kinds of scans on certain
    //  kinds of indexes:
    //

    switch(_cc) {
    case t_cc_none:
        index_lock_mode = lock_m::parent_mode[mode]; // IS if mode == SH
        key_lock_level = t_cc_none;
        break;

    case t_cc_im:
    case t_cc_kvl:
        index_lock_mode = lock_m::parent_mode[mode]; // IS if mode==SH
        key_lock_level = _cc;
        break;

    case t_cc_modkvl:
        index_lock_mode = lock_m::parent_mode[mode]; // IS if mode==SH
        // GROT: force the checks below to
        // check scan conditions
        key_lock_level = t_cc_none;
        break;

    case t_cc_file:
        index_lock_mode = mode;
        key_lock_level = t_cc_none;
        break;
    case t_cc_append:
    default:
        _error_occurred = RC(eBADLOCKMODE);
        return;
        break;
    }

    /*
     *  Save tid
     */
    tid = xct()->tid();

    /*
     *  Access directory entry
     */
    sdesc_t* sd = 0;
    _error_occurred = dir->access(_stid, sd, index_lock_mode);
    if (_error_occurred.is_error())  {
        return;
    }

    if (sd->sinfo().stype != t_index)  {
        _error_occurred = RC(eBADSTORETYPE);
        return;
    }

    if((concurrency_t)sd->sinfo().cc != key_lock_level) {
        switch((concurrency_t)sd->sinfo().cc) {
            case t_cc_none:
                //  allow anything
                break;

            case t_cc_modkvl:
                // certain checks are made in fetch_init
                if(_cc == t_cc_none || _cc == t_cc_file) {
                        key_lock_level = t_cc_none;
                } else {
                    key_lock_level = (concurrency_t)sd->sinfo().cc;
                }
                break;

            case t_cc_im:
            case t_cc_kvl:

                //  allow file 
                if(_cc == t_cc_file) {
                    key_lock_level = t_cc_file;
                    break;
                }
                key_lock_level = (concurrency_t)sd->sinfo().cc;
                break;

            default:
                _error_occurred = RC(eBADCCLEVEL);
                return;
        }
    }

    /*
     *  Initialize the fetch
     */
    switch (ntype = (ndx_t) sd->sinfo().ntype)  {
    case t_bad_ndx_t:  
        _error_occurred = RC(eBADNDXTYPE);
        return;

    case t_btree:
    case t_uni_btree:
        {
            _btcursor = new bt_cursor_t(!_skip_nulls);
            if (! _btcursor) {
                _error_occurred = RC(eOUTOFMEMORY);
                return;
            }
            bool inclusive = (cond == eq || cond == ge || cond == le);
	    
            cvec_t* elem = 0;

	    if(_btcursor->is_backward()) {
		elem = &(inclusive ? cvec_t::pos_inf : cvec_t::neg_inf);
	    } else {
		elem = &(inclusive ? cvec_t::neg_inf : cvec_t::pos_inf);
	    }

            _error_occurred = bt->fetch_init(*_btcursor, sd->root(), 
                                            sd->sinfo().nkc, sd->sinfo().kc,
                                            ntype == t_uni_btree,
                                            key_lock_level,
                                            bound, *elem, 
                                             cond, c2, b2, mode);
            if (_error_occurred.is_error())  {
                return;
            }
	    /*
            if(_btcursor->is_backward()) {
                // Not fully supported
                _error_occurred = RC(eNOTIMPLEMENTED);
                return;
            }
	    */
        }
        break;
    case t_mrbtree:
    case t_uni_mrbtree:
    case t_mrbtree_l:
    case t_uni_mrbtree_l:
    case t_mrbtree_p:
    case t_uni_mrbtree_p:
        {
            _btcursor = new bt_cursor_t(!_skip_nulls);
            if (! _btcursor) {
                _error_occurred = RC(eOUTOFMEMORY);
                return;
            }
            bool inclusive = (cond == eq || cond == ge || cond == le);

            cvec_t* elem = 0;

	    if(_btcursor->is_backward()) {
		elem = &(inclusive ? cvec_t::pos_inf : cvec_t::neg_inf);
	    } else {
		elem = &(inclusive ? cvec_t::neg_inf : cvec_t::pos_inf);
	    }

	    // traverse all the subtrees that covers the region [bound,b2]
	    std::vector<lpid_t> roots;
	    cvec_t* bound_key;
	    cvec_t* b2_key;
	    _error_occurred = bt->_scramble_key(bound_key, bound, sd->sinfo().nkc, sd->sinfo().kc);
	    char* bound_sc = (char*) malloc((*bound_key).size());
	    (*bound_key).copy_to(bound_sc, (*bound_key).size());
	    cvec_t b1(bound_sc, (*bound_key).size());
	    _error_occurred = bt->_scramble_key(b2_key, b2, sd->sinfo().nkc, sd->sinfo().kc);

	    if(&bound == &vec_t::neg_inf && &b2 == &vec_t::pos_inf) {
		_error_occurred = sd->partitions().getAllPartitions(roots);
	    } else {
		_error_occurred = sd->partitions().getPartitions(b1, *b2_key, roots);
	    }
	    _error_occurred = bt->mr_fetch_init(*_btcursor, roots, 
						sd->sinfo().nkc, sd->sinfo().kc,
						ntype == t_uni_btree,
						key_lock_level,
						b1, *elem, 
						cond, c2, *b2_key, mode,
                                                bIgnoreLatches);
	    free(bound_sc);
	    
	    if (_error_occurred.is_error())  {
                return;
            }
	    /*
            if(_btcursor->is_backward()) {
                // Not fully supported
                _error_occurred = RC(eNOTIMPLEMENTED);
                return;
            }
	    */
        }
        break;

    default:
        W_FATAL(eINTERNAL);
   }

}
Exemple #26
0
void chkpt_t::deserialize_binary(ifstream& ifs)
{
    if(!ifs.is_open()) {
        cerr << "Could not open input stream for chkpt file" << endl;;
        W_FATAL(fcINTERNAL);
    }

    ifs.read((char*)&highest_tid, sizeof(tid_t));

    size_t buf_tab_size;
    ifs.read((char*)&buf_tab_size, sizeof(size_t));
    for(uint i=0; i<buf_tab_size; i++) {
        PageID pid;
        ifs.read((char*)&pid, sizeof(PageID));

        buf_tab_entry_t entry;
        ifs.read((char*)&entry, sizeof(buf_tab_entry_t));

        DBGOUT1(<<"pid[]="<<pid<< " , " <<
                  "rec_lsn[]="<<entry.rec_lsn<< " , " <<
                  "page_lsn[]="<<entry.page_lsn);

        // buf_tab[pid] = entry;
        mark_page_dirty(pid, entry.page_lsn, entry.rec_lsn);
    }

    size_t xct_tab_size;
    ifs.read((char*)&xct_tab_size, sizeof(size_t));
    for(uint i=0; i<xct_tab_size; i++) {
        tid_t tid;
        ifs.read((char*)&tid, sizeof(tid_t));

        xct_tab_entry_t entry;
        ifs.read((char*)&entry.state, sizeof(smlevel_0::xct_state_t));
        ifs.read((char*)&entry.last_lsn, sizeof(lsn_t));
        ifs.read((char*)&entry.first_lsn, sizeof(lsn_t));

        DBGOUT1(<<"tid[]="<<tid<<" , " <<
                  "state[]="<<entry.state<< " , " <<
                  "last_lsn[]="<<entry.last_lsn<<" , " <<
                  "first_lsn[]="<<entry.first_lsn);

        if (entry.state != smlevel_0::xct_ended) {
            mark_xct_active(tid, entry.first_lsn, entry.last_lsn);

            if (is_xct_active(tid)) {
                size_t lock_tab_size;
                ifs.read((char*)&lock_tab_size, sizeof(size_t));
                for(uint j=0; j<lock_tab_size; j++) {
                    lock_info_t lock_entry;
                    ifs.read((char*)&lock_entry, sizeof(lock_info_t));
                    // entry.locks.push_back(lock_entry);
                    add_lock(tid, lock_entry.lock_mode, lock_entry.lock_hash);

                    DBGOUT1(<< "    lock_mode[]="<<lock_entry.lock_mode
                            << " , lock_hash[]="<<lock_entry.lock_hash);
                }
            }
            // xct_tab[tid] = entry;
        }
    }
Exemple #27
0
main(int argc, char **argv)
{
	int	numBits = 71;
	int	numBytes;
	int	i;
	int	errors = 0;
	int	iterations = 0;
	bool	random_tests = false;
	bool	stateless_tests = false;
	int	c;

	while ((c = getopt(argc, argv, "n:ri:")) != EOF) {
		switch (c) {
		case 'n':
			/* number of bits */
			numBits = atoi(optarg);
			break;
		case 'r':
			/* tests using random bit numbers;
			   otherwise tests test all valid
			   bit numbers in order */
			random_tests = true;
			break;
		case 'i':
			/* iterations for each test */
			iterations = atoi(optarg);
			break;
		default:
			errors++;
			break;
		}
	}
	if (errors) {
		W_FORM(cerr)("usage: %s [-n bits] [-r] [-i iterations]\n",
			     argv[0]);
		return 1;
	}
	if (!iterations)
		iterations = random_tests ? 10000 : numBits;

	// tests must leave no state if probes are random, or will
	// repeat through the sample space
	stateless_tests = (random_tests || iterations > numBits);

	numBytes = (numBits - 1) / 8 + 1;

	u_char	*map = new u_char[numBytes];
	if (!map)
		W_FATAL(fcOUTOFMEMORY);

	W_FORM(cout)("test bitmap of %d bits, stored in %d bytes (%d bits).\n",
		     numBits, numBytes, numBytes*8);
	
	for (i = 0; i < numBytes; i++)
		map[i] = rand();

	cout << "Clear Map:    ";
	errors = 0;
	bm_zero(map, numBits);
	for (i = 0; i < numBits; i++)  {
		if (bm_is_set(map, i))  {
			cout << i << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "Set Map:      ";
	errors = 0;
	bm_fill(map, numBits);
	for (i = 0; i < numBits; i++)  {
		if ( ! bm_is_set(map, i))  {
			cout << i << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "Set:          ";
	errors = 0;
	bm_zero(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_set(map, bit);
		if ( ! bm_is_set(map, bit) )  {
			cout << bit << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "Clear:        ";
	errors = 0;
	bm_fill(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_clr(map, bit);
		if (bm_is_set(map, bit))  {
			cout << bit << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "First Set:    ";
	errors = 0;
	bm_zero(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_set(map, bit);
		
		if (bm_first_set(map, numBits, 0) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		
		if (bm_first_set(map, numBits, bit) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}

		bm_clr(map, bit);
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "First Clear:  ";
	errors = 0;
	bm_fill(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_clr(map, bit);
		if (bm_first_clr(map, numBits, 0) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		
		if (bm_first_clr(map, numBits, bit) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		bm_set(map, bit);
	}
	cout << (errors ? "failed" : "passed") << endl << flush;

	cout << "Last Set:     ";
	errors = 0;
	bm_zero(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_set(map, bit);
		
		if (bm_last_set(map, numBits, numBits-1) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		
		if (bm_last_set(map, numBits, bit) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		if (stateless_tests)
			bm_clr(map, bit);
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	cout << "Last Clear:   ";
	errors = 0;
	bm_fill(map, numBits);
	for (i = 0; i < iterations; i++)  {
		int	bit = (random_tests ? rand() : i) % numBits;
		bm_clr(map, bit);
		if (bm_last_clr(map, numBits, numBits-1) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		
		if (bm_last_clr(map, numBits, bit) != bit)  {
			cout << bit << " ";
			errors++;
			break;
		}
		if (stateless_tests)
			bm_set(map, bit);
	}
	cout << (errors ? "failed" : "passed") << endl << flush;

	cout << "Num Set:      ";
	errors = 0;
	bm_zero(map, numBits);
	if (bm_num_set(map, numBits) != 0) {
		cout << "all ";
		errors++;
	}
	for (i = 0; i < numBits; i++)  {
		bm_set(map, i);
		
		if (bm_num_set(map, numBits) != i+1)  {
			cout << i << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;

	cout << "Num Clear:    ";
	errors = 0;
	bm_fill(map, numBits);
	if (bm_num_clr(map, numBits) != 0) {
		cout << "all ";
		errors++;
	}
	for (i = 0; i < numBits; i++)  {
		bm_clr(map, i);
		
		if (bm_num_clr(map, numBits) != i+1)  {
			cout << i << " ";
			errors++;
			break;
		}
	}
	cout << (errors ? "failed" : "passed") << endl << flush;
	
	delete [] map;
	
	cout << flush;
}
Exemple #28
0
bool 
lock_m::get_parent(const lockid_t& c, lockid_t& p)
{
    switch (c.lspace()) {
        case lockid_t::t_vol:
            // no parent
        case lockid_t::t_extent:
            // no parent
            p.zero(); // sets type to t_bad
            break;
        case lockid_t::t_store:
            // parent of store is volume
            new (&p) lockid_t(c.vid());
            break;
        case lockid_t::t_page: {
            // parent of page is store
            stid_t s;
            c.extract_stid(s);
            new (&p) lockid_t(s);
            }
            break;
        case lockid_t::t_kvl: {
            // parent of kvl is store?
            stid_t s;
            c.extract_stid(s);
            new (&p) lockid_t(s);
            }
            break;
        case lockid_t::t_record: {
            // parent of record is page
            lpid_t pg;
            c.extract_lpid(pg);
            new (&p) lockid_t(pg);
            }
            break;
        case lockid_t::t_user1:
            // no parent
            p.zero();
            break;
        case lockid_t::t_user2: {
            lockid_t::user1_t u;
            c.extract_user1(u);
            new (&p) lockid_t(u);
            }
            break;
        case lockid_t::t_user3:  {
            lockid_t::user2_t u;
            c.extract_user2(u);
            new (&p) lockid_t(u);
            }
            break;
        case lockid_t::t_user4:  {
            lockid_t::user3_t u;
            c.extract_user3(u);
            new (&p) lockid_t(u);
            }
            break;
        default:
            W_FATAL(eINTERNAL);
    }
    DBGTHRD(<< "child:" << c << "  parent: " << p );
#ifdef W_TRACE
    bool b =  p.lspace() != lockid_t::t_bad;
    DBGTHRD(<< "get_parent returns " << b
        << " for parent type " << int(p.lspace()) );
#endif
    return p.lspace() != lockid_t::t_bad;
}
Exemple #29
0
w_rc_t out_of_log_space (
    xct_i* iter, 
    xct_t *& xd,
    smlevel_0::fileoff_t curr,
    smlevel_0::fileoff_t thresh,
    const char *filename
)
{
    static int calls=0;

    calls++;

    w_rc_t rc;
    fprintf(stdout, "\n**************************************** %d\n", calls);
    dump();

    fprintf(stdout, 
            "Called out_of_log_space with curr %lld thresh %lld, file %s\n",
            (long long) curr, (long long) thresh, filename);
    {
        w_ostrstream o;
        o << xd->tid() << endl;
        fprintf(stdout, "called with xct %s\n" , o.c_str()); 
    }

    xd->log_warn_disable();
    iter->never_mind(); // release the mutex

    {
        w_ostrstream o;
        static sm_stats_info_t curr;

        W_DO( ssm->gather_stats(curr));

        o << curr.sm.log_bytes_generated << ends;
        fprintf(stdout, "stats: log_bytes_generated %s\n" , o.c_str()); 
    }
    lsn_t target;
    {
        w_ostrstream o;
        o << "Active xcts: " << xct_t::num_active_xcts() << " ";

        tid_t old = xct_t::oldest_tid();
        o << "Oldest transaction: " << old;

        xct_t *x = xct_t::look_up(old);
        if(x==NULL) {
            fprintf(stdout, "Could not find %s\n", o.c_str());
            W_FATAL(fcINTERNAL);
        }

        target = x->first_lsn();
        o << "   First lsn: " << x->first_lsn();
        o << "   Last lsn: " << x->last_lsn();

        fprintf(stdout, "%s\n" , o.c_str()); 

    }

    if(calls > 3) {
        // See what happens...
        static tid_t aborted_tid;
        if(aborted_tid == xd->tid()) {
            w_ostrstream o;
            o << aborted_tid << endl;
            fprintf(stdout, 
                    "Multiple calls with same victim! : %s total calls %d\n",
                    o.c_str(), calls);
            W_FATAL(smlevel_0::eINTERNAL);
        }
        aborted_tid = xd->tid();
        fprintf(stdout, "\n\n******************************** ABORTING\n\n");
        return RC(smlevel_0::eUSERABORT); // sm will abort this guy
    }

    fprintf(stdout, "\n\n******************************** ARCHIVING \n\n");
    fprintf(stdout, "Move aside log file log.%d to log.%d.bak\n", 
            target.file(), target.file());
    static char O[smlevel_0::max_devname<<1];
    strcat(O, filename);
    static char N[smlevel_0::max_devname<<1];
    strcat(N, filename);
    strcat(N, ".bak");

    int e = ::rename(O, N);
    if(e != 0) {
        fprintf(stdout, "Could not move %s to %s: error : %d %s\n",
                O, N, e, strerror(errno));
        if(errno == ENOENT) {
            fprintf(stdout, "Ignored error.\n\n");
            return RCOK; // just to ignore these.
        }
        fprintf(stdout, "Returning eOUTOFLOGSPACE.\n\n");
        rc = RC2(smlevel_0::eOUTOFLOGSPACE, errno); 
    } else {
        dump();
        fprintf(stdout, "archived ... OK\n\n");
        W_COERCE(ss_m::log_file_was_archived(filename));
    }
    return rc;
}
Exemple #30
0
istream &
w_base_t::_scan_uint8(
    istream& i, 
    w_base_t::uint8_t &u8, 
    bool chew_white, // true if coming from istream operator
    bool is_signed, // if true, we have to return an error for overflow
    bool&    range_err // set to true if range error occurred  
) 
{
    w_base_t::uint8_t    thresh=0, 
    thresh2=0 /* thresh2, thresh3, thresh4 for decimal only */, 
        thresh3=0, thresh4=0;
    w_base_t::uint8_t     value = 0;

    bool     negate = false;
    int        e=0;
    int        base=0;
    bool     skip_white = true;
    states     s = start;
    streampos   tell_start = i.tellg();
    int        chewamt = chew_white? 1 : 0; 
    XTABLE     *table=0;

    range_err = false;
    {
    // Get the base from the stream
    ios_fmtflags old = i.flags();
    skip_white = ((old & ios::skipws) != 0);
    switch(old & ios::basefield) {
        case 0:
        base = 0;
        table = &table_unknown;
        break;

        case ios::hex:
        base = 4; // shift by this
        table = &table_base16;
        thresh = is_signed?  thresh_hex_signed : thresh_hex_unsigned;
        break;

        case ios::oct:
        base = 3; // shift by this
        table = &table_base8;
        thresh = is_signed?  thresh_oct_signed : thresh_oct_unsigned;
        break;

        case ios::dec:
        base = 10; // multiply by this
        table = &table_base10;
        thresh = is_signed?  thresh_dec_signed : thresh_dec_unsigned;
        thresh2 = is_signed?  thresh2_dec_signed : thresh2_dec_unsigned;
        thresh3 = is_signed?  (negate? 8: 7) : 5;
        thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
        break;
        default:
        W_FATAL(fcINTERNAL);
        break;
    }
    }

    int ich;
    char ch;
    while (s < end) {
    ch = 0;
    // if (i) {
        ich = i.get();
        if (ich != EOF) {
           ch = char(ich);
           /* By using isspace() we get locale-dependent behavior */
           if(isspace(ch)) {
           e = white;
           } else {
           e = equiv[unsigned(ch)];
        }
        }
        else
           e = eofile;
    // } else {
        // e = eofile;
    // }

    /* transition table */
    s = (*table)[e][s];

    switch(s) {
        case start:
        /* Have seen leading white space */
        if(!skip_white) {
            s = end;
        }
        tell_start += chewamt; 
        break;

        case sgned:
        if(ch == '-') {
            negate = true;
            if(thresh3!=0) thresh3 = is_signed?  (negate? 8: 7) : 5;
        }
        break;

        case leadz:
        /* Have seen 1 or more leading zeroes 
         * if base is 0 (unstated), 0 or 0x will
         * determine the base.
         */
        break;

        case new_hex:
        /* State means we've seen [0][a-f] or 0[xX] */
        if(base && (base != 4)) {
            /* consider this the end of the string */
            IOS_BACK(i, ch);
            s = end;
            break;
        }
        w_assert9(base == 0 || base == 4);
        if((base == 0) && (e != exx)) {
            /* consider this the end of the string */
            IOS_BACK(i, ch);
            s = end;
            break;
        }
            /* at this point, in the 0[xX] case, 
         * we WILL make a conversion,
         * if nothing else, it will be to 0. In event
         * of error (the char after the [Xx] is not
         * a legit hex digit) we have to be able to 
         * seek back to where the [Xx] was, rather than
         * leave the endptr at the offending digit.
         */
        base = 4; // 2 ** base, i.e., shift amt
        if(e != exx) {
           IOS_BACK(i, ch);
        } else {
            /* XXX used to be tellg()-1, but no streampos
               arith allowed that way. */
            tell_start = i.tellg();
            tell_start -= 1;    // for possible error-handling
        }
        thresh = is_signed?  thresh_hex_signed : thresh_hex_unsigned;
        break;

        case new_oct:
        /* State means we've seen 0 followed by [1-7] */
        if(base==0 || base == 3) {
            /* treat as oct # */
            base = 3; // shift amt
            thresh = is_signed?  thresh_oct_signed : thresh_oct_unsigned;
        } else if(base == 10) {
            s = new_dec;
            thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
            thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
            thresh3 = is_signed?  (negate? 8: 7) : 5;
            thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
        } else {
            w_assert9(base == 4);
            s = new_hex;
            thresh = is_signed?  thresh_hex_signed : thresh_hex_unsigned;
        }
        IOS_BACK(i, ch);
        break;

        case new_dec:
        /* State means we've seen [1-9] in start/sgned state 
        *  or 0 followed by [8-9]
        */
        if(e == eight || e == nine) {
            if(base && base != 10) {
            /* consider this the end of the string */
            IOS_BACK(i, ch);
            s = end;
            break;
            }
        }
        if(base==0 || base == 10) {
            /* treat as dec # */
            base = 10; // multiply amt
            thresh = is_signed?  thresh_dec_signed : thresh_dec_unsigned;
            thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
            thresh3 = is_signed?  (negate? 8: 7) : 5;
            thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
        } else if(base == 3) {
            s = new_oct;
            thresh = is_signed?  thresh_oct_signed : thresh_oct_unsigned;
        } else {
            w_assert9(base == 4);
            thresh = is_signed?  thresh_hex_signed : thresh_hex_unsigned;
            s = new_hex;
        }
        IOS_BACK(i, ch);
        break;

        case is_hex:
        w_assert9(base == 4);
        /* drop down */

        case is_oct:
        if(value & thresh) {
           range_err = true;
           // keep parsing
           // s = end;
           break;
        }
        /* shift */
        value <<= base;
        value += int(e);
        break;

        case is_dec:
        w_assert9(base == 10);
        if(value & thresh4) {
            if(value > thresh2) {
               /* will overflow on multiply */
               range_err = true;
               // keep parsing
               // s = end;
               break;
            } 
            value *= base;
            if((value - thresh2) + unsigned(e) > thresh3) {
            /* overflow adding in e */
               range_err = true;
               // keep parsing
               // s = end;
               break;
            }
        } else {
            /* multiply */
            value *= base;
        }
        value += unsigned(e);
        break;

        case error:
        IOS_FAIL(i);
        i.seekg(tell_start);
        s = end;
        break;

        case no_hex:
        i.seekg(tell_start);
        s = end;
        break;

        case end:
            IOS_BACK(i, ch);
        break;

        case no_state:
        W_FATAL(fcINTERNAL);
        break;
    }
    }
    if(range_err) {
       // don't seek to start
        u8 = negate ? 
       ( is_signed? w_base_t::int8_min : w_base_t::uint8_max) :
       ( is_signed? w_base_t::int8_max : w_base_t::uint8_max);
       IOS_FAIL(i);
    } else { 
    u8 = negate ?  (0 - value) : value;
    }

    return i;
}