⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_ncbithr.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            // Cascaded R-lock must be allowed            if (w_cycle % 10 == 0) {                assert(m_RW->TryReadLock());                m_Res->BeginRead(m_Index);            }            // ======= CTls test =======            // Verify TLS - current value must be 10            assert(*m_Tls->GetValue() == 10);            // Continue CRWLock test            for (int i=0; i<7; i++) {                delay(1);                s_var++;            }            if (w_cycle % 4 == 0) {                m_Res->EndWrite(m_Index);                m_RW->Unlock();            }            if (w_cycle % 6 == 0) {                m_Res->EndRead(m_Index);                m_RW->Unlock();            }            if (w_cycle % 8 == 0) {                m_Res->EndWrite(m_Index);                m_RW->Unlock();            }            if (w_cycle % 10 == 0) {                m_Res->EndRead(m_Index);                m_RW->Unlock();            }            m_Res->EndWrite(m_Index);            m_RW->Unlock();            delay(1);        }    }    // ======= CTls test =======    // Verify TLS - current value must be 10    assert(*m_Tls->GetValue() == 10);    for (int i=0; i<5; i++) {        stored_value = new int;        assert(stored_value != 0);        *stored_value = *m_Tls->GetValue()+1;        m_Tls->SetValue(stored_value,                        TestTlsCleanup, &m_CheckValue);        assert(*stored_value == m_CheckValue+1);    }    assert(*m_Tls->GetValue() == 15);    assert(m_CheckValue == 14);    // ======= CThread::Detach() and CThread::Join() test =======    if (m_Index % 2 == 0) {        CMutexGuard exit_guard(*exit_locks[m_Index]);        delay(10); // Provide delay for join-before-exit    }    if (m_Index % 3 == 0)    {        // Never verified, since CThread::Exit() terminates the thread        // inside Test_CThreadExit().        assert(Test_CThreadExit());    }    return reinterpret_cast<void*>(-1);}///////////////////////////////////////////////////////////////////////////////  Test applicationclass CThreadedApp : public CNcbiApplication{    void Init(void);    int Run(void);};void CThreadedApp::Init(void){    // Prepare command line descriptions    auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);    // sNumThreads    arg_desc->AddDefaultKey        ("threads", "NumThreads",         "Total number of threads to create and run",         CArgDescriptions::eInteger, NStr::IntToString(sNumThreads));    arg_desc->SetConstraint        ("threads", new CArgAllow_Integers(cNumThreadsMin, cNumThreadsMax));    // sSpawnBy    arg_desc->AddDefaultKey        ("spawnby", "SpawnBy",         "Threads spawning factor",         CArgDescriptions::eInteger, NStr::IntToString(sSpawnBy));    arg_desc->SetConstraint        ("spawnby", new CArgAllow_Integers(cSpawnByMin, cSpawnByMax));    // sNumRCycles    arg_desc->AddDefaultKey        ("rcycles", "RCycles",         "Number of read cycles by each reader thread",         CArgDescriptions::eInteger, NStr::IntToString(sRCycles));    arg_desc->SetConstraint        ("rcycles", new CArgAllow_Integers(cRCyclesMin, cRCyclesMax));    // sNumWCycles    arg_desc->AddDefaultKey        ("wcycles", "WCycles",         "Number of write cycles by each writer thread",         CArgDescriptions::eInteger, NStr::IntToString(sWCycles));    arg_desc->SetConstraint        ("wcycles", new CArgAllow_Integers(cWCyclesMin, cWCyclesMax));    string prog_description =        "This is a program testing thread, TLS, mutex and RW-lock classes.";    arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),                              prog_description, false);    SetupArgDescriptions(arg_desc.release());}int CThreadedApp::Run(void){# if defined(NCBI_POSIX_THREADS)    NcbiCout << "OS: Unix" << NcbiEndl;# elif defined(NCBI_WIN32_THREADS)    NcbiCout << "OS: MS-Windows" << NcbiEndl;# else    NcbiCout << "OS: unknown" << NcbiEndl;# endif    // Process command line    const CArgs& args = GetArgs();    sNumThreads = args["threads"].AsInteger();    sSpawnBy    = args["spawnby"].AsInteger();    sRCycles    = args["rcycles"].AsInteger();    sWCycles    = args["wcycles"].AsInteger();    NcbiCout << "Test parameters:" << NcbiEndl;    NcbiCout << "\tTotal threads     " << sNumThreads << NcbiEndl;    NcbiCout << "\tSpawn threads by  " << sSpawnBy << NcbiEndl;    NcbiCout << "\tR-cycles          " << sRCycles << NcbiEndl;    NcbiCout << "\tW-cycles          " << sWCycles << NcbiEndl << NcbiEndl;    // Redirect error log to hide messages sent by delay()    SetDiagStream(0);    // Test CBaseTls::Discard()    NcbiCout << "Creating/discarding TLS test...";    int main_cleanup_flag = 0;    CTls<int>* dummy_tls = new CTls<int>;    assert(main_cleanup_flag == 0);    dummy_tls->SetValue(&main_cleanup_flag, Main_Thread_Tls_Cleanup);    assert(main_cleanup_flag == 0);    dummy_tls->Discard();    assert(main_cleanup_flag == 1);    NcbiCout << " Passed" << NcbiEndl << NcbiEndl;    // Create test objects    main_cleanup_flag = 0;    CRef< CTls<int> > tls(new CTls<int>);    tls->SetValue(0);    CRWLock rw;    CSharedResource res;    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << "===== Starting threads =====" << NcbiEndl;    }}    // Prepare exit-locks, lock each 2nd mutex    // They will be used by join/detach before exit    for (int i=0; i<sNumThreads; i++) {        states[i] = eNull;        exit_locks[i] = new CMutex;        if (i % 2 == 0) {            exit_locks[i]->Lock();        }    }    // Create and run threads    for (int i=0; i<sSpawnBy; i++) {        int idx;        {{            CFastMutexGuard spawn_guard(s_GlobalLock);            if (s_NextIndex >= sNumThreads) {                break;            }            idx = s_NextIndex;            s_NextIndex++;        }}        // Check Discard() for some threads        if (i % 2 == 0) {            thr[idx] = new CTestThread(idx, tls, &rw, &res);            assert(states[idx] == eCreated);            thr[idx]->Discard();            assert(states[idx] == eDestroyed);        }                thr[idx] = new CTestThread(idx, tls, &rw, &res);        assert(states[idx] == eCreated);        thr[idx]->Run();        {{            CFastMutexGuard guard(s_GlobalLock);            NcbiCout << idx << " ";        }}    }    // Wait for all threads running    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Waiting for all threads to run =====" << NcbiEndl;    }}    map<int, bool> thread_map;    for (int i=0; i<sNumThreads; i++) {        thread_map[i] = false;    }    int ready = 0;    while (ready < sNumThreads) {        ready = 0;        for (int i=0; i<sNumThreads; i++) {            if (states[i] >= eRunning) {                ready++;                if ( !thread_map[i] ) {                    CFastMutexGuard guard(s_GlobalLock);                    NcbiCout << i << " ";                    thread_map[i] = true;                }            }        }    }    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Joining threads before exit =====" << NcbiEndl;    }}    for (int i=0; i<sNumThreads; i++) {        // Try to join before exit        if (i % 4 == 2) {            assert(states[i] < eTerminated);            exit_locks[i]->Unlock();            void* exit_data = 0;            thr[i]->Join(&exit_data);            // Must be set to 1 by Main()            assert(exit_data != 0);            {{                CFastMutexGuard guard(s_GlobalLock);                NcbiCout << i << " ";            }}        }    }    // Reset CRef to the test tls. One more CRef to the object    // must have been stored in the CThread's m_UsedTlsSet.    assert(main_cleanup_flag == 0);    tls.Reset();    assert(main_cleanup_flag == 0);    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Detaching threads before exit =====" << NcbiEndl;    }}    for (int i=0; i<sNumThreads; i++) {        // Detach before exit        if (i % 4 == 0) {            assert(states[i] < eTerminated);            thr[i]->Detach();            exit_locks[i]->Unlock();            {{                CFastMutexGuard guard(s_GlobalLock);                NcbiCout << i << " ";            }}        }    }    // Wait for all threads to exit    delay(10);    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Detaching threads after exit =====" << NcbiEndl;    }}    for (int i=0; i<sNumThreads; i++) {        // Detach after exit        if (i % 4 == 1) {            assert(states[i] != eDestroyed);            thr[i]->Detach();            {{                CFastMutexGuard guard(s_GlobalLock);                NcbiCout << i << " ";            }}        }    }    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Joining threads after exit =====" << NcbiEndl;    }}    for (int i=0; i<sNumThreads; i++) {        // Join after exit        if (i % 4 == 3) {            assert(states[i] != eDestroyed);            thr[i]->Join();            {{                CFastMutexGuard guard(s_GlobalLock);                NcbiCout << i << " ";            }}        }    }    // Wait for all threads to be destroyed    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl <<                    "===== Waiting for all threads to be destroyed =====" << NcbiEndl;    }}    for (int i=0; i<sNumThreads; i++) {        thread_map[i] = false;    }    ready = 0;    while (ready < sNumThreads) {        ready = 0;        for (int i=0; i<sNumThreads; i++) {            if (states[i] == eDestroyed) {                ready++;                if ( !thread_map[i] ) {                    CFastMutexGuard guard(s_GlobalLock);                    NcbiCout << i << " ";                    thread_map[i] = true;                    delete exit_locks[i];                }            }        }    }    {{        CFastMutexGuard guard(s_GlobalLock);        NcbiCout << NcbiEndl << NcbiEndl << "Test passed" << NcbiEndl;    }}    return 0;}///////////////////////////////////////////////////////////////////////////////  MAINint main(int argc, const char* argv[]) {    CThreadedApp app;    return app.AppMain(argc, argv, 0, eDS_Default, 0);}/* * =========================================================================== * $Log: test_ncbithr.cpp,v $ * Revision 1000.1  2004/06/01 19:10:21  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.7 * * Revision 6.7  2004/05/14 13:59:51  gorelenk * Added include of ncbi_pch.hpp * * Revision 6.6  2002/11/04 21:29:05  grichenk * Fixed usage of const CRef<> and CRef<> constructor * * Revision 6.5  2002/09/19 20:05:43  vasilche * Safe initialization of static mutexes * * Revision 6.4  2002/04/16 18:49:09  ivanov * Centralize threatment of assert() in tests. * Added #include <test/test_assert.h>. CVS log moved to end of file. * * Revision 6.3  2002/03/13 05:02:09  vakatov * sNumThreads = 35;  sSpawnBy = 6; * * Revision 6.2  2001/04/03 18:21:23  grichenk * + test for CThread::Exit() * * Revision 6.1  2001/03/13 22:45:20  vakatov * Initial revision * * =========================================================================== */

⌨️ 快捷键说明

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