]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/smart_ptr/test/sp_atomic_mt2_test.cpp
2 // Copyright (c) 2008 Peter Dimov
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
8 #include <boost/config.hpp>
10 #include <boost/shared_ptr.hpp>
11 #include <boost/bind.hpp>
13 #include <boost/thread/shared_mutex.hpp>
14 #include <boost/thread/locks.hpp>
16 #include <boost/detail/lightweight_mutex.hpp>
17 #include <boost/detail/lightweight_thread.hpp>
28 static void next_value( unsigned & v
)
30 v
= v
% 2? 3 * v
+ 1: v
/ 2;
35 std::vector
<unsigned> v_
;
37 explicit X( std::size_t n
): v_( n
)
39 for( std::size_t i
= 0; i
< n
; ++i
)
47 return std::accumulate( v_
.begin(), v_
.end(), 0 );
52 std::for_each( v_
.begin(), v_
.end(), next_value
);
56 static boost::shared_ptr
<X
> ps
;
58 static boost::detail::lightweight_mutex lm
;
59 static boost::shared_mutex rw
;
68 int read_access( prim_type pt
)
74 boost::detail::lightweight_mutex::scoped_lock
lock( lm
);
80 boost::shared_lock
<boost::shared_mutex
> lock( rw
);
86 boost::shared_ptr
<X
> p2
= boost::atomic_load( &ps
);
92 void write_access( prim_type pt
)
98 boost::detail::lightweight_mutex::scoped_lock
lock( lm
);
105 boost::unique_lock
<boost::shared_mutex
> lock( rw
);
112 boost::shared_ptr
<X
> p1
= boost::atomic_load( &ps
);
116 boost::shared_ptr
<X
> p2( new X( *p1
) );
119 if( boost::atomic_compare_exchange( &ps
, &p1
, p2
) ) break;
126 void worker( int k
, prim_type pt
, int n
, int r
)
130 unsigned s
= 0, nr
= 0, nw
= 0;
132 for( int i
= 0; i
< n
; ++i
)
136 s
+= read_access( pt
);
147 printf( "Worker %2d: %u:%u, %10u\n", k
, nr
, nw
, s
);
150 #if defined( BOOST_HAS_PTHREADS )
151 char const * thmodel
= "POSIX";
153 char const * thmodel
= "Windows";
156 char const * pt_to_string( prim_type pt
)
174 static void handle_pt_option( std::string
const & opt
, prim_type
& pt
, prim_type pt2
)
176 if( opt
== pt_to_string( pt2
) )
182 static void handle_int_option( std::string
const & opt
, std::string
const & prefix
, int & k
, int kmin
, int kmax
)
184 if( opt
.substr( 0, prefix
.size() ) == prefix
)
186 int v
= atoi( opt
.substr( prefix
.size() ).c_str() );
188 if( v
>= kmin
&& v
<= kmax
)
195 int main( int ac
, char const * av
[] )
197 using namespace std
; // printf, clock_t, clock
199 int m
= 4; // threads
200 int n
= 10000; // vector size
201 int k
= 1000000; // iterations
202 int r
= 100; // read/write ratio, r:1
204 prim_type pt
= pt_atomics
;
206 for( int i
= 1; i
< ac
; ++i
)
208 handle_pt_option( av
[i
], pt
, pt_mutex
);
209 handle_pt_option( av
[i
], pt
, pt_rwlock
);
210 handle_pt_option( av
[i
], pt
, pt_atomics
);
212 handle_int_option( av
[i
], "n=", n
, 1, INT_MAX
);
213 handle_int_option( av
[i
], "size=", n
, 1, INT_MAX
);
215 handle_int_option( av
[i
], "k=", k
, 1, INT_MAX
);
216 handle_int_option( av
[i
], "iterations=", k
, 1, INT_MAX
);
218 handle_int_option( av
[i
], "m=", m
, 1, INT_MAX
);
219 handle_int_option( av
[i
], "threads=", m
, 1, INT_MAX
);
221 handle_int_option( av
[i
], "r=", r
, 1, INT_MAX
);
222 handle_int_option( av
[i
], "ratio=", r
, 1, INT_MAX
);
225 printf( "%s: threads=%d size=%d iterations=%d ratio=%d %s\n\n", thmodel
, m
, n
, k
, r
, pt_to_string( pt
) );
227 ps
.reset( new X( n
) );
231 std::vector
<pthread_t
> a( m
);
233 for( int i
= 0; i
< m
; ++i
)
235 boost::detail::lw_thread_create( a
[ i
], boost::bind( worker
, i
, pt
, k
, r
) );
238 for( int j
= 0; j
< m
; ++j
)
240 pthread_join( a
[ j
], 0 );
245 double ts
= static_cast<double>( t
) / CLOCKS_PER_SEC
;
246 printf( "%.3f seconds, %.3f accesses per microsecond.\n", ts
, m
* k
/ ts
/ 1e+6 );