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

📄 grammar_mt_tests.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
字号:
/*=============================================================================
    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 multithreading
static void skipped()
{
    std::cout << "skipped\n";
}

int
main()
{
    skipped();
    return 0;
}

#else
// the real MT stuff

#undef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE

#include <boost/thread/thread.hpp>
#include <boost/spirit/core/non_terminal/grammar.hpp>
#include <boost/spirit/core/non_terminal/rule.hpp>
#include <boost/spirit/core/composite/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::grammar<simple>
{
    template <typename ScannerT>
    struct definition
    {
        definition(simple const& /*self*/)
        {
            top = boost::spirit::epsilon_p;
            boost::mutex::scoped_lock lock(simple_mutex);
            simple_definition_count++;
        }

        boost::spirit::rule<ScannerT> top;
        boost::spirit::rule<ScannerT> const &start() const { return top; }
    };
};

struct count_guard
{
    count_guard(int &c) : counter(c) {}
    ~count_guard() { counter = 0; }
private:
    int &counter;
};

static void
milli_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 void
nap()
{
    // this function is called by various threads to ensure
    // that thread lifetime actually overlap
    milli_sleep(300);
}

template <typename GrammarT>
static void
make_definition(GrammarT &g)
{
    char const *text="blah";
    boost::spirit::scanner<> s(text, text+4);

    g.parse(s);
}

template <typename GrammarT>
static void
make_definition3(GrammarT &g)
{
    char const *text="blah";
    boost::spirit::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 void
multiple_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;
};

static void
single_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(boost::ref(task1));
    boost::thread t2(boost::ref(task2));
    boost::thread t3(boost::ref(task3));
    boost::thread t4(boost::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 void
multiple_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(boost::ref(task1));
    boost::thread t2(boost::ref(task2));
    boost::thread t3(boost::ref(task3));
    boost::thread t4(boost::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 void
single_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(boost::ref(task1));
    boost::thread t2(boost::ref(task2));
    boost::thread t3(boost::ref(task3));
    boost::thread t4(boost::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 void
multiple_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(boost::ref(task1));
    boost::thread t2(boost::ref(task2));
    boost::thread t3(boost::ref(task3));
    boost::thread t4(boost::ref(task4));

    t1.join();
    t2.join();
    t3.join();
    t4.join();

    BOOST_TEST(exactly_eight_instances_created);
}
////////////////////////////////////////////////////////////////////////////////
int
main()
{
    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::parse_info<char const *> pi;

////////////////////////////////////////////////
// These macros are used with BOOST_TEST



#endif // MT mode

⌨️ 快捷键说明

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