summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/thread/example/shared_monitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/thread/example/shared_monitor.cpp')
-rw-r--r--src/boost/libs/thread/example/shared_monitor.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/boost/libs/thread/example/shared_monitor.cpp b/src/boost/libs/thread/example/shared_monitor.cpp
new file mode 100644
index 00000000..d1996588
--- /dev/null
+++ b/src/boost/libs/thread/example/shared_monitor.cpp
@@ -0,0 +1,144 @@
+// 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;
+}