Ejemplo n.º 1
0
w_rc_t    sthread_t::fork()
{
    {
        sthread_init_t::do_init();
        CRITICAL_SECTION(cs, _start_terminate_lock);
        /* can only fork a new thread */
        if (_forked)
            return RC(stOS);

        /* Add us to the list of threads, unless we are the main thread */
        if(this != _main_thread)
        {
            CRITICAL_SECTION(cs, _class_list_lock);
            _class_list->append(this);
        }


        _forked = true;
        if(this == _main_thread) {
            // happens at global constructor time
            CRITICAL_SECTION(cs_thread, _wait_lock);
            _status = t_running;
        } else    {
            // happens after main() called
            DO_PTHREAD( pthread_cond_signal(_start_cond) );
        }
    }

    return RCOK;
}
Ejemplo n.º 2
0
w_rc_t                        
bf_prefetch_thread_t::fetch(
    const lpid_t&       pid,
    page_p&                page                
) 
{
    FUNC(bf_prefetch_thread_t::fetch);
    bool got;
    latch_mode_t mode;

    DBGTHRD(<<"fetching -- awaiting mutex...");
    CRITICAL_SECTION(cs, _prefetch_mutex);

    if(get_error()) {
        w_rc_t rc(_fix_error.delegate());
        return rc;
    }
    int i = _f; 
    bf_prefetch_thread_t::frame_info &inf = _info[i];

    w_assert3(inf._status != pf_init);
    // caller must have requested it

    mode = inf._mode;

    if(inf._pid == pid && inf._status == pf_available ) {
        page = inf._page; // refixes
        got = true;
    } else {
        w_assert3(inf._status == pf_requested ||
            inf._status == pf_in_transit ||
            inf._status == pf_grabbed 
            );

        got = false;
    }
    new_state(i,pf_fetch);
    w_assert3( inf._status == pf_init || inf._status == pf_grabbed);

    cs.exit();

    DBGTHRD(<<"fetching -- released mutex...");
    w_rc_t rc;
    if(!got) {
        // Just go ahead and fix it here.
        // If _status is pf_in_transit, we should
        // block in the buffer manger; if it's 
        // pf_requested, the thread hasn't run yet (which
        // really shouldn't be the case if we're prefetching
        // at most 1 at a time).

        DBGTHRD(<<"did not get -- fixing page...");
        smlevel_0::store_flag_t store_flags = smlevel_0::st_bad;
        rc = page.fix(pid, page_p::t_any_p, mode, 0, store_flags);
        if(rc.is_error()) {
            CRITICAL_SECTION(cs2, _prefetch_mutex);
            _fix_error = rc;
            new_state(i, pf_error);
        }
    }
Ejemplo n.º 3
0
bool Working_Ant::walk(Ant_Graph *       g,
		       Ant_Graph::Node * tgt_node, 
		       Ant_Graph::Arc *  ant_arc)
{
  g->leave_agent_from_location(this);

  double distance;

  {
    CRITICAL_SECTION(ant_arc->mutex);

    distance = ant_arc->distance;

        // deposita feromona (mayor distancia ==> menor feromona)
    ant_arc->feromone_level += Q/distance;
  }

  {
    CRITICAL_SECTION(tgt_node->mutex);

        // Comida que consume hormiga (mayor distancia ==> mayor consumo)
    tgt_node->food -= F*distance/max_dist;
  }

      // vida que consume hormiga (mayor distancia ==> menos vida)
  life -= L*distance/max_dist;

  g->enter_agent_in_node(this, tgt_node);

  return true;
}
Ejemplo n.º 4
0
void pong_thread_t::run()
{
    int i;
    int self = id;

        {
                CRITICAL_SECTION(cs, game.theBall);
                for(i=0; i<PongTimes; ++i){
                        while(game.whoseShot != self){
                                DO_PTHREAD(pthread_cond_wait(&game.paddle[self], &game.theBall));
                        }
                        game.whoseShot = 1-self;
                        DO_PTHREAD(pthread_cond_signal(&game.paddle[1-self]));

                }
        }

    // OUT.form("pong(%#lx) id=%d done\n", (long)this, id);
    note.done();

    if (DumpInThreads) {
                OUT << *this << endl;
                FLUSHOUT;
        }
}
Ejemplo n.º 5
0
w_rc_t sthread_t::close(int fd)
{
    fd -= fd_base;
    if (fd < 0 || fd >= (int)open_max || !_disks[fd])
        return RC(stBADFD);

    w_rc_t    e;

    // sync before close
    e = _disks[fd]->sync();
    if (e.is_error())
        return e;

    e = _disks[fd]->close();
    if (e.is_error())
        return e;

    sdisk_t    *togo;
    {
        CRITICAL_SECTION(cs, protectFDs);
        togo = _disks[fd];
        _disks[fd] = 0;
        open_count--;
    }
    delete togo;
    
    return e;
}
Ejemplo n.º 6
0
void    wait_for_t::wait()
{
        CRITICAL_SECTION(cs, _lock);
        while (have < expected) {
                DO_PTHREAD(pthread_cond_wait(&_done, &_lock));
        }
}
Ejemplo n.º 7
0
void ShoreYCSBEnv::print_throughput(const double iQueriedSF,
                                    const int iSpread,
                                    const int iNumOfThreads,
                                    const double delay)
{
    CRITICAL_SECTION(last_stats_cs, _last_stats_mutex);

    // get the current statistics
    ShoreYCSBTrxStats current_stats = _get_stats();

    // now calculate the diff
    current_stats -= _last_stats;

    uint trxs_att  = current_stats.attempted.total();
    uint trxs_abt  = current_stats.failed.total();
    uint trxs_dld  = current_stats.deadlocked.total();

    TRACE( TRACE_ALWAYS, "*******\n"             \
           "QueriedSF: (%.1f)\n"                 \
           "Spread:    (%s)\n"                   \
           "Threads:   (%d)\n"                   \
           "Trxs Att:  (%d)\n"                   \
           "Trxs Abt:  (%d)\n"                   \
           "Trxs Dld:  (%d)\n"                   \
           "Secs:      (%.2f)\n"                 \
           "TPS:       (%.2f)\n",
           iQueriedSF,
           (iSpread ? "Yes" : "No"),
           iNumOfThreads, trxs_att, trxs_abt, trxs_dld,
           delay, (trxs_att-trxs_abt-trxs_dld)/delay);
}
Ejemplo n.º 8
0
// prints all the env vars
void envVar::printVars(void)
{
    TRACE( TRACE_DEBUG, "Environment variables\n");
    CRITICAL_SECTION(evm_cs,_lock);
    for (envVarConstIt cit= _evm.begin(); cit != _evm.end(); ++cit)
        TRACE( TRACE_STATISTICS, "%s -> %s\n", cit->first.c_str(), cit->second.c_str()); 
}
Ejemplo n.º 9
0
int rvp_t::append_actions(const baseActionsList& actionList)
{
    CRITICAL_SECTION(action_cs, _actions_lock);
    // append new actionList to the end of the list
    _actions.insert(_actions.end(), actionList.begin(),actionList.end()); 
    return (0);
}
Ejemplo n.º 10
0
int trx_worker_t::_pre_STOP_impl()
{
    Request* pr;
    int reqs_read  = 0;
    int reqs_write = 0;
    int reqs_abt   = 0;

    assert (_pqueue);

    // Go over the readers list
    for (; _pqueue->_read_pos != _pqueue->_for_readers->end(); _pqueue->_read_pos++) {
        pr = *(_pqueue->_read_pos);
        ++reqs_read;
        if (abort_one_trx(pr->_xct)) ++reqs_abt;
    }

    // Go over the writers list
    {
        CRITICAL_SECTION(q_cs, _pqueue->_lock);
        for (_pqueue->_read_pos = _pqueue->_for_writers->begin();
             _pqueue->_read_pos != _pqueue->_for_writers->end();
             _pqueue->_read_pos++) 
            {
                pr = *(_pqueue->_read_pos);
                ++reqs_write;
                if (abort_one_trx(pr->_xct)) ++reqs_abt;
            }
    }

    if ((reqs_read + reqs_write) > 0) {
        TRACE( TRACE_ALWAYS, "(%d) aborted before stopping. (%d) (%d)\n", 
               reqs_abt, reqs_read, reqs_write);
    }
    return (reqs_abt);
}
Ejemplo n.º 11
0
bool htab_remove(bf_core_m *core, bfpid_t const &pid, bf_core_m::Tstats &s) 
{
    bool ret(false);
    bfcb_t *cb  = core->_htab->lookup(pid);

    if(cb) {
        // find the bucket so we can acquire the lock,
        // necessary for removal.
        // also ensure pin count is zero.
        int idx = core->_htab->hash(cb->hash_func(), pid);
        bf_core_m::htab::bucket &b = core->_htab->_table[idx];
        cb->zero_pin_cnt();
        CRITICAL_SECTION(cs, b._lock);

        bool bull = core->_htab->remove(cb);
        w_assert0(bull);
        w_assert1(cb->pin_cnt() == 0);
    }

    // It's possible that it couldn't remove the item
    // because the lock is not held or the pin count is > 0
    if(ret) {
        w_assert2(cb->hash_func() == bf_core_m::htab::HASH_COUNT);
    }

    s = me()->TL_stats().bfht;
    return ret;
}
Ejemplo n.º 12
0
w_rc_t bf_tree_m::_grab_free_block(bf_idx& ret, bool evict)
{
    ret = 0;
    while (true) {
        // once the bufferpool becomes full, getting _freelist_lock everytime will be
        // too costly. so, we check _freelist_len without lock first.
        //   false positive : fine. we do real check with locks in it
        //   false negative : fine. we will eventually get some free block anyways.
        if (_freelist_len > 0) {
            CRITICAL_SECTION(cs, &_freelist_lock);
            if (_freelist_len > 0) { // here, we do the real check
                bf_idx idx = FREELIST_HEAD;
                DBG5(<< "Grabbing idx " << idx);
                w_assert1(_is_valid_idx(idx));
                w_assert1 (!get_cb(idx)._used);
                ret = idx;

                --_freelist_len;
                if (_freelist_len == 0) {
                    FREELIST_HEAD = 0;
                } else {
                    FREELIST_HEAD = _freelist[idx];
                    w_assert1 (FREELIST_HEAD > 0 && FREELIST_HEAD < _block_cnt);
                }
                DBG5(<< "New head " << FREELIST_HEAD);
                w_assert1(ret != FREELIST_HEAD);
                return RCOK;
            }
        } // exit the scope to do the following out of the critical section
Ejemplo n.º 13
0
void Aleph::error(const char* file, int line, const char* format, ...)
{
# ifdef _PTHREAD_H
  CRITICAL_SECTION(aleph_message_mutex);
# endif 

  va_list ap;
  
  va_start(ap, format);

  if (Aleph::daemonized)  
    {
      ::syslog(LOG_ERR, "Fatal error detected at %s %u\n", file, line);
      Aleph::syslog(format, ap);
    }
  else
    {
      printf("Fatal error detected in %s %u\n", file, line); 
      vfprintf(stdout, format, ap);
      printf("\n");
    }

  va_end(ap);

  abort();
}
Ejemplo n.º 14
0
void Aleph::exit(const char* file, int line, const char* format, ...) 
{
# ifdef _PTHREAD_H
  CRITICAL_SECTION(aleph_message_mutex);
# endif

  va_list ap;
  
  va_start(ap, format);

  if (Aleph::daemonized)  
    {
      ::syslog(LOG_NOTICE, "%s: %u\n", file, line); 
      Aleph::syslog(format, ap);
    }
  else
    {
      vfprintf(stdout, format, ap);
      printf("%s:%u\n", file, line);
      printf("\n");
    }
  
  va_end(ap);

  ::exit(0);
}
Ejemplo n.º 15
0
w_rc_t
sthread_t::join(timeout_in_ms /*timeout*/)
{
    w_rc_t rc;
    {
        CRITICAL_SECTION(cs, _start_terminate_lock);

        /* A thread that hasn't been forked can't be wait()ed for.
           It's not a thread until it has been fork()ed.
        */
        if (!_forked) {
            rc =  RC(stOS);
        } else
        {
            cs.exit();
            /*
             *  Wait for thread to finish.
             */
            sthread_core_exit(_core, _terminated);

        }
    }

    return rc;
}
Ejemplo n.º 16
0
void asc_sort_man_impl::add_tuple(table_row_t& atuple)
{
    CRITICAL_SECTION(cs, _sorted_lock);

    /* setup the tuple size */
    if (!_tuple_size) init();

    /* check if more space is needed */
    if (_buf_size == _tuple_count) {
        /* double the buffer size if needed */
        char* tmp = new char[(2*_buf_size)*_tuple_size];
        memcpy(tmp, _sort_buf, _buf_size*_tuple_size);
        delete [] _sort_buf;

        _sort_buf = tmp;
        _buf_size *= 2;

        //fprintf(stderr,"+\n");
    }

    /* add the current tuple to the end of the buffer */
    size_t ksz = _preprow->_bufsz;
    atuple.store_key(_preprow->_dest, ksz);
    memcpy(_sort_buf+(_tuple_count*_tuple_size), _preprow->_dest, _tuple_size);
    _tuple_count++;
    _is_sorted = false;
}
Ejemplo n.º 17
0
void ant_transit(void * __graph, void * __ant, void *)
{
  Ant_Graph * graph = static_cast<Ant_Graph*>(__graph);

  Working_Ant * working_ant = static_cast<Working_Ant*>(__ant); 

  {
    CRITICAL_SECTION(graph->bit_mutex);

    working_ant->my_bit = Working_Ant::bit_idx;

    Working_Ant::bit_idx = 
      (Working_Ant::bit_idx + 1) % graph->get_num_threads();
  }

  Ant_Graph::Node * current_node = graph->get_agent_node_location(working_ant);

  Ant_Graph::Node * next_node = NULL;

  Ant_Graph::Arc * next_arc = NULL;

  while (true)
    {
      const bool ant_is_alive = 
	working_ant->select_path(current_node, next_node, next_arc);

      if (not ant_is_alive) break;

      working_ant->walk(graph, next_node, next_arc);

      current_node = next_node;
    }

  graph->remove_agent(working_ant);
}
Ejemplo n.º 18
0
// refreshes all the env vars from the conf file
int envVar::refreshVars(void)
{
    TRACE( TRACE_DEBUG, "Refreshing environment variables\n");
    CRITICAL_SECTION(evm_cs,_lock);
    for (envVarIt it= _evm.begin(); it != _evm.end(); ++it)
        _readConfVar(it->first,it->second);    
    return (0);
}
Ejemplo n.º 19
0
// sets as input another conf file
void envVar::setConfFile(const string& sConfFile)
{
    assert (!sConfFile.empty());
    CRITICAL_SECTION(evm_cs,_lock);
    _cfname = sConfFile;
    _pfparser = new ConfigFile(_cfname);
    assert (_pfparser);
}
Ejemplo n.º 20
0
void    wait_for_t::done()
{
        CRITICAL_SECTION(cs, _lock);
        have++;
        if (have >= expected) {
                DO_PTHREAD(pthread_cond_signal(&_done));
        }
}
Ejemplo n.º 21
0
ShoreYCSBTrxStats ShoreYCSBEnv::_get_stats()
{
    CRITICAL_SECTION(cs, _statmap_mutex);
    ShoreYCSBTrxStats rval;
    rval -= rval; // dirty hack to set all zeros
    for (statmap_t::iterator it=_statmap.begin(); it != _statmap.end(); ++it)
	rval += *it->second;
    return (rval);
}
Ejemplo n.º 22
0
bool bf_core_m::htab::cuckold(bucket* dest, bucket* src, int which, 
        int hashfunc, bfcb_t* &moved) 
{
    ADD_BFSTAT(_slots_tried, 1); 
    if(dest->_count < SLOT_COUNT) 
    {
        ADD_BFSTAT(_cuckolds, 1); 
        // dest has room
        
        // Order the lock-grabbing to avoid deadlock
        bucket* b1 = (src < dest)? src : dest;
        bucket* b2 = (src < dest)? dest : src;

        CRITICAL_SECTION(cs1, b1->_lock);
        CRITICAL_SECTION(cs2, b2->_lock);

        if(src->_count < SLOT_COUNT) 
        {
            // src now has room - don't do anything after all
            return true;
        }
        
        if(dest->_count < SLOT_COUNT)
        {
            // good to go : dest still has room.  
            // Copy over src, update slot _count
            bfcb_t *b;
            dest->_slots[dest->_count++] = b = src->_slots[which];
            b->set_hash_func(hashfunc);
            b->set_hash(dest-_table);

            // adjust dest hash info while we have the locks.
            //
            // compress src, update slot _count
            src->_slots[which] = src->_slots[--src->_count];
            moved = src->_slots[which];
            CHECK_ENTRY(src-_table, true);
            CHECK_ENTRY(dest-_table, true);
            return true;
        }
    }
    CHECK_TABLE();
    return false; // possibly stale
}
Ejemplo n.º 23
0
EventDescription* EventDescription::Create(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor /*= Color::Null*/)
{
	CRITICAL_SECTION(lock)
	EventDescription* result = EventDescriptionBoard::Get().CreateDescription();
	result->name = eventName;
	result->file = fileName;
	result->line = fileLine;
	result->color = eventColor;
	return result;
}
Ejemplo n.º 24
0
// sets a new parameter
int envVar::setVar(const string& sParam, const string& sValue)
{
    if ((!sParam.empty())&&(!sValue.empty())) {
        TRACE( TRACE_DEBUG, "(%s) (%s)\n", sParam.c_str(), sValue.c_str());
        CRITICAL_SECTION(evm_cs,_lock);
        _evm[sParam] = sValue;
        return (_evm.size());
    }
    return (0);
}
Ejemplo n.º 25
0
int ShoreTPCBEnv::statistics()
{
    // read the current trx statistics
    CRITICAL_SECTION(cs, _statmap_mutex);
    ShoreTPCBTrxStats rval;
    rval -= rval; // dirty hack to set all zeros
    for (statmap_t::iterator it=_statmap.begin(); it != _statmap.end(); ++it)
	rval += *it->second;

    TRACE( TRACE_STATISTICS, "AcctUpd. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.acct_update,
           rval.failed.acct_update,
           rval.deadlocked.acct_update);

    TRACE( TRACE_STATISTICS, "MbenchInsertOnly. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_insert_only,
           rval.failed.mbench_insert_only,
           rval.deadlocked.mbench_insert_only);

    TRACE( TRACE_STATISTICS, "MbenchDeleteOnly. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_delete_only,
           rval.failed.mbench_delete_only,
           rval.deadlocked.mbench_delete_only);

    TRACE( TRACE_STATISTICS, "MbenchProbeOnly. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_probe_only,
           rval.failed.mbench_probe_only,
           rval.deadlocked.mbench_probe_only);

    TRACE( TRACE_STATISTICS, "MbenchInsertDelte. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_insert_delete,
           rval.failed.mbench_insert_delete,
           rval.deadlocked.mbench_insert_delete);

    TRACE( TRACE_STATISTICS, "MbenchInsertProbe. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_insert_probe,
           rval.failed.mbench_insert_probe,
           rval.deadlocked.mbench_insert_probe);

    TRACE( TRACE_STATISTICS, "MbenchDeleteProbe. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_delete_probe,
           rval.failed.mbench_delete_probe,
           rval.deadlocked.mbench_delete_probe);

    TRACE( TRACE_STATISTICS, "MbenchMix. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_mix,
           rval.failed.mbench_mix,
           rval.deadlocked.mbench_mix);

    ShoreEnv::statistics();

    return (0);
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
void sthread_t::sleep(timeout_in_ms timeout, const char *reason)
{
    reason = (reason && *reason) ? reason : "sleep";

    /* FRJ: even though we could just use the posix sleep() call,
       we'll stick to the sthreads way and block on a cond
       var. That way the sthreads debug stuff will keep
       working. Besides, we're here to waste time, right?
    */
    CRITICAL_SECTION(cs, _wait_lock);
    _sleeping = true;
    (void) _block(timeout, reason, this); // W_IGNORE
    _sleeping = false;
}
Ejemplo n.º 28
0
// checks the map for a specific param
// if it doesn't find it checks also the config file
string envVar::getVar(const string& sParam, const string& sDefValue)
{
    if (sParam.empty()) {
        TRACE( TRACE_ALWAYS, "Invalid Param input\n");
        return ("");
    }

    CRITICAL_SECTION(evm_cs,_lock);
    envVarIt it = _evm.find(sParam);
    if (it==_evm.end()) {        
        //TRACE( TRACE_DEBUG, "(%s) param not set. Searching conf\n", sParam.c_str()); 
        return (_readConfVar(sParam,sDefValue));
    }
    return (it->second);
}
Ejemplo n.º 29
0
bool asc_sort_man_impl::get_sorted(const int index, table_row_t* ptuple)
{
    CRITICAL_SECTION(cs, _sorted_lock);

    if (_is_sorted) {
        if (index >=0 && index < _tuple_count) {
            ptuple->load_key(_sort_buf + (index * _tuple_size));
            return true;
        }
        //TRACE( TRACE_DEBUG, "out of bounds index...\n");
        return (false);
    }
    TRACE( TRACE_DEBUG, "buffer not sorted yet...\n");
    return (false);
}
Ejemplo n.º 30
0
int ShoreTPCCEnv::statistics()
{
    // read the current trx statistics
    CRITICAL_SECTION(cs, _statmap_mutex);
    ShoreTPCCTrxStats rval;
    rval -= rval; // dirty hack to set all zeros
    for (statmap_t::iterator it=_statmap.begin(); it != _statmap.end(); ++it)
	rval += *it->second;

    TRACE( TRACE_STATISTICS, "NewOrder. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.new_order,
           rval.failed.new_order,
           rval.deadlocked.new_order);

    TRACE( TRACE_STATISTICS, "Payment. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.payment,
           rval.failed.payment,
           rval.deadlocked.payment);

    TRACE( TRACE_STATISTICS, "OrderStatus. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.order_status,
           rval.failed.order_status,
           rval.deadlocked.order_status);

    TRACE( TRACE_STATISTICS, "Delivery. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.delivery,
           rval.failed.delivery,
           rval.deadlocked.delivery);

    TRACE( TRACE_STATISTICS, "StockLevel. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.stock_level,
           rval.failed.stock_level,
           rval.deadlocked.stock_level);

    TRACE( TRACE_STATISTICS, "MBenchWh. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_wh,
           rval.failed.mbench_wh,
           rval.deadlocked.mbench_wh);

    TRACE( TRACE_STATISTICS, "MBenchCust. Att (%d). Abt (%d). Dld (%d)\n",
           rval.attempted.mbench_cust,
           rval.failed.mbench_cust,
           rval.deadlocked.mbench_cust);

    ShoreEnv::statistics();

    return (0);
}