Line data Source code
1 :
2 : /* Copyright (c) 2006-2013, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2012-2013, Daniel Nachbaur <danielnachbaur@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #define TEST_RUNTIME 300 // seconds
20 : #include <test.h>
21 : #include <lunchbox/clock.h>
22 : #include <lunchbox/refPtr.h>
23 : #include <lunchbox/referenced.h>
24 : #include <lunchbox/thread.h>
25 : #include <iostream>
26 :
27 : #include <boost/intrusive_ptr.hpp>
28 : #include <boost/make_shared.hpp>
29 : #include <boost/shared_ptr.hpp>
30 : #include <boost/serialization/access.hpp>
31 : #include <boost/archive/text_oarchive.hpp>
32 : #include <boost/archive/text_iarchive.hpp>
33 :
34 : #define NTHREADS 24
35 : #define NREFS 200000
36 :
37 : class Foo : public lunchbox::Referenced
38 : {
39 : public:
40 4 : Foo() {}
41 :
42 : private:
43 8 : virtual ~Foo() {}
44 :
45 : friend class boost::serialization::access;
46 2 : template< class Archive > void serialize( Archive&, unsigned int ) {}
47 : };
48 :
49 : typedef lunchbox::RefPtr<Foo> FooPtr;
50 1 : FooPtr foo;
51 :
52 48 : class TestThread : public lunchbox::Thread
53 : {
54 : public:
55 24 : virtual void run()
56 : {
57 24 : FooPtr myFoo;
58 2460446 : for( size_t i = 0; i<NREFS; ++i )
59 : {
60 2460422 : myFoo = foo;
61 2545120 : foo = myFoo;
62 2794891 : myFoo = 0;
63 24 : }
64 24 : }
65 : };
66 :
67 : typedef boost::intrusive_ptr<Foo> BoostPtr;
68 1 : BoostPtr bFoo;
69 :
70 48 : class BThread : public lunchbox::Thread
71 : {
72 : public:
73 24 : virtual void run()
74 : {
75 24 : BoostPtr myBoost;
76 3310867 : for( size_t i = 0; i<NREFS; ++i )
77 : {
78 3310843 : myBoost = bFoo;
79 3335071 : bFoo = myBoost;
80 3338016 : myBoost = 0;
81 24 : }
82 24 : }
83 : };
84 :
85 : class Bar : public lunchbox::Referenced
86 : {
87 : public:
88 2 : Bar() {}
89 3 : virtual ~Bar() {}
90 : };
91 :
92 : typedef boost::shared_ptr<Bar> BarPtr;
93 1 : BarPtr bBar;
94 :
95 48 : class BarThread : public lunchbox::Thread
96 : {
97 : public:
98 48 : virtual void run()
99 : {
100 48 : BarPtr myBar;
101 7165684 : for( size_t i = 0; i<NREFS; ++i )
102 : {
103 7165636 : myBar = bBar;
104 4345937 : bBar = myBar;
105 7248309 : myBar.reset();
106 48 : }
107 48 : }
108 : };
109 :
110 1 : int main( int, char** )
111 : {
112 1 : foo = new Foo;
113 :
114 25 : TestThread threads[NTHREADS];
115 2 : lunchbox::Clock clock;
116 25 : for( size_t i=0; i<NTHREADS; ++i )
117 24 : TEST( threads[i].start( ));
118 :
119 25 : for( size_t i=0; i<NTHREADS; ++i )
120 24 : TEST( threads[i].join( ));
121 :
122 1 : const float time = clock.getTimef();
123 1 : std::cout << time << " ms for " << 3*NREFS << " lunchbox::RefPtr operations"
124 1 : << " in " << NTHREADS << " threads ("
125 2 : << time/(3*NREFS*NTHREADS)*1000000 << "ns/op)" << std::endl;
126 :
127 1 : TEST( foo->getRefCount() == 1 );
128 :
129 1 : bFoo = new Foo;
130 2 : BThread bThreads[NTHREADS];
131 1 : clock.reset();
132 25 : for( size_t i=0; i<NTHREADS; ++i )
133 24 : TEST( bThreads[i].start( ));
134 :
135 25 : for( size_t i=0; i<NTHREADS; ++i )
136 24 : TEST( bThreads[i].join( ));
137 :
138 1 : const float bTime = clock.getTimef();
139 1 : std::cout << bTime << " ms for " << 3*NREFS << " boost::intrusive_ptr ops "
140 1 : << "in " << NTHREADS << " threads ("
141 2 : << bTime/(3*NREFS*NTHREADS)*1000000 << "ns/op)" << std::endl;
142 :
143 1 : TEST( bFoo->getRefCount() == 1 );
144 :
145 2 : boost::intrusive_ptr< Foo > boostFoo( foo.get( ));
146 1 : TEST( foo->getRefCount() == 2 );
147 :
148 1 : boostFoo = 0;
149 1 : TEST( foo->getRefCount() == 1 );
150 :
151 1 : bBar = BarPtr( new Bar );
152 2 : BarThread barThreads[NTHREADS];
153 :
154 1 : clock.reset();
155 25 : for( size_t i=0; i<NTHREADS; ++i )
156 24 : TEST( barThreads[i].start( ));
157 :
158 25 : for( size_t i=0; i<NTHREADS; ++i )
159 24 : TEST( barThreads[i].join( ));
160 :
161 1 : const float barTime = clock.getTimef();
162 1 : std::cout << barTime << " ms for " << 3*NREFS <<" boost::shared_ptr ops in "
163 2 : << NTHREADS << " threads (" << barTime/(3*NREFS*NTHREADS)*1000000
164 1 : << "ns/op)" << std::endl;
165 :
166 1 : bBar = boost::make_shared< Bar >();
167 1 : clock.reset();
168 25 : for( size_t i=0; i<NTHREADS; ++i )
169 24 : TEST( barThreads[i].start( ));
170 :
171 25 : for( size_t i=0; i<NTHREADS; ++i )
172 24 : TEST( barThreads[i].join( ));
173 :
174 1 : const float barTime2 = clock.getTimef();
175 1 : std::cout << barTime2 << " ms for " << 3*NREFS<<" boost::shared_ptr ops in "
176 2 : << NTHREADS << " threads (" << barTime2/(3*NREFS*NTHREADS)*1000000
177 1 : << "ns/op) using make_shared" << std::endl;
178 :
179 1 : foo = 0;
180 :
181 2 : FooPtr inFoo1( new Foo );
182 1 : TEST( inFoo1->getRefCount() == 1 );
183 2 : FooPtr inFoo2 = inFoo1;
184 1 : TEST( inFoo2->getRefCount() == 2 );
185 2 : FooPtr outFoo1;
186 2 : std::stringstream stream;
187 2 : boost::archive::text_oarchive oar( stream );
188 1 : oar & inFoo1;
189 2 : boost::archive::text_iarchive iar( stream );
190 1 : iar & outFoo1;
191 1 : TEST( outFoo1->getRefCount() == 1 );
192 2 : FooPtr outFoo2 = outFoo1;
193 1 : TEST( outFoo2->getRefCount() == 2 );
194 :
195 26 : return EXIT_SUCCESS;
196 3 : }
|