]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/smart_ptr/extras/test/sp_atomic_mt_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / smart_ptr / extras / test / sp_atomic_mt_test.cpp
CommitLineData
7c673cae
FG
1
2// Copyright (c) 2008 Peter Dimov
3//
4// Distributed under the Boost Software License, Version 1.0.
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7
8//#define USE_MUTEX
9//#define USE_RWLOCK
10
11#include <boost/config.hpp>
12
13#include <boost/shared_ptr.hpp>
14#include <boost/bind.hpp>
15
16#if defined( USE_RWLOCK )
17#include <boost/thread/shared_mutex.hpp>
18#include <boost/thread/locks.hpp>
19#endif
20
21#include <boost/detail/lightweight_mutex.hpp>
22#include <boost/detail/lightweight_test.hpp>
23#include <boost/detail/lightweight_thread.hpp>
24
25#include <cstdio>
26#include <ctime>
27
28//
29
30int const n = 1024 * 1024;
31
32struct X
33{
34 int v_; // version
35
36 unsigned a_;
37 unsigned b_;
38
39 X(): v_( 0 ), a_( 1 ), b_( 1 )
40 {
41 }
42
43 int get() const
44 {
45 return a_ * 7 + b_ * 11;
46 }
47
48 void set()
49 {
50 int tmp = get();
51
52 b_ = a_;
53 a_ = tmp;
54
55 ++v_;
56 }
57};
58
59static boost::shared_ptr<X> ps( new X );
60
61static boost::detail::lightweight_mutex lm;
62
63#if defined( USE_RWLOCK )
64static boost::shared_mutex rw;
65#endif
66
67static int tr = 0;
68
69void reader( int r )
70{
71 int k = 0;
72 unsigned s = 0;
73
74 for( int i = 0; i < n; ++k )
75 {
76#if defined( USE_MUTEX )
77
78 boost::detail::lightweight_mutex::scoped_lock lock( lm );
79
80 s += ps->get();
81
82 BOOST_TEST( ps->v_ >= i );
83 i = ps->v_;
84
85#elif defined( USE_RWLOCK )
86
87 boost::shared_lock<boost::shared_mutex> lock( rw );
88
89 s += ps->get();
90
91 BOOST_TEST( ps->v_ >= i );
92 i = ps->v_;
93
94#else
95
96 boost::shared_ptr<X> p2 = boost::atomic_load( &ps );
97
98 s += p2->get();
99
100 BOOST_TEST( p2->v_ >= i );
101 i = p2->v_;
102
103#endif
104 }
105
106 printf( "Reader %d: %9d iterations (%6.3fx), %u\n", r, k, (double)k / n, s );
107
108 boost::detail::lightweight_mutex::scoped_lock lock( lm );
109 tr += k;
110}
111
112void writer()
113{
114 for( int i = 0; i < n; ++i )
115 {
116#if defined( USE_MUTEX )
117
118 boost::detail::lightweight_mutex::scoped_lock lock( lm );
119
120 BOOST_TEST( ps->v_ == i );
121 ps->set();
122
123#elif defined( USE_RWLOCK )
124
125 boost::unique_lock<boost::shared_mutex> lock( rw );
126
127 BOOST_TEST( ps->v_ == i );
128 ps->set();
129
130#else
131
132 boost::shared_ptr<X> p2( new X( *ps ) );
133
134 BOOST_TEST( p2->v_ == i );
135 p2->set();
136
137 boost::atomic_store( &ps, p2 );
138
139#endif
140 }
141}
142
143#if defined( BOOST_HAS_PTHREADS )
144 char const * thmodel = "POSIX";
145#else
146 char const * thmodel = "Windows";
147#endif
148
149int const mr = 8; // reader threads
150int const mw = 1; // writer thread
151
152#if defined( USE_MUTEX )
153 char const * prim = "mutex";
154#elif defined( USE_RWLOCK )
155 char const * prim = "rwlock";
156#else
157 char const * prim = "atomics";
158#endif
159
160int main()
161{
162 using namespace std; // printf, clock_t, clock
163
164 printf( "Using %s threads: %dR + %dW threads, %d iterations, %s\n\n", thmodel, mr, mw, n, prim );
165
166 clock_t t = clock();
167
92f5a8d4 168 boost::detail::lw_thread_t a[ mr+mw ];
7c673cae
FG
169
170 for( int i = 0; i < mr; ++i )
171 {
172 boost::detail::lw_thread_create( a[ i ], boost::bind( reader, i ) );
173 }
174
175 for( int i = mr; i < mr+mw; ++i )
176 {
177 boost::detail::lw_thread_create( a[ i ], writer );
178 }
179
180 for( int j = 0; j < mr+mw; ++j )
181 {
92f5a8d4 182 boost::detail::lw_thread_join( a[ j ] );
7c673cae
FG
183 }
184
185 t = clock() - t;
186
187 double ts = static_cast<double>( t ) / CLOCKS_PER_SEC;
188 printf( "%.3f seconds, %.3f reads per microsecond.\n", ts, tr / ts / 1e+6 );
189
190 return boost::report_errors();
191}