grammar_mt_tests.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 317 行

CPP
317
字号
/*=============================================================================    Copyright (c) 2003 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)=============================================================================*/#include <iostream>#include <boost/config.hpp>#include <boost/detail/lightweight_test.hpp>#if defined(DONT_HAVE_BOOST) || !defined(BOOST_HAS_THREADS) || defined(BOOST_DISABLE_THREADS)// we end here if we can't do multithreadingstatic void skipped(){    std::cout << "skipped\n";}intmain(){    skipped();    return 0;}#else// the real MT stuff#undef BOOST_SPIRIT_THREADSAFE#define BOOST_SPIRIT_THREADSAFE#include <boost/thread/thread.hpp>#include <boost/spirit/include/classic_grammar.hpp>#include <boost/spirit/include/classic_rule.hpp>#include <boost/spirit/include/classic_epsilon.hpp>#include <boost/thread/xtime.hpp>#include <boost/ref.hpp>static boost::mutex simple_mutex;static int simple_definition_count = 0;struct simple : public BOOST_SPIRIT_CLASSIC_NS::grammar<simple>{    template <typename ScannerT>    struct definition    {        definition(simple const& /*self*/)        {            top = BOOST_SPIRIT_CLASSIC_NS::epsilon_p;            boost::mutex::scoped_lock lock(simple_mutex);            simple_definition_count++;        }        BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> top;        BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> const &start() const { return top; }    };};struct count_guard{    count_guard(int &c) : counter(c) {}    ~count_guard() { counter = 0; }private:    int &counter;};static voidmilli_sleep(unsigned long milliseconds){    static long const nanoseconds_per_second = 1000L*1000L*1000L;    boost::xtime xt;    boost::xtime_get(&xt, boost::TIME_UTC);    xt.nsec+=1000*1000*milliseconds;    while (xt.nsec > nanoseconds_per_second)    {        xt.nsec -= nanoseconds_per_second;        xt.sec++;    }            boost::thread::sleep(xt);}static voidnap(){    // this function is called by various threads to ensure    // that thread lifetime actually overlap    milli_sleep(300);}template <typename GrammarT>static voidmake_definition(GrammarT &g){    char const *text="blah";    BOOST_SPIRIT_CLASSIC_NS::scanner<> s(text, text+4);    g.parse(s);}template <typename GrammarT>static voidmake_definition3(GrammarT &g){    char const *text="blah";    BOOST_SPIRIT_CLASSIC_NS::scanner<> s(text, text+4);    g.parse(s);    nap();    g.parse(s);    g.parse(s);}////////////////////////////////////////////////////////////////////////////////#define exactly_one_instance_created simple_definition_count == 1#define exactly_two_instances_created simple_definition_count == 2#define exactly_four_instances_created simple_definition_count == 4#define exactly_eight_instances_created simple_definition_count == 8////////////////////////////////////////////////////////////////////////////////static voidmultiple_attempts_to_instantiate_a_definition_from_a_single_thread(){    // checks wether exactly one definition per grammar    // object is created    count_guard guard(simple_definition_count);    simple simple1_p;    simple simple2_p;    make_definition(simple1_p);    make_definition(simple1_p);    make_definition(simple1_p);    BOOST_TEST(exactly_one_instance_created);    make_definition(simple2_p);    make_definition(simple2_p);    make_definition(simple2_p);    BOOST_TEST(exactly_two_instances_created);}////////////////////////////////////////////////////////////////////////////////struct single_grammar_object_task{    void operator()() const    {        make_definition3(simple1_p);    };    simple simple1_p;};////////////////////////////////////////////////////////////////////////////////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);}////////////////////////////////////////////////////////////////////////////////static voidsingle_local_grammar_object_multiple_threads(){    // check wether independent definition objects are    // created    count_guard guard(simple_definition_count);    single_grammar_object_task task1, task2, task3, task4;    boost::thread t1(callable_ref(task1));    boost::thread t2(callable_ref(task2));    boost::thread t3(callable_ref(task3));    boost::thread t4(callable_ref(task4));    t1.join();    t2.join();    t3.join();    t4.join();    BOOST_TEST(exactly_four_instances_created);}////////////////////////////////////////////////////////////////////////////////struct two_grammar_objects_task{    void operator()() const    {        make_definition3(simple1_p);        make_definition3(simple2_p);    };    simple simple1_p;    simple simple2_p;};static voidmultiple_local_grammar_objects_multiple_threads(){    // check wether exactly one definition per thread     // and per grammar object is created    count_guard guard(simple_definition_count);    two_grammar_objects_task task1, task2, task3, task4;    boost::thread t1(callable_ref(task1));    boost::thread t2(callable_ref(task2));    boost::thread t3(callable_ref(task3));    boost::thread t4(callable_ref(task4));    t1.join();    t2.join();    t3.join();    t4.join();    BOOST_TEST(exactly_eight_instances_created);}////////////////////////////////////////////////////////////////////////////////static simple global_simple1_p;struct single_global_grammar_object_task{    void operator()() const    {        make_definition3(global_simple1_p);    };};static voidsingle_global_grammar_object_multiple_threads(){    // check wether exactly one definition per thread is    // created    count_guard guard(simple_definition_count);    single_global_grammar_object_task task1, task2, task3, task4;    boost::thread t1(callable_ref(task1));    boost::thread t2(callable_ref(task2));    boost::thread t3(callable_ref(task3));    boost::thread t4(callable_ref(task4));    t1.join();    t2.join();    t3.join();    t4.join();    BOOST_TEST(exactly_four_instances_created);}////////////////////////////////////////////////////////////////////////////////static simple global_simple2_p;static simple global_simple3_p;struct multiple_global_grammar_objects_task{    void operator()() const    {        make_definition3(global_simple2_p);        make_definition3(global_simple3_p);    };};static voidmultiple_global_grammar_objects_multiple_threads(){    // check wether exactly one definition per thread     // and per grammar object is created    count_guard guard(simple_definition_count);    multiple_global_grammar_objects_task task1, task2, task3, task4;    boost::thread t1(callable_ref(task1));    boost::thread t2(callable_ref(task2));    boost::thread t3(callable_ref(task3));    boost::thread t4(callable_ref(task4));    t1.join();    t2.join();    t3.join();    t4.join();    BOOST_TEST(exactly_eight_instances_created);}////////////////////////////////////////////////////////////////////////////////intmain(){    multiple_attempts_to_instantiate_a_definition_from_a_single_thread();    single_local_grammar_object_multiple_threads();    multiple_local_grammar_objects_multiple_threads();    single_global_grammar_object_multiple_threads();    multiple_global_grammar_objects_multiple_threads();    return boost::report_errors();}////////////////////////////////////////////////////////////////////////////////static BOOST_SPIRIT_CLASSIC_NS::parse_info<char const *> pi;////////////////////////////////////////////////// These macros are used with BOOST_TEST#endif // MT mode

⌨️ 快捷键说明

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