prefetch_impl.cpp

来自「ncbi源码」· C++ 代码 · 共 290 行

CPP
290
字号
/* * =========================================================================== * PRODUCTION $Log: prefetch_impl.cpp,v $ * PRODUCTION Revision 1000.2  2004/06/01 19:23:32  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//*  $Id: prefetch_impl.cpp,v 1000.2 2004/06/01 19:23:32 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Author: Aleksey Grichenko, Eugene Vasilchenko** File Description:*   Prefetch implementation**/#include <ncbi_pch.hpp>#include <objmgr/impl/prefetch_impl.hpp>#include <corelib/ncbimtx.hpp>#include <objmgr/bioseq_handle.hpp>#include <objmgr/scope.hpp>#include <objmgr/impl/tse_info.hpp>#include <objmgr/impl/scope_impl.hpp>#include <objmgr/impl/data_source.hpp>#include <objmgr/seqmatch_info.hpp>BEGIN_NCBI_SCOPEBEGIN_SCOPE(objects)// NOTE: Max. value for semaphore must be prefetch depth + 1, because// one extra-Post will be called when the token impl. is released.CPrefetchToken_Impl::CPrefetchToken_Impl(const TIds& ids, unsigned int depth)    : m_TokenCount(0),      m_TSESemaphore(depth, max(depth+1, depth)),      m_Non_locking(false){    m_Ids = ids;}CPrefetchToken_Impl::~CPrefetchToken_Impl(void){    return;}void CPrefetchToken_Impl::x_InitPrefetch(CScope& scope){    m_TSEs.resize(m_Ids.size());    m_CurrentId = 0;    CRef<CDataSource> source(scope.GetImpl().GetFirstLoaderSource());    if (!source) {        return;    }    source->Prefetch(*this);}void CPrefetchToken_Impl::x_SetNon_locking(void){    m_Non_locking = true;}void CPrefetchToken_Impl::AddResolvedId(size_t id_idx, TTSE_Lock tse){    CFastMutexGuard guard(m_Lock);    if ( m_Non_locking ) {        m_TSESemaphore.Post();        return;    }    if (m_Ids.empty()  ||  id_idx < m_CurrentId) {        // Token has been cleaned or id already passed, do not lock the TSE        return;    }    m_TSEs[id_idx] = tse;    int count = ++m_TSEMap[tse];    if (count > 1) {        // One more ID found in a prefetched TSE        m_TSESemaphore.Post();    }}bool CPrefetchToken_Impl::IsEmpty(void) const{    CFastMutexGuard guard(m_Lock);    return m_Ids.empty();}CPrefetchToken_Impl::operator bool(void) const{    CFastMutexGuard guard(m_Lock);    return m_CurrentId < m_Ids.size();}CBioseq_Handle CPrefetchToken_Impl::NextBioseqHandle(CScope& scope){    TTSE_Lock tse;    CSeq_id_Handle id;    {{        CFastMutexGuard guard(m_Lock);        // Can not call bool(*this) - creates deadlock        _ASSERT(m_CurrentId < m_Ids.size());        id = m_Ids[m_CurrentId];        // Keep temporary TSE lock        tse = m_TSEs[m_CurrentId];        m_TSEs[m_CurrentId].Reset();        ++m_CurrentId;        if ( tse ) {            TTSE_Map::iterator it = m_TSEMap.find(tse);            if ( --(it->second) < 1 ) {                m_TSEMap.erase(it);                // Signal that next TSE or next token may be prefetched                m_TSESemaphore.Post();            }        }    }}    return scope.GetBioseqHandle(id);}void CPrefetchToken_Impl::AddTokenReference(void){    ++m_TokenCount;}void CPrefetchToken_Impl::RemoveTokenReference(void){    if ( !(--m_TokenCount) ) {        // No more tokens, reset the queue        CFastMutexGuard guard(m_Lock);        m_Ids.clear();        m_TSEs.clear();        m_CurrentId = 0;        // Allow the thread to process next token        m_TSESemaphore.Post();    }}CPrefetchThread::CPrefetchThread(CDataSource& data_source)    : m_DataSource(data_source),      m_Stop(false){    return;}CPrefetchThread::~CPrefetchThread(void){    return;}void CPrefetchThread::AddRequest(CPrefetchToken_Impl& token){    {{        CFastMutexGuard guard(m_Lock);        m_Queue.Put(Ref(&token));    }}}void CPrefetchThread::Terminate(void){    {{        CFastMutexGuard guard(m_Lock);        m_Stop = true;    }}    // Unlock the thread    m_Queue.Put(CRef<CPrefetchToken_Impl>(0));}void* CPrefetchThread::Main(void){    do {        CRef<CPrefetchToken_Impl> token = m_Queue.Get();        {{            CFastMutexGuard guard(m_Lock);            if (m_Stop) {                return 0;            }            _ASSERT( token );            if ( token->IsEmpty() ) {                // Token may have been canceled                continue;            }        }}        bool release_token = false;        for (size_t i = 0; ; ++i) {            {{                CFastMutexGuard guard(m_Lock);                if (m_Stop) {                    return 0;                }            }}            CSeq_id_Handle id;            token->m_TSESemaphore.Wait();            {{                // m_Ids may be cleaned up by the token, check size                // on every iteration.                CFastMutexGuard guard(token->m_Lock);                i = max(i, token->m_CurrentId);                if (i >= token->m_Ids.size()) {                    // Can not release token now - mutex is still locked                    release_token = true;                    break;                }                id = token->m_Ids[i];            }}            try {                CSeqMatch_Info info = m_DataSource.BestResolve(id);                if ( info ) {                    TTSE_Lock tse(&info.GetTSE_Info());                    if (tse) {                        token->AddResolvedId(i, tse);                    }                }            } catch (...) {                // BestResolve() failed, go to the next id.            }        }        if (release_token) {            token.Reset();        }    } while (true);    return 0;}END_SCOPE(objects)END_NCBI_SCOPE/** ---------------------------------------------------------------------------* $Log: prefetch_impl.cpp,v $* Revision 1000.2  2004/06/01 19:23:32  gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5** Revision 1.5  2004/05/21 21:42:12  gorelenk* Added PCH ncbi_pch.hpp** Revision 1.4  2004/05/07 13:47:35  grichenk* Removed single-id constructors.* Added non-locking prefetch mode.** Revision 1.3  2004/04/26 14:15:33  grichenk* Catch exceptions in the prefetching thread** Revision 1.2  2004/04/19 14:52:29  grichenk* Added prefetch depth limit, redesigned prefetch queue.** Revision 1.1  2004/04/16 13:30:34  grichenk* Initial revision*** ===========================================================================*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?