void Test1()
{
    DIVIDING_LINE_1('-');

    constexpr int Count = 2001001;

#if HAS_BOOST
    boost::recursive_mutex osMutex;
    ostream_t os(std::cout, osMutex);
#else
    ostream_t &os = std::cout;
#endif

    Stopwatch sw;
    sw.Start();

    ProducerConsumerContext context(os, Count, Count / 10, ENABLE_LOGGING);

    Producer p1(context, 0, Count / 2, 200);
    Producer p2(context, Count / 2, Count - Count / 2, 200);

    Consumer c1(context, Count / 3, 200);
    Consumer c2(context, Count / 3, 200);
    Consumer c3(context, Count - Count / 3 - Count / 3, 200);

    std::vector<std::thread> threads;
    threads.push_back(p1.Create());
    threads.push_back(p2.Create());
    threads.push_back(c1.Create());
    threads.push_back(c2.Create());
    threads.push_back(c3.Create());

    for (auto &t : threads)
        t.join();

    sw.Stop();
    std::cout << "Ellapsed time: " << sw.GetElapsedMilliseconds() << "ms" << std::endl;

    std::cout << "Checking if test is passed...\n";

    sw.Restart();
    bool ok = context.IsTestPassed();
    sw.Stop();

    std::cout << "It takes " << sw.GetElapsedMilliseconds() << "ms to figure out if test is passed." << std::endl;
    std::cout << "Is test passed? " << std::boolalpha << ok << std::endl;
}
void Test0()
{
    DIVIDING_LINE_1('-');

#if !PRODUCER_DO_MY_BEST && !CONSUMER_DO_MY_BEST
# error You are in danger of deadlock!
#endif

    constexpr int Count = 2000;

#if HAS_BOOST
    boost::recursive_mutex osMutex;
    ostream_t os(std::cout, osMutex);
#else
    ostream_t &os = std::cout;
#endif

    Stopwatch sw;
    sw.Start();

    ProducerConsumerContext context(os, Count, Count / 10, ENABLE_LOGGING);

    Producer p1(context, 0, Count / 2, 200);
    Producer p2(context, Count / 2, Count - Count / 2, 200);

    Consumer c1(context, Count / 3, 200);
    Consumer c2(context, Count / 3, 200);
    Consumer c3(context, Count - Count / 3 - Count / 3, 200);

    std::vector<std::thread> threads;
    threads.push_back(p1.Create());
    threads.push_back(p2.Create());
    threads.push_back(c1.Create());
    threads.push_back(c2.Create());
    threads.push_back(c3.Create());

    for (auto &t : threads)
        t.join();

    sw.Stop();

    std::cout << "Test Done: " << context.IsTestPassed() << ". Ellapsed time: " << sw.GetElapsedMilliseconds() << "ms\n";
}