Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/spirit/test/owi_mt_tests.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 5.2 KB
Line 
1/*=============================================================================
2    Copyright (c) 2002-2004 Martin Wille
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9
10// std::lower_bound seems to perform awfully slow with _GLIBCXX_DEBUG enabled
11#undef _GLIBCXX_DEBUG
12
13#include <iostream>
14#include <boost/config.hpp>
15#include <boost/detail/lightweight_test.hpp>
16
17#if !defined(BOOST_HAS_THREADS) || defined(DONT_HAVE_BOOST) || defined(BOOST_DISABLE_THREADS)
18static void skipped()
19{
20    std::cout << "skipped\n";
21}
22
23int
24main()
25{
26    skipped();
27    return 0;
28}
29#else
30
31////////////////////////////////////////////////////////////////////////////////
32
33static const unsigned long initial_test_size = 5000UL;
34#if defined(_DEBUG) && (BOOST_MSVC >= 1400)
35static const unsigned long maximum_test_size = 10000UL;
36#else
37static const unsigned long maximum_test_size = 1000000UL;
38#endif
39
40////////////////////////////////////////////////////////////////////////////////
41
42#undef BOOST_SPIRIT_THREADSAFE
43#define BOOST_SPIRIT_THREADSAFE
44
45#include <boost/thread/thread.hpp>
46#include <boost/spirit/core/non_terminal/impl/object_with_id.ipp>
47#include <boost/ref.hpp>
48#include <boost/thread/xtime.hpp>
49#include <vector>
50#include <algorithm>
51#include <boost/detail/lightweight_test.hpp>
52
53using boost::spirit::impl::object_with_id;
54
55struct tag1 {};
56typedef object_with_id<tag1> class1;
57
58unsigned long test_size = initial_test_size;
59boost::xtime start_time;
60
61template <typename ClassT>
62struct test_task
63{
64    test_task() : v(), m(), progress(0) {}
65
66    void operator ()()
67    {   // create lots of objects
68        unsigned long i = 0;
69
70        v.reserve(maximum_test_size);
71        do
72        {
73            for (; i<test_size; ++i)
74                v.push_back(new ClassT);
75        }
76        while ( i < increase_test_size(i) );
77    }
78
79    static unsigned long
80    increase_test_size(unsigned long size)
81    {
82        static boost::mutex  m;
83        boost::mutex::scoped_lock l(m);
84
85        if (size<test_size || test_size == maximum_test_size)
86            return test_size;
87
88        boost::xtime now;
89        boost::xtime_get(&now, boost::TIME_UTC);
90        unsigned long seconds = now.sec - start_time.sec;
91        if (seconds < 4)
92        {
93            test_size *= 2;
94            if (test_size > maximum_test_size)
95                test_size = maximum_test_size;
96        }
97
98        return test_size;
99    }
100
101    std::vector<ClassT*> const &data() const
102    {
103        return v;
104    }
105
106private:
107    std::vector<ClassT*> v;
108    boost::mutex         m;
109    unsigned int         progress;
110};
111
112test_task<class1> test1;
113test_task<class1> test2;
114test_task<class1> test3;
115
116
117template <typename ClassT>
118void
119check_ascending(test_task<ClassT> const &t)
120{
121    typedef typename std::vector<ClassT*>::const_iterator iter;
122    iter p(t.data().begin());
123    iter const e(t.data().end());
124    iter n(p);
125
126    while (++n!=e)
127    {
128        if ((**n).get_object_id()<=(**p).get_object_id())
129        {
130            using namespace std;
131            throw std::runtime_error("object ids out of order");
132        }
133        p = n;
134    }
135};
136
137struct less1
138{
139    bool operator()(class1 const *p, class1 const *q) const
140    {
141        return p->get_object_id() < q->get_object_id();
142    }
143};
144
145template <typename ClassT>
146void
147check_not_contained_in(
148    test_task<ClassT> const &candidate,
149    test_task<ClassT> const &in
150)
151{
152    typedef typename std::vector<ClassT*>::const_iterator iter;
153    iter p(candidate.data().begin());
154    iter const e(candidate.data().end());
155
156    while (p!=e)
157    {
158        iter found = std::lower_bound(in.data().begin(),in.data().end(),*p,less1());
159        if  (found!=in.data().end() &&
160            (**found).get_object_id() == (**p).get_object_id())
161        {
162            using namespace std;
163            throw std::runtime_error("object ids not unqiue");
164        }
165        ++p;
166    }
167};
168
169void concurrent_creation_of_objects()
170{
171    {
172        boost::xtime_get(&start_time, boost::TIME_UTC);
173        boost::thread thread1(boost::ref(test1));
174        boost::thread thread2(boost::ref(test2));
175        boost::thread thread3(boost::ref(test3));
176
177        thread1.join();
178        thread2.join();
179        thread3.join();
180    }
181}
182
183void local_uniqueness()
184{
185
186
187    BOOST_TEST(test1.data().size()==test_size);
188    BOOST_TEST(test2.data().size()==test_size);
189    BOOST_TEST(test3.data().size()==test_size);
190}
191
192void local_ordering_and_uniqueness()
193{
194    // now all objects should have unique ids,
195    // the ids must be ascending within each vector
196    // check for ascending ids
197    check_ascending(test1);
198    check_ascending(test2);
199    check_ascending(test3);
200}
201
202void global_uniqueness()
203{
204    check_not_contained_in(test1,test3);
205    check_not_contained_in(test1,test2);
206    check_not_contained_in(test2,test1);
207    check_not_contained_in(test2,test3);
208    check_not_contained_in(test3,test2);
209    check_not_contained_in(test3,test1);
210}
211
212int
213main()
214{
215    concurrent_creation_of_objects();
216    local_ordering_and_uniqueness();
217    global_uniqueness();
218    return boost::report_errors();
219}
220
221#endif // BOOST_HAS_THREADS
222
Note: See TracBrowser for help on using the repository browser.