test_mt.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:9k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_mt.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:09:33  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_mt.cpp,v 1000.2 2004/06/01 19:09:33 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Aleksey Grichenko
  35.  *
  36.  * File Description:
  37.  *   Wrapper for testing modules in MT environment
  38.  *
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <corelib/test_mt.hpp>
  42. #include <corelib/ncbimtx.hpp>
  43. #include <test/test_assert.h>  /* This header must go last */
  44. BEGIN_NCBI_SCOPE
  45. DEFINE_STATIC_FAST_MUTEX(s_GlobalLock);
  46. static CThreadedApp* s_Application;
  47. // Default values
  48. unsigned int  s_NumThreads    = 34;
  49. int           s_SpawnBy       = 6;
  50. // Next test thread index
  51. static volatile unsigned int  s_NextIndex = 0;
  52. /////////////////////////////////////////////////////////////////////////////
  53. // Test thread
  54. //
  55. class CTestThread : public CThread
  56. {
  57. public:
  58.     CTestThread(int id);
  59. protected:
  60.     ~CTestThread(void);
  61.     virtual void* Main(void);
  62.     virtual void  OnExit(void);
  63. private:
  64.     int m_Idx;
  65. };
  66. CTestThread::CTestThread(int idx)
  67.     : m_Idx(idx)
  68. {
  69.     if ( s_Application != 0 )
  70.         assert(s_Application->Thread_Init(m_Idx));
  71. }
  72. CTestThread::~CTestThread(void)
  73. {
  74.     if ( s_Application != 0 )
  75.         assert(s_Application->Thread_Destroy(m_Idx));
  76. }
  77. void CTestThread::OnExit(void)
  78. {
  79.     if ( s_Application != 0 )
  80.         assert(s_Application->Thread_Exit(m_Idx));
  81. }
  82. CRef<CTestThread> thr[k_NumThreadsMax];
  83. void* CTestThread::Main(void)
  84. {
  85.     int spawn_max;
  86.     int first_idx;
  87.     {{
  88.         CFastMutexGuard spawn_guard(s_GlobalLock);
  89.         spawn_max = s_NumThreads - s_NextIndex;
  90.         if (spawn_max > s_SpawnBy) {
  91.             spawn_max = s_SpawnBy;
  92.         }
  93.         first_idx = s_NextIndex;
  94.         s_NextIndex += s_SpawnBy;
  95.     }}
  96.     // Spawn more threads
  97.     for (int i = first_idx; i < first_idx + spawn_max; i++) {
  98.         thr[i] = new CTestThread(i);
  99.         // Allow threads to run even in single thread environment
  100.         thr[i]->Run(CThread::fRunAllowST);
  101.     }
  102.     // Run the test
  103.     if ( s_Application != 0 && s_Application->Thread_Run(m_Idx) ) {
  104.         return this;
  105.     }
  106.     return 0;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. //  Test application
  110. CThreadedApp::CThreadedApp(void)
  111. {
  112.     s_Application = this;
  113. }
  114. CThreadedApp::~CThreadedApp(void)
  115. {
  116.     s_Application = 0;
  117. }
  118. void CThreadedApp::Init(void)
  119. {
  120.     // Prepare command line descriptions
  121.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  122.     // s_NumThreads
  123.     arg_desc->AddDefaultKey
  124.         ("threads", "NumThreads",
  125.          "Total number of threads to create and run",
  126.          CArgDescriptions::eInteger, NStr::IntToString(s_NumThreads));
  127.     arg_desc->SetConstraint
  128.         ("threads", new CArgAllow_Integers(k_NumThreadsMin, k_NumThreadsMax));
  129.     // s_NumThreads (emulation in ST)
  130.     arg_desc->AddDefaultKey
  131.         ("repeats", "NumRepeats",
  132.          "In non-MT mode only(!) -- how many times to repeat the test. "
  133.          "If passed 0, then the value of argument `-threads' will be used.",
  134.          CArgDescriptions::eInteger, "0");
  135.     arg_desc->SetConstraint
  136.         ("repeats", new CArgAllow_Integers(0, k_NumThreadsMax));
  137.     // s_SpawnBy
  138.     arg_desc->AddDefaultKey
  139.         ("spawnby", "SpawnBy",
  140.          "Threads spawning factor",
  141.          CArgDescriptions::eInteger, NStr::IntToString(s_SpawnBy));
  142.     arg_desc->SetConstraint
  143.         ("spawnby", new CArgAllow_Integers(k_SpawnByMin, k_SpawnByMax));
  144.     // Let test application add its own arguments
  145.     TestApp_Args(*arg_desc);
  146.     string prog_description =
  147.         "MT-environment test";
  148.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
  149.                               prog_description, false);
  150.     SetupArgDescriptions(arg_desc.release());
  151. }
  152. int CThreadedApp::Run(void)
  153. {
  154.     // Process command line
  155.     const CArgs& args = GetArgs();
  156. #if !defined(_MT)
  157.     s_NumThreads = args["repeats"].AsInteger();
  158.     if ( !s_NumThreads )
  159. #endif
  160.         s_NumThreads = args["threads"].AsInteger();
  161.     s_SpawnBy = args["spawnby"].AsInteger();
  162.     //
  163.     assert(TestApp_Init());
  164. #if defined(_MT)
  165.     LOG_POST("Running " << s_NumThreads << " threads");
  166. #else
  167.     LOG_POST("Simulating " << s_NumThreads << " threads in ST mode");
  168. #endif
  169.     int spawn_max;
  170.     int first_idx;
  171.     {{
  172.         CFastMutexGuard spawn_guard(s_GlobalLock);
  173.         spawn_max = s_NumThreads - s_NextIndex;
  174.         if (spawn_max > s_SpawnBy) {
  175.             spawn_max = s_SpawnBy;
  176.         }
  177.         first_idx = s_NextIndex;
  178.         s_NextIndex += s_SpawnBy;
  179.     }}
  180.     // Create and run threads
  181.     for (int i = first_idx; i < first_idx + spawn_max; i++) {
  182.         thr[i] = new CTestThread(i);
  183.         // Allow threads to run even in single thread environment
  184.         thr[i]->Run(CThread::fRunAllowST);
  185.     }
  186.     // Wait for all threads
  187.     for (unsigned int i=0; i<s_NumThreads; i++) {
  188.         void* ok;
  189.         thr[i]->Join(&ok);
  190.         assert(ok);
  191.     }
  192.     assert(TestApp_Exit());
  193.     // Destroy all threads
  194.     for (unsigned int i=0; i<s_NumThreads; i++) {
  195.         thr[i].Reset();
  196.     }
  197.     return 0;
  198. }
  199. bool CThreadedApp::Thread_Init(int /*idx*/)
  200. {
  201.     return true;
  202. }
  203. bool CThreadedApp::Thread_Run(int /*idx*/)
  204. {
  205.     return true;
  206. }
  207. bool CThreadedApp::Thread_Exit(int /*idx*/)
  208. {
  209.     return true;
  210. }
  211. bool CThreadedApp::Thread_Destroy(int /*idx*/)
  212. {
  213.     return true;
  214. }
  215. bool CThreadedApp::TestApp_Args(CArgDescriptions& /*args*/)
  216. {
  217.     return true;
  218. }
  219. bool CThreadedApp::TestApp_Init(void)
  220. {
  221.     return true;
  222. }
  223. bool CThreadedApp::TestApp_Exit(void)
  224. {
  225.     return true;
  226. }
  227. END_NCBI_SCOPE
  228. /*
  229.  * ===========================================================================
  230.  * $Log: test_mt.cpp,v $
  231.  * Revision 1000.2  2004/06/01 19:09:33  gouriano
  232.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  233.  *
  234.  * Revision 1.9  2004/05/14 13:59:27  gorelenk
  235.  * Added include of ncbi_pch.hpp
  236.  *
  237.  * Revision 1.8  2003/12/12 23:41:29  vakatov
  238.  * + cmd.-line arg `-repeats' to alternate the number of test execution repeats
  239.  *   in single-thread mode
  240.  *
  241.  * Revision 1.7  2003/10/22 17:55:54  vasilche
  242.  * Do not call assert() from threads - check result in main function.
  243.  *
  244.  * Revision 1.6  2003/05/16 15:58:28  grichenk
  245.  * Display running/simulating message only once.
  246.  *
  247.  * Revision 1.5  2003/05/08 20:50:10  grichenk
  248.  * Allow MT tests to run in ST mode using CThread::fRunAllowST flag.
  249.  *
  250.  * Revision 1.4  2002/12/26 16:39:23  vasilche
  251.  * Object manager class CSeqMap rewritten.
  252.  *
  253.  * Revision 1.3  2002/09/19 20:05:43  vasilche
  254.  * Safe initialization of static mutexes
  255.  *
  256.  * Revision 1.2  2002/04/30 19:09:47  gouriano
  257.  * added possibility to add custom arguments
  258.  *
  259.  * Revision 1.1  2002/04/23 13:11:49  gouriano
  260.  * test_mt.cpp/hpp moved into another location
  261.  *
  262.  * Revision 6.5  2002/04/16 18:49:07  ivanov
  263.  * Centralize threatment of assert() in tests.
  264.  * Added #include <test/test_assert.h>. CVS log moved to end of file.
  265.  *
  266.  * Revision 6.4  2002/04/10 18:38:19  ivanov
  267.  * Moved CVS log to end of file
  268.  *
  269.  * Revision 6.3  2002/03/14 19:48:25  gouriano
  270.  * changed sNumThreads = 36:
  271.  * in test_semaphore_mt number of threads must be even
  272.  *
  273.  * Revision 6.2  2002/03/13 05:50:19  vakatov
  274.  * sNumThreads = 35;  sSpawnBy = 6;  (to work on SCHROEDER)
  275.  *
  276.  * Revision 6.1  2001/04/06 15:53:08  grichenk
  277.  * Initial revision
  278.  *
  279.  * ===========================================================================
  280.  */