owi_mt_tests.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 241 行
CPP
241 行
/*============================================================================= Copyright (c) 2002-2004 Martin Wille http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/// std::lower_bound seems to perform awfully slow with _GLIBCXX_DEBUG enabled#undef _GLIBCXX_DEBUG#include <iostream>#include <boost/config.hpp>#include <boost/detail/lightweight_test.hpp>#if !defined(BOOST_HAS_THREADS) || defined(DONT_HAVE_BOOST) || defined(BOOST_DISABLE_THREADS)static void skipped(){ std::cout << "skipped\n";}intmain(){ skipped(); return 0;}#else////////////////////////////////////////////////////////////////////////////////static const unsigned long initial_test_size = 5000UL;#if defined(_DEBUG) && (BOOST_MSVC >= 1400)static const unsigned long maximum_test_size = 10000UL;#elsestatic const unsigned long maximum_test_size = 1000000UL;#endif////////////////////////////////////////////////////////////////////////////////#undef BOOST_SPIRIT_THREADSAFE#define BOOST_SPIRIT_THREADSAFE#include <boost/thread/thread.hpp>#include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>#include <boost/ref.hpp>#include <boost/thread/xtime.hpp>#include <vector>#include <algorithm>#include <boost/detail/lightweight_test.hpp>using BOOST_SPIRIT_CLASSIC_NS::impl::object_with_id;struct tag1 {};typedef object_with_id<tag1> class1;unsigned long test_size = initial_test_size;boost::xtime start_time;template <typename ClassT>struct test_task{ test_task() : v(), m(), progress(0) {} void operator ()() { // create lots of objects unsigned long i = 0; v.reserve(maximum_test_size); do { for (; i<test_size; ++i) v.push_back(new ClassT); } while ( i < increase_test_size(i) ); } static unsigned long increase_test_size(unsigned long size) { static boost::mutex m; boost::mutex::scoped_lock l(m); if (size<test_size || test_size == maximum_test_size) return test_size; boost::xtime now; boost::xtime_get(&now, boost::TIME_UTC); unsigned long seconds = now.sec - start_time.sec; if (seconds < 4) { test_size *= 2; if (test_size > maximum_test_size) test_size = maximum_test_size; } return test_size; } std::vector<ClassT*> const &data() const { return v; }private: std::vector<ClassT*> v; boost::mutex m; unsigned int progress;};template <typename T>class callable_reference_wrapper : public boost::reference_wrapper<T>{public: explicit callable_reference_wrapper(T& t) : boost::reference_wrapper<T>(t) {} inline void operator()() { this->get().operator()(); }};template <typename T>callable_reference_wrapper<T>callable_ref(T &t){ return callable_reference_wrapper<T>(t);}test_task<class1> test1;test_task<class1> test2;test_task<class1> test3;template <typename ClassT>voidcheck_ascending(test_task<ClassT> const &t){ typedef typename std::vector<ClassT*>::const_iterator iter; iter p(t.data().begin()); iter const e(t.data().end()); iter n(p); while (++n!=e) { if ((**n).get_object_id()<=(**p).get_object_id()) { using namespace std; throw std::runtime_error("object ids out of order"); } p = n; }}struct less1{ bool operator()(class1 const *p, class1 const *q) const { return p->get_object_id() < q->get_object_id(); }};template <typename ClassT>voidcheck_not_contained_in( test_task<ClassT> const &candidate, test_task<ClassT> const &in){ typedef typename std::vector<ClassT*>::const_iterator iter; iter p(candidate.data().begin()); iter const e(candidate.data().end()); while (p!=e) { iter found = std::lower_bound(in.data().begin(),in.data().end(),*p,less1()); if (found!=in.data().end() && (**found).get_object_id() == (**p).get_object_id()) { using namespace std; throw std::runtime_error("object ids not unqiue"); } ++p; }}void concurrent_creation_of_objects(){ { boost::xtime_get(&start_time, boost::TIME_UTC); boost::thread thread1(callable_ref(test1)); boost::thread thread2(callable_ref(test2)); boost::thread thread3(callable_ref(test3)); thread1.join(); thread2.join(); thread3.join(); }}void local_uniqueness(){ BOOST_TEST(test1.data().size()==test_size); BOOST_TEST(test2.data().size()==test_size); BOOST_TEST(test3.data().size()==test_size);}void local_ordering_and_uniqueness(){ // now all objects should have unique ids, // the ids must be ascending within each vector // check for ascending ids check_ascending(test1); check_ascending(test2); check_ascending(test3);}void global_uniqueness(){ check_not_contained_in(test1,test3); check_not_contained_in(test1,test2); check_not_contained_in(test2,test1); check_not_contained_in(test2,test3); check_not_contained_in(test3,test2); check_not_contained_in(test3,test1);}intmain(){ concurrent_creation_of_objects(); local_ordering_and_uniqueness(); global_uniqueness(); return boost::report_errors();}#endif // BOOST_HAS_THREADS
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?