af3b5f3227
[SVN r83552]
145 lines
3.3 KiB
C++
145 lines
3.3 KiB
C++
// Copyright (C) 2012 Vicente J. Botet Escriba
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#include <iostream>
|
|
#include <boost/thread/mutex.hpp>
|
|
#include <boost/thread/shared_mutex.hpp>
|
|
#include <boost/thread/lock_algorithms.hpp>
|
|
#include <boost/thread/thread_only.hpp>
|
|
#if defined BOOST_THREAD_DONT_USE_CHRONO
|
|
#include <boost/chrono/chrono_io.hpp>
|
|
#endif
|
|
#include <cassert>
|
|
#include <vector>
|
|
|
|
#define EXCLUSIVE 1
|
|
#define SHARED 2
|
|
|
|
#define MODE SHARED
|
|
|
|
class A
|
|
{
|
|
#if MODE == EXCLUSIVE
|
|
typedef boost::mutex mutex_type;
|
|
#elif MODE == SHARED
|
|
typedef boost::shared_mutex mutex_type;
|
|
#else
|
|
#error MODE not set
|
|
#endif
|
|
typedef std::vector<double> C;
|
|
mutable mutex_type mut_;
|
|
C data_;
|
|
public:
|
|
A() : data_(10000000) {}
|
|
A(const A& a);
|
|
A& operator=(const A& a);
|
|
|
|
void compute(const A& x, const A& y);
|
|
};
|
|
|
|
A::A(const A& a)
|
|
{
|
|
#if MODE == EXCLUSIVE
|
|
boost::unique_lock<mutex_type> lk(a.mut_);
|
|
#elif MODE == SHARED
|
|
boost::shared_lock<mutex_type> lk(a.mut_);
|
|
#else
|
|
#error MODE not set
|
|
#endif
|
|
data_ = a.data_;
|
|
}
|
|
|
|
A&
|
|
A::operator=(const A& a)
|
|
{
|
|
if (this != &a)
|
|
{
|
|
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
|
|
#if MODE == EXCLUSIVE
|
|
boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
|
|
#elif MODE == SHARED
|
|
boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
|
|
#else
|
|
#error MODE not set
|
|
#endif
|
|
boost::lock(lk1, lk2);
|
|
data_ = a.data_;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void
|
|
A::compute(const A& x, const A& y)
|
|
{
|
|
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
|
|
#if MODE == EXCLUSIVE
|
|
boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
|
|
boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
|
|
#elif MODE == SHARED
|
|
boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
|
|
boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
|
|
#else
|
|
#error MODE not set
|
|
#endif
|
|
boost::lock(lk1, lk2, lk3);
|
|
assert(data_.size() == x.data_.size());
|
|
assert(data_.size() == y.data_.size());
|
|
for (unsigned i = 0; i < data_.size(); ++i)
|
|
data_[i] = (x.data_[i] + y.data_[i]) / 2;
|
|
}
|
|
|
|
A a1;
|
|
A a2;
|
|
|
|
void test_s()
|
|
{
|
|
A la3 = a1;
|
|
for (int i = 0; i < 150; ++i)
|
|
{
|
|
la3.compute(a1, a2);
|
|
}
|
|
}
|
|
|
|
void test_w()
|
|
{
|
|
A la3 = a1;
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
la3.compute(a1, a2);
|
|
a1 = la3;
|
|
a2 = la3;
|
|
#if defined BOOST_THREAD_DONT_USE_CHRONO
|
|
boost::this_thread::sleep_for(boost::chrono::seconds(1));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
#if defined BOOST_THREAD_DONT_USE_CHRONO
|
|
typedef boost::chrono::high_resolution_clock Clock;
|
|
typedef boost::chrono::duration<double> sec;
|
|
Clock::time_point t0 = Clock::now();
|
|
#endif
|
|
std::vector<boost::thread*> v;
|
|
boost::thread thw(test_w);
|
|
v.push_back(&thw);
|
|
boost::thread thr0(test_w);
|
|
v.push_back(&thr0);
|
|
boost::thread thr1(test_w);
|
|
v.push_back(&thr1);
|
|
boost::thread thr2(test_w);
|
|
v.push_back(&thr2);
|
|
boost::thread thr3(test_w);
|
|
v.push_back(&thr3);
|
|
for (std::size_t i = 0; i < v.size(); ++i)
|
|
v[i]->join();
|
|
#if defined BOOST_THREAD_DONT_USE_CHRONO
|
|
Clock::time_point t1 = Clock::now();
|
|
std::cout << sec(t1-t0) << '\n';
|
|
#endif
|
|
return 0;
|
|
}
|