summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/thread/example
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/thread/example
parentInitial commit. (diff)
downloadceph-upstream/16.2.11+ds.tar.xz
ceph-upstream/16.2.11+ds.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/thread/example')
-rw-r--r--src/boost/libs/thread/example/Jamfile.v223
-rw-r--r--src/boost/libs/thread/example/ba_externallly_locked.cpp120
-rw-r--r--src/boost/libs/thread/example/condition.cpp91
-rw-r--r--src/boost/libs/thread/example/default_executor.cpp61
-rw-r--r--src/boost/libs/thread/example/executor.cpp207
-rw-r--r--src/boost/libs/thread/example/fib_task_region.cpp91
-rw-r--r--src/boost/libs/thread/example/future_fallback_to.cpp161
-rw-r--r--src/boost/libs/thread/example/future_then.cpp137
-rw-r--r--src/boost/libs/thread/example/future_unwrap.cpp92
-rw-r--r--src/boost/libs/thread/example/future_when_all.cpp330
-rw-r--r--src/boost/libs/thread/example/generic_executor_ref.cpp163
-rw-r--r--src/boost/libs/thread/example/lambda_future.cpp80
-rw-r--r--src/boost/libs/thread/example/make_future.cpp154
-rw-r--r--src/boost/libs/thread/example/monitor.cpp113
-rw-r--r--src/boost/libs/thread/example/mutex.cpp47
-rw-r--r--src/boost/libs/thread/example/not_interleaved.cpp63
-rw-r--r--src/boost/libs/thread/example/not_interleaved2.cpp61
-rw-r--r--src/boost/libs/thread/example/once.cpp39
-rw-r--r--src/boost/libs/thread/example/parallel_accumulate.cpp102
-rw-r--r--src/boost/libs/thread/example/parallel_quick_sort.cpp110
-rw-r--r--src/boost/libs/thread/example/perf_condition_variable.cpp237
-rw-r--r--src/boost/libs/thread/example/perf_shared_mutex.cpp72
-rw-r--r--src/boost/libs/thread/example/producer_consumer.cpp147
-rw-r--r--src/boost/libs/thread/example/producer_consumer2.cpp150
-rw-r--r--src/boost/libs/thread/example/producer_consumer_bounded.cpp146
-rw-r--r--src/boost/libs/thread/example/recursive_mutex.cpp49
-rw-r--r--src/boost/libs/thread/example/scoped_thread.cpp83
-rw-r--r--src/boost/libs/thread/example/serial_executor.cpp107
-rw-r--r--src/boost/libs/thread/example/serial_executor_cont.cpp113
-rw-r--r--src/boost/libs/thread/example/shared_monitor.cpp144
-rw-r--r--src/boost/libs/thread/example/shared_mutex.cpp746
-rw-r--r--src/boost/libs/thread/example/starvephil.cpp187
-rw-r--r--src/boost/libs/thread/example/std_scoped_thread.cpp112
-rw-r--r--src/boost/libs/thread/example/std_thread_guard.cpp66
-rw-r--r--src/boost/libs/thread/example/strict_lock.cpp40
-rw-r--r--src/boost/libs/thread/example/synchronized_person.cpp282
-rw-r--r--src/boost/libs/thread/example/synchronized_value.cpp147
-rw-r--r--src/boost/libs/thread/example/tennis.cpp137
-rw-r--r--src/boost/libs/thread/example/this_executor.cpp85
-rw-r--r--src/boost/libs/thread/example/thread.cpp37
-rw-r--r--src/boost/libs/thread/example/thread_group.cpp73
-rw-r--r--src/boost/libs/thread/example/thread_guard.cpp58
-rw-r--r--src/boost/libs/thread/example/thread_pool.cpp78
-rw-r--r--src/boost/libs/thread/example/tss.cpp37
-rw-r--r--src/boost/libs/thread/example/user_scheduler.cpp79
-rw-r--r--src/boost/libs/thread/example/with_lock_guard.cpp53
-rw-r--r--src/boost/libs/thread/example/xtime.cpp18
47 files changed, 5728 insertions, 0 deletions
diff --git a/src/boost/libs/thread/example/Jamfile.v2 b/src/boost/libs/thread/example/Jamfile.v2
new file mode 100644
index 000000000..bfc8a59b3
--- /dev/null
+++ b/src/boost/libs/thread/example/Jamfile.v2
@@ -0,0 +1,23 @@
+# Copyright (C) 2001-2003
+# William E. Kempf
+#
+# 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)
+
+project boost/thread/example
+ : requirements <library>../build//boost_thread <threading>multi
+ ;
+
+
+exe monitor : monitor.cpp ;
+exe starvephil : starvephil.cpp ;
+exe tennis : tennis.cpp ;
+exe condition : condition.cpp ;
+exe mutex : mutex.cpp ;
+exe once : once.cpp ;
+exe recursive_mutex : recursive_mutex.cpp ;
+exe thread : thread.cpp ;
+exe thread_group : thread_group.cpp ;
+exe tss : tss.cpp ;
+exe xtime : xtime.cpp ;
+
diff --git a/src/boost/libs/thread/example/ba_externallly_locked.cpp b/src/boost/libs/thread/example/ba_externallly_locked.cpp
new file mode 100644
index 000000000..e93876769
--- /dev/null
+++ b/src/boost/libs/thread/example/ba_externallly_locked.cpp
@@ -0,0 +1,120 @@
+// Copyright (C) 2012 Vicente Botet
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lockable_adapter.hpp>
+#include <boost/thread/externally_locked.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <iostream>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list
+#endif
+
+using namespace boost;
+
+class BankAccount
+{
+ int balance_;
+public:
+ void Deposit(int amount)
+ {
+ balance_ += amount;
+ }
+ void Withdraw(int amount)
+ {
+ balance_ -= amount;
+ }
+ int GetBalance()
+ {
+ return balance_;
+ }
+};
+
+//[AccountManager
+class AccountManager: public basic_lockable_adapter<mutex>
+{
+public:
+ typedef basic_lockable_adapter<mutex> lockable_base_type;
+ AccountManager() :
+ lockable_base_type(), checkingAcct_(*this), savingsAcct_(*this)
+ {
+ }
+ inline void Checking2Savings(int amount);
+ inline void AMoreComplicatedChecking2Savings(int amount);
+private:
+ /*<-*/
+ bool some_condition()
+ {
+ return true;
+ } /*->*/
+ externally_locked<BankAccount, AccountManager > checkingAcct_;
+ externally_locked<BankAccount, AccountManager > savingsAcct_;
+};
+//]
+
+//[Checking2Savings
+void AccountManager::Checking2Savings(int amount)
+{
+ strict_lock<AccountManager> guard(*this);
+ checkingAcct_.get(guard).Withdraw(amount);
+ savingsAcct_.get(guard).Deposit(amount);
+}
+//]
+
+//#if DO_NOT_COMPILE
+////[AMoreComplicatedChecking2Savings_DO_NOT_COMPILE
+//void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
+// unique_lock<AccountManager> guard(*this);
+// if (some_condition()) {
+// guard.lock();
+// }
+// checkingAcct_.get(guard).Withdraw(amount);
+// savingsAcct_.get(guard).Deposit(amount);
+// guard1.unlock();
+//}
+////]
+//#elif DO_NOT_COMPILE_2
+////[AMoreComplicatedChecking2Savings_DO_NOT_COMPILE2
+//void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
+// unique_lock<AccountManager> guard1(*this);
+// if (some_condition()) {
+// guard1.lock();
+// }
+// {
+// strict_lock<AccountManager> guard(guard1);
+// checkingAcct_.get(guard).Withdraw(amount);
+// savingsAcct_.get(guard).Deposit(amount);
+// }
+// guard1.unlock();
+//}
+////]
+//#else
+////[AMoreComplicatedChecking2Savings
+void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
+ unique_lock<AccountManager> guard1(*this);
+ if (some_condition()) {
+ guard1.lock();
+ }
+ {
+ nested_strict_lock<unique_lock<AccountManager> > guard(guard1);
+ checkingAcct_.get(guard).Withdraw(amount);
+ savingsAcct_.get(guard).Deposit(amount);
+ }
+ guard1.unlock();
+}
+////]
+//#endif
+
+int main()
+{
+ AccountManager mgr;
+ mgr.Checking2Savings(100);
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/condition.cpp b/src/boost/libs/thread/example/condition.cpp
new file mode 100644
index 000000000..a747f9e45
--- /dev/null
+++ b/src/boost/libs/thread/example/condition.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <vector>
+#include <boost/utility.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/thread_only.hpp>
+#include "../test/remove_error_code_unused_warning.hpp"
+
+class bounded_buffer : private boost::noncopyable
+{
+public:
+ typedef boost::unique_lock<boost::mutex> lock;
+
+ bounded_buffer(int n) : boost::noncopyable(), begin(0), end(0), buffered(0), circular_buf(n) { }
+
+ void send (int m) {
+ lock lk(monitor);
+ while (buffered == circular_buf.size())
+ buffer_not_full.wait(lk);
+ circular_buf[end] = m;
+ end = (end+1) % circular_buf.size();
+ ++buffered;
+ buffer_not_empty.notify_one();
+ }
+ int receive() {
+ lock lk(monitor);
+ while (buffered == 0)
+ buffer_not_empty.wait(lk);
+ int i = circular_buf[begin];
+ begin = (begin+1) % circular_buf.size();
+ --buffered;
+ buffer_not_full.notify_one();
+ return i;
+ }
+
+private:
+ int begin, end;
+ std::vector<int>::size_type buffered;
+ std::vector<int> circular_buf;
+ boost::condition_variable_any buffer_not_full, buffer_not_empty;
+ boost::mutex monitor;
+};
+
+bounded_buffer buf(2);
+
+boost::mutex io_mutex;
+
+void sender() {
+ int n = 0;
+ while (n < 1000000) {
+ buf.send(n);
+ if(!(n%10000))
+ {
+ boost::unique_lock<boost::mutex> io_lock(io_mutex);
+ std::cout << "sent: " << n << std::endl;
+ }
+ ++n;
+ }
+ buf.send(-1);
+}
+
+void receiver() {
+ int n;
+ do {
+ n = buf.receive();
+ if(!(n%10000))
+ {
+ boost::unique_lock<boost::mutex> io_lock(io_mutex);
+ std::cout << "received: " << n << std::endl;
+ }
+ } while (n != -1); // -1 indicates end of buffer
+ buf.send(-1);
+}
+
+int main(int, char*[])
+{
+ boost::thread thrd1(&sender);
+ boost::thread thrd2(&receiver);
+ boost::thread thrd3(&receiver);
+ boost::thread thrd4(&receiver);
+ thrd1.join();
+ thrd2.join();
+ thrd3.join();
+ thrd4.join();
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/default_executor.cpp b/src/boost/libs/thread/example/default_executor.cpp
new file mode 100644
index 000000000..ccdb38767
--- /dev/null
+++ b/src/boost/libs/thread/example/default_executor.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
+#include <string>
+#include <iostream>
+
+#include <boost/thread/caller_context.hpp>
+
+
+boost::generic_executor_ref default_executor()
+{
+ static boost::basic_thread_pool tp(4);
+ return boost::generic_executor_ref(tp);
+}
+
+void p2()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+
+void p1()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ default_executor().submit(&p2);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(400));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+int main()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+ default_executor().submit(&p1);
+
+ boost::this_thread::sleep_for(boost::chrono::seconds(5));
+
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+ return 1;
+
+}
diff --git a/src/boost/libs/thread/example/executor.cpp b/src/boost/libs/thread/example/executor.cpp
new file mode 100644
index 000000000..82734347f
--- /dev/null
+++ b/src/boost/libs/thread/example/executor.cpp
@@ -0,0 +1,207 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <iostream>
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/loop_executor.hpp>
+#include <boost/thread/executors/serial_executor.hpp>
+#include <boost/thread/executors/inline_executor.hpp>
+#include <boost/thread/executors/thread_executor.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/executor_adaptor.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+#include <cassert>
+
+boost::future<void> p(boost::future<void> f) {
+ assert(f.is_ready());
+ return boost::make_ready_future();
+}
+
+void p1()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ //boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+}
+
+void p2()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ //boost::this_thread::sleep_for(boost::chrono::seconds(10));
+}
+
+int f1()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ return 1;
+}
+int f2(int i)
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(2));
+ return i + 1;
+}
+
+void submit_some(boost::executor& tp)
+{
+ for (int i = 0; i < 3; ++i) {
+ tp.submit(&p2);
+ }
+ for (int i = 0; i < 3; ++i) {
+ tp.submit(&p1);
+ }
+
+}
+
+
+void at_th_entry(boost::basic_thread_pool& )
+{
+
+}
+
+int test_executor_adaptor()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ try
+ {
+ {
+ boost::executor_adaptor < boost::basic_thread_pool > ea(4);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ submit_some( ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
+ {
+ boost::future<int> t1 = boost::async(ea, &f1);
+ boost::future<int> t2 = boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ submit_some(ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea3(1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::future<int> t1 = boost::async(ea3, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::future<int> t2 = boost::async(ea3, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ //boost::future<int> t2 = boost::async(ea3, f2, 1); // todo this doesn't compiles yet on C++11
+ //boost::future<int> t2 = boost::async(ea3, boost::bind(f2, 1)); // todo this doesn't compiles yet on C++98
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ submit_some(ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::executor_adaptor < boost::loop_executor > ea2;
+ submit_some( ea2);
+ ea2.underlying_executor().run_queued_closures();
+ }
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::executor_adaptor < boost::basic_thread_pool > ea1(4);
+ boost::executor_adaptor < boost::serial_executor > ea2(ea1);
+ submit_some(ea2);
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::executor_adaptor < boost::inline_executor > ea1;
+ submit_some(ea1);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::executor_adaptor < boost::thread_executor > ea1;
+ submit_some(ea1);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
+ {
+ boost::basic_thread_pool ea(4, at_th_entry);
+ boost::future<int> t1 = boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::async(&f1);
+ }
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
+
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea(1);
+ boost::async(ea,&f1);
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ }
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ return 0;
+}
+
+
+int main()
+{
+ return test_executor_adaptor();
+
+#if 0 && defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
+ && defined BOOST_THREAD_PROVIDES_EXECUTORS \
+ && ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+ boost::basic_thread_pool executor;
+ // compiles
+ boost::make_ready_future().then(&p);
+
+ // ??
+ boost::make_ready_future().then(executor, &p);
+
+ // doesn't compile
+ boost::make_ready_future().then(executor, &p);
+#endif
+}
diff --git a/src/boost/libs/thread/example/fib_task_region.cpp b/src/boost/libs/thread/example/fib_task_region.cpp
new file mode 100644
index 000000000..1540dc294
--- /dev/null
+++ b/src/boost/libs/thread/example/fib_task_region.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2012 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread/experimental/task_region.hpp>
+#include <iostream>
+
+#if ! defined BOOST_NO_CXX11_RANGE_BASED_FOR && ! defined BOOST_NO_CXX11_LAMBDAS
+
+int fib_task_region(int n)
+{
+ using boost::experimental::parallel::task_region;
+ using boost::experimental::parallel::task_region_handle;
+
+ if (n == 0) return 0;
+ if (n == 1) return 1;
+
+ int n1;
+ int n2;
+
+ task_region([&](task_region_handle& trh)
+ {
+ trh.run([&]
+ {
+ n1 = fib_task_region(n - 1);
+ });
+
+ n2 = fib_task_region(n - 2);
+ });
+
+ return n1 + n2;
+}
+
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+template <class Ex>
+int fib_task_region_gen( Ex& ex, int n)
+{
+ using boost::experimental::parallel::task_region;
+ using boost::experimental::parallel::task_region_handle_gen;
+
+ if (n == 0) return 0;
+ if (n == 1) return 1;
+
+ int n1;
+ int n2;
+
+ task_region(ex, [&](task_region_handle_gen<Ex>& trh)
+ {
+ trh.run([&]
+ {
+ n1 = fib_task_region(n - 1);
+ });
+
+ n2 = fib_task_region(n - 2);
+ });
+
+ return n1 + n2;
+}
+#endif
+
+int main()
+{
+ for (int i = 0; i<10; ++i) {
+ std::cout << fib_task_region(i) << " ";
+ }
+ std::cout << std::endl;
+
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ boost::basic_thread_pool tp;
+ for (int i = 0; i<10; ++i) {
+ std::cout << fib_task_region_gen(tp,i) << " ";
+ }
+ std::cout << std::endl;
+#endif
+ return 0;
+}
+#else
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/future_fallback_to.cpp b/src/boost/libs/thread/example/future_fallback_to.cpp
new file mode 100644
index 000000000..7e928eec5
--- /dev/null
+++ b/src/boost/libs/thread/example/future_fallback_to.cpp
@@ -0,0 +1,161 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <exception>
+#include <string>
+#include <iostream>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1_ex()
+{
+ BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
+ throw std::logic_error("kk");
+}
+
+int p1()
+{
+ BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
+ return 1;;
+}
+
+int main()
+{
+ const int number_of_tests = 200;
+ BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
+
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ f1.wait();
+ BOOST_ASSERT(f1.get()==1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(&p1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f2 = f1.fallback_to(-1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ f2.wait();
+ //std::cout << __FILE__ << "["<< __LINE__<<"] " << std::endl;
+ BOOST_ASSERT(f2.get()==1);
+ //std::cout << __FILE__ << "["<< __LINE__<<"] " << std::endl;
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1_ex);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ f1.wait();
+ BOOST_ASSERT(f1.get_or(-1)==-1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1_ex);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f2 = f1.fallback_to(-1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ f2.wait();
+ //std::cout << __FILE__ << "["<< __LINE__<<"] " << std::endl;
+ BOOST_ASSERT(f2.get()==-1);
+ //std::cout << __FILE__ << "["<< __LINE__<<"] " << std::endl;
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << "["<< __LINE__<<"] " << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/future_then.cpp b/src/boost/libs/thread/example/future_then.cpp
new file mode 100644
index 000000000..17ef36714
--- /dev/null
+++ b/src/boost/libs/thread/example/future_then.cpp
@@ -0,0 +1,137 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
+ return 123;
+}
+
+int p2(boost::future<int> f)
+{
+ BOOST_THREAD_LOG << "P2<" << BOOST_THREAD_END_LOG;
+ try
+ {
+ return 2 * f.get();
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+int p2s(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG << "<P2S" << BOOST_THREAD_END_LOG;
+ try
+ {
+ return 2 * f.get();
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ BOOST_THREAD_LOG << "P2S>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+
+int main()
+{
+ const int number_of_tests = 100;
+ BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(&p1);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f2 = f1.then(&p2);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ (void)f2.get();
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ {
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::shared_future<int> f1 = boost::async(&p1).share();
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ boost::future<int> f2 = f1.then(&p2s);
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ (void)f2.get();
+ BOOST_THREAD_LOG << "" << BOOST_THREAD_END_LOG;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/future_unwrap.cpp b/src/boost/libs/thread/example/future_unwrap.cpp
new file mode 100644
index 000000000..aeed9db9a
--- /dev/null
+++ b/src/boost/libs/thread/example/future_unwrap.cpp
@@ -0,0 +1,92 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
+ return 123;
+}
+
+boost::future<int> p2()
+{
+ BOOST_THREAD_LOG << "<P2" << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
+ return boost::move(f1);
+}
+
+int main()
+{
+ const int number_of_tests = 100;
+ BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ boost::future<int> inner_future = boost::async(boost::launch::async, &p2).unwrap();
+ inner_future.wait();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
+#endif
+ {
+ boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
+ boost::future<int> inner_future = outer_future.unwrap();
+ inner_future.wait();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
+ {
+ boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
+ boost::future<int> inner_future = outer_future.unwrap();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/future_when_all.cpp b/src/boost/libs/thread/example/future_when_all.cpp
new file mode 100644
index 000000000..52a40e9c0
--- /dev/null
+++ b/src/boost/libs/thread/example/future_when_all.cpp
@@ -0,0 +1,330 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/detail/log.hpp>
+#include <string>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG
+ << "P1" << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ return 123;
+}
+int p1b()
+{
+ BOOST_THREAD_LOG
+ << "P1b" << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ return 321;
+}
+
+int p2(boost::future<int> f)
+{
+ BOOST_THREAD_LOG
+ << " P2 " << BOOST_THREAD_END_LOG;
+ try
+ {
+ return 2 * f.get();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ BOOST_THREAD_LOG
+ << "P2>" << BOOST_THREAD_END_LOG;
+ return 0;
+
+}
+int p2s(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG
+ << "<P2" << BOOST_THREAD_END_LOG;
+ try
+ {
+ return 2 * f.get();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_ASSERT(false);
+ }
+ BOOST_THREAD_LOG
+ << "P2>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG
+ << "<MAIN" << BOOST_THREAD_END_LOG;
+ {
+ try
+ {
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<boost::csbl::tuple<> > all0 = boost::when_all();
+ BOOST_THREAD_LOG
+ << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#endif
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::make_ready_future(1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ //(void) all.wait();
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<std::string> f2 = boost::make_ready_future(std::string("nnnnnnn"));;
+ boost::future<boost::csbl::tuple<boost::future<int>, boost::future<std::string> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ //(void) all.wait();
+ boost::csbl::tuple<boost::future<int>, boost::future<std::string> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::csbl::vector<boost::future<int> > v;
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ v.push_back(boost::async(boost::launch::async, &p1));
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ v.push_back(boost::async(boost::launch::async, &p1b));
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << res[0].get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << res[1].get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ {
+ try
+ {
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<boost::csbl::tuple<> > all0 = boost::when_any();
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#endif
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::make_ready_future(1);
+ boost::future<int> f2 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<std::string> f1 = boost::make_ready_future(std::string("aaaa"));
+ boost::future<int> f2 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<std::string>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<std::string>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f2 = boost::make_ready_future(1);
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::async, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p1b);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << boost::csbl::get<0>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << boost::csbl::get<1>(res).get() <<" " << BOOST_THREAD_END_LOG;
+ }
+#endif
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::csbl::vector<boost::future<int> > v;
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ v.push_back(boost::async(boost::launch::async, &p1));
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ v.push_back(boost::async(boost::launch::async, &p1b));
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_THREAD_LOG
+ << res[0].get() <<" " << BOOST_THREAD_END_LOG;
+ BOOST_THREAD_LOG
+ << res[1].get() <<" " << BOOST_THREAD_END_LOG;
+ }
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ BOOST_THREAD_LOG
+ << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+#else
+#include <boost/thread/csbl/vector.hpp>
+using namespace boost;
+
+void f( boost::csbl::vector<future<int> > &//vec
+ , BOOST_THREAD_RV_REF(future<int>) //f
+ ) {
+}
+int main()
+{
+ boost::csbl::vector<future<int> > vec;
+ f(vec, make_ready_future(0));
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/generic_executor_ref.cpp b/src/boost/libs/thread/example/generic_executor_ref.cpp
new file mode 100644
index 000000000..9e61d5dc7
--- /dev/null
+++ b/src/boost/libs/thread/example/generic_executor_ref.cpp
@@ -0,0 +1,163 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/loop_executor.hpp>
+#include <boost/thread/executors/serial_executor.hpp>
+#include <boost/thread/executors/inline_executor.hpp>
+#include <boost/thread/executors/thread_executor.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/executor_adaptor.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+
+void p1()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ //boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+}
+
+void p2()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ //boost::this_thread::sleep_for(boost::chrono::seconds(10));
+}
+
+int f1()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ return 1;
+}
+int f2(int i)
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(2));
+ return i + 1;
+}
+
+void submit_some(boost::generic_executor_ref tp)
+{
+ for (int i = 0; i < 3; ++i) {
+ tp.submit(&p2);
+ }
+ for (int i = 0; i < 3; ++i) {
+ tp.submit(&p1);
+ }
+
+}
+
+void at_th_entry(boost::basic_thread_pool& )
+{
+
+}
+
+
+
+int test_generic_executor_ref()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ try
+ {
+ {
+ boost::basic_thread_pool ea(4);
+ submit_some( ea);
+ {
+ boost::future<int> t1 = boost::async(ea, &f1);
+ boost::future<int> t2 = boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ }
+ submit_some(ea);
+ {
+ boost::basic_thread_pool ea3(1);
+ boost::future<int> t1 = boost::async(ea3, &f1);
+ boost::future<int> t2 = boost::async(ea3, &f1);
+ //boost::future<int> t2 = boost::async(ea3, f2, 1); // todo this doesn't compiles yet on C++11
+ //boost::future<int> t2 = boost::async(ea3, boost::bind(f2, 1)); // todo this doesn't compiles yet on C++98
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ }
+ submit_some(ea);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::loop_executor ea2;
+ submit_some( ea2);
+ ea2.run_queued_closures();
+ }
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea1(4);
+ boost::serial_executor ea2(ea1);
+ submit_some(ea2);
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::inline_executor ea1;
+ submit_some(ea1);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ //boost::thread_executor ea1;
+ //submit_some(ea1);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea(4, at_th_entry);
+ boost::future<int> t1 = boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea(4, at_th_entry);
+ boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ }
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ return 0;
+}
+
+
+int main()
+{
+ return test_generic_executor_ref();
+
+
+}
diff --git a/src/boost/libs/thread/example/lambda_future.cpp b/src/boost/libs/thread/example/lambda_future.cpp
new file mode 100644
index 000000000..a5fec8a1b
--- /dev/null
+++ b/src/boost/libs/thread/example/lambda_future.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
+ && ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1800) // works since msvc-12.0
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int main()
+{
+ const int number_of_tests = 100;
+ BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
+
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, []() {return 123;});
+ int result = f1.get();
+ BOOST_THREAD_LOG << "f1 " << result << BOOST_THREAD_END_LOG;
+ }
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, []() {return 123;});
+ boost::future<int> f2 = f1.then([](boost::future<int> f) {return 2*f.get(); });
+ int result = f2.get();
+ BOOST_THREAD_LOG << "f2 " << result << BOOST_THREAD_END_LOG;
+ }
+#if ! defined BOOST_NO_CXX14_GENERIC_LAMBDAS
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, []() {return 123;});
+ boost::future<int> f2 = f1.then([](auto f) {return 2*f.get(); });
+ int result = f2.get();
+ BOOST_THREAD_LOG << "f2 " << result << BOOST_THREAD_END_LOG;
+ }
+#endif
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERRORRRRR exception thrown" << std::endl;
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+#else
+
+//#warning "This test is not supported in this configuration, either because Bosst.Thread has been configured to don't support continuations, the compiler doesn't provides lambdas or because they are buggy as for MSV versions < msvc-12.0"
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/make_future.cpp b/src/boost/libs/thread/example/make_future.cpp
new file mode 100644
index 000000000..76207d7ad
--- /dev/null
+++ b/src/boost/libs/thread/example/make_future.cpp
@@ -0,0 +1,154 @@
+// Copyright (C) 2012 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <iostream>
+
+namespace boost
+{
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(v);
+ }
+}
+
+int p1() { return 5; }
+int& p1r() { static int i=0; return i; }
+
+void p() { }
+
+#if defined BOOST_THREAD_USES_MOVE
+boost::future<void> void_compute()
+{
+ return BOOST_THREAD_MAKE_RV_REF(boost::make_ready_future());
+}
+#endif
+
+boost::future<int> compute(int x)
+{
+ if (x == 0) return boost::make_ready_future(0);
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ if (x < 0) return boost::make_exceptional_future<int>(std::logic_error("Error"));
+#else
+ if (x < 0) return boost::make_exceptional(std::logic_error("Error"));
+#endif
+ //boost::future<int> f1 = boost::async([]() { return x+1; });
+ boost::future<int> f1 = boost::async(p1);
+ return boost::move(f1);
+}
+
+boost::future<int&> compute_ref(int x)
+{
+ static int i = 0;
+ //if (x == 0) return boost::make_ready_future<int&>(i); //This must not compile as the type is deduced as boost::future<int>
+ if (x == 0) return boost::make_ready_no_decay_future<int&>(i);
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ if (x < 0) return boost::make_exceptional_future<int&>(std::logic_error("Error"));
+#else
+ if (x < 0) return boost::make_exceptional(std::logic_error("Error"));
+#endif
+ boost::future<int&> f1 = boost::async(p1r);
+ return boost::move(f1);
+}
+
+boost::shared_future<int> shared_compute(int x)
+{
+ if (x == 0) return boost::make_ready_future(0).share();
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ if (x < 0) return boost::make_exceptional_future<int>(std::logic_error("Error")).share();
+#else
+ if (x < 0) return boost::make_exceptional(std::logic_error("Error"));
+#endif
+ //boost::future<int> f1 = boost::async([]() { return x+1; });
+ boost::shared_future<int> f1 = boost::async(&p1).share();
+ return f1;
+}
+
+
+int main()
+{
+ const int number_of_tests = 100;
+ for (int i=0; i< number_of_tests; i++)
+ try
+ {
+// {
+// std::cout << __FILE__ << " "<<__LINE__ << std::endl;
+// boost::future<int> f = boost::async(boost::launch::async, p1);
+// std::cout << i << " "<<f.get() << std::endl;
+// }
+#if defined BOOST_THREAD_USES_MOVE
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<void> f = void_compute();
+ f.get();
+ }
+#endif
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int> f = compute(-1);
+ f.wait();
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int> f = compute(0);
+ std::cout << f.get() << std::endl;
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int&> f = compute_ref(0);
+ std::cout << f.get() << std::endl;
+ }
+#if __cplusplus > 201103L
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ int i = 0;
+ boost::future<int&> f = boost::make_ready_future(std::ref(i));
+ std::cout << f.get() << std::endl;
+ }
+#endif
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ int i = 0;
+ boost::future<int&> f = boost::make_ready_future(boost::ref(i));
+ std::cout << f.get() << std::endl;
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ const int i = 0;
+ boost::future<int const&> f = boost::make_ready_future(boost::cref(i));
+ std::cout << f.get() << std::endl;
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int> f = compute(2);
+ std::cout << f.get() << std::endl;
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::shared_future<int> f = shared_compute(0);
+ std::cout << f.get() << std::endl;
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERRORRRRR "<<ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << "ERRORRRRR "<<"ERRORRRRR exception thrown" << std::endl;
+ return 2;
+ }
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/monitor.cpp b/src/boost/libs/thread/example/monitor.cpp
new file mode 100644
index 000000000..5c9a74210
--- /dev/null
+++ b/src/boost/libs/thread/example/monitor.cpp
@@ -0,0 +1,113 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <vector>
+#include <iostream>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread_only.hpp>
+
+namespace {
+const int ITERS = 100;
+boost::mutex io_mutex;
+} // namespace
+
+template <typename M>
+class buffer_t
+{
+public:
+ typedef boost::unique_lock<M> scoped_lock;
+
+ buffer_t(int n)
+ : p(0), c(0), full(0), buf(n)
+ {
+ }
+
+ void send(int m)
+ {
+ scoped_lock lk(mutex);
+ while (full == buf.size())
+ cond.wait(lk);
+ buf[p] = m;
+ p = (p+1) % buf.size();
+ ++full;
+ cond.notify_one();
+ }
+ int receive()
+ {
+ scoped_lock lk(mutex);
+ while (full == 0)
+ cond.wait(lk);
+ int i = buf[c];
+ c = (c+1) % buf.size();
+ --full;
+ cond.notify_one();
+ return i;
+ }
+
+ static buffer_t& get_buffer()
+ {
+ static buffer_t buf(2);
+ return buf;
+ }
+
+ static void do_sender_thread()
+ {
+ for (int n = 0; n < ITERS; ++n)
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(io_mutex);
+ std::cout << "sending: " << n << std::endl;
+ }
+ get_buffer().send(n);
+ }
+ }
+
+ static void do_receiver_thread()
+ {
+ for (int x=0; x < (ITERS/2); ++x)
+ {
+ int n = get_buffer().receive();
+ {
+ boost::unique_lock<boost::mutex> lock(io_mutex);
+ std::cout << "received: " << n << std::endl;
+ }
+ }
+ }
+
+private:
+ M mutex;
+ boost::condition_variable_any cond;
+ unsigned int p, c, full;
+ std::vector<int> buf;
+};
+
+template <typename M>
+void do_test(M* dummy=0)
+{
+ (void)dummy;
+ typedef buffer_t<M> buffer_type;
+ buffer_type::get_buffer();
+ boost::thread thrd1(&buffer_type::do_receiver_thread);
+ boost::thread thrd2(&buffer_type::do_receiver_thread);
+ boost::thread thrd3(&buffer_type::do_sender_thread);
+ thrd1.join();
+ thrd2.join();
+ thrd3.join();
+}
+
+void test_buffer()
+{
+ do_test<boost::mutex>();
+ do_test<boost::recursive_mutex>();
+}
+
+int main()
+{
+ test_buffer();
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/mutex.cpp b/src/boost/libs/thread/example/mutex.cpp
new file mode 100644
index 000000000..9e4762083
--- /dev/null
+++ b/src/boost/libs/thread/example/mutex.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+boost::mutex io_mutex; // The iostreams are not guaranteed to be thread-safe!
+
+class counter
+{
+public:
+ counter() : count(0) { }
+
+ int increment() {
+ boost::unique_lock<boost::mutex> scoped_lock(mutex);
+ return ++count;
+ }
+
+private:
+ boost::mutex mutex;
+ int count;
+};
+
+counter c;
+
+void change_count()
+{
+ int i = c.increment();
+ boost::unique_lock<boost::mutex> scoped_lock(io_mutex);
+ std::cout << "count == " << i << std::endl;
+}
+
+int main(int, char*[])
+{
+ const int num_threads = 4;
+ boost::thread_group thrds;
+ for (int i=0; i < num_threads; ++i)
+ thrds.create_thread(&change_count);
+
+ thrds.join_all();
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/not_interleaved.cpp b/src/boost/libs/thread/example/not_interleaved.cpp
new file mode 100644
index 000000000..ad90fd1f5
--- /dev/null
+++ b/src/boost/libs/thread/example/not_interleaved.cpp
@@ -0,0 +1,63 @@
+// (C) Copyright 2012 Howard Hinnant
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+// adapted from the example given by Howard Hinnant in
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#include <boost/thread/externally_locked_stream.hpp>
+
+void use_cerr(boost::externally_locked_stream<std::ostream> &mcerr)
+{
+ using namespace boost;
+ chrono::steady_clock::time_point tf = chrono::steady_clock::now() + chrono::seconds(10);
+ while (chrono::steady_clock::now() < tf)
+ {
+ mcerr << "logging data to cerr\n";
+ this_thread::sleep_for(chrono::milliseconds(500));
+ }
+}
+
+void use_cout(boost::externally_locked_stream<std::ostream> &mcout)
+{
+ using namespace boost;
+ chrono::steady_clock::time_point tf = chrono::steady_clock::now() + chrono::seconds(5);
+ while (chrono::steady_clock::now() < tf)
+ {
+ mcout << "logging data to cout\n";
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+}
+
+int main()
+{
+ using namespace boost;
+
+ recursive_mutex terminal_mutex;
+
+ externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex);
+ externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
+ externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
+
+ scoped_thread<> t1(boost::thread(use_cerr, boost::ref(mcerr)));
+ scoped_thread<> t2(boost::thread(use_cout, boost::ref(mcout)));
+ this_thread::sleep_for(chrono::seconds(2));
+ std::string nm;
+ {
+ strict_lock<recursive_mutex> lk(terminal_mutex);
+ std::ostream & gcout = mcout.get(lk);
+ //std::istream & gcin = mcin.get(lk);
+ gcout << "Enter name: ";
+ //gcin >> nm;
+ }
+ t1.join();
+ t2.join();
+ mcout << nm << '\n';
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/not_interleaved2.cpp b/src/boost/libs/thread/example/not_interleaved2.cpp
new file mode 100644
index 000000000..e3c4cddc3
--- /dev/null
+++ b/src/boost/libs/thread/example/not_interleaved2.cpp
@@ -0,0 +1,61 @@
+// (C) Copyright 2012 Howard Hinnant
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+// adapted from the example given by Howard Hinnant in
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#include <boost/thread/ostream_buffer.hpp>
+
+void use_cerr()
+{
+ using namespace boost;
+ chrono::steady_clock::time_point tf = chrono::steady_clock::now() + chrono::seconds(5);
+ int i = 0;
+ while (chrono::steady_clock::now() < tf)
+ {
+ ostream_buffer<std::ostream> mcerr(std::cerr);
+ mcerr.stream() << "logging data to cerr " << i++ << "\n";
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+}
+
+void use_cout()
+{
+ using namespace boost;
+ chrono::steady_clock::time_point tf = chrono::steady_clock::now() + chrono::seconds(5);
+ int i = 0;
+ while (chrono::steady_clock::now() < tf)
+ {
+ ostream_buffer<std::ostream> mcout(std::cout);
+ mcout.stream() << "logging data to cout " << i++ << "\n";
+ this_thread::sleep_for(chrono::milliseconds(500));
+ }
+}
+
+int main()
+{
+ using namespace boost;
+
+ scoped_thread<> t1(&use_cerr);
+ scoped_thread<> t2(&use_cout);
+ this_thread::sleep_for(chrono::seconds(2));
+ std::string nm = "he, he\n";
+ {
+ ostream_buffer<std::ostream> mcout(std::cout);
+ mcout.stream() << "Enter name: \n";
+ }
+ t1.join();
+ t2.join();
+ {
+ ostream_buffer<std::ostream> mcout(std::cout);
+ mcout.stream() << nm;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/once.cpp b/src/boost/libs/thread/example/once.cpp
new file mode 100644
index 000000000..c063a9ce4
--- /dev/null
+++ b/src/boost/libs/thread/example/once.cpp
@@ -0,0 +1,39 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+#define BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/once.hpp>
+#include <cassert>
+
+int value=0;
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+static boost::once_flag once;
+//static boost::once_flag once2 = BOOST_ONCE_INIT;
+#else
+static boost::once_flag once = BOOST_ONCE_INIT;
+//static boost::once_flag once2 = once;
+#endif
+
+void init()
+{
+ ++value;
+}
+
+void thread_proc()
+{
+ boost::call_once(&init, once);
+}
+
+int main()
+{
+ boost::thread_group threads;
+ for (int i=0; i<5; ++i)
+ threads.create_thread(&thread_proc);
+ threads.join_all();
+ assert(value == 1);
+}
diff --git a/src/boost/libs/thread/example/parallel_accumulate.cpp b/src/boost/libs/thread/example/parallel_accumulate.cpp
new file mode 100644
index 000000000..acd72017e
--- /dev/null
+++ b/src/boost/libs/thread/example/parallel_accumulate.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// 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 <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/future.hpp>
+
+#include <numeric>
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <vector>
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+template<typename Iterator,typename T>
+struct accumulate_block
+{
+ //typedef T result_type;
+ T operator()(Iterator first,Iterator last)
+ {
+ return std::accumulate(first,last,T());
+ }
+};
+
+template<typename Iterator,typename T>
+T parallel_accumulate(Iterator first,Iterator last,T init)
+{
+ unsigned long const length=static_cast<unsigned long>(std::distance(first,last));
+
+ if(!length)
+ return init;
+
+ unsigned long const block_size=25;
+ unsigned long const num_blocks=(length+block_size-1)/block_size;
+
+ boost::csbl::vector<boost::future<T> > futures(num_blocks-1);
+ boost::basic_thread_pool pool;
+
+ Iterator block_start=first;
+ for(unsigned long i=0;i<(num_blocks-1);++i)
+ {
+ Iterator block_end=block_start;
+ std::advance(block_end,block_size);
+ futures[i]=boost::async(pool, accumulate_block<Iterator,T>(), block_start, block_end);
+ block_start=block_end;
+ }
+ T last_result=accumulate_block<Iterator,T>()(block_start,last);
+ T result=init;
+ for(unsigned long i=0;i<(num_blocks-1);++i)
+ {
+ result+=futures[i].get();
+ }
+ result += last_result;
+ return result;
+}
+
+
+int main()
+{
+ try
+ {
+ const int s = 1001;
+ std::vector<int> vec;
+ vec.reserve(s);
+ for (int i=0; i<s;++i)
+ vec.push_back(1);
+ int r = parallel_accumulate(vec.begin(), vec.end(),0);
+ std::cout << r << std::endl;
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ return 0;
+}
+
+#else
+///#warning "This compiler doesn't supports variadics"
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/parallel_quick_sort.cpp b/src/boost/libs/thread/example/parallel_quick_sort.cpp
new file mode 100644
index 000000000..c8dc46fae
--- /dev/null
+++ b/src/boost/libs/thread/example/parallel_quick_sort.cpp
@@ -0,0 +1,110 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/future.hpp>
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+#include <numeric>
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <list>
+
+template<typename T>
+struct sorter
+{
+ boost::basic_thread_pool pool;
+ typedef std::list<T> return_type;
+
+ std::list<T> do_sort(std::list<T> chunk_data)
+ {
+ if(chunk_data.empty())
+ {
+ return chunk_data;
+ }
+
+ std::list<T> result;
+ result.splice(result.begin(),chunk_data, chunk_data.begin());
+ T const& partition_val=*result.begin();
+
+ typename std::list<T>::iterator divide_point=
+ std::partition(chunk_data.begin(), chunk_data.end(), [&](T const& val){return val<partition_val;});
+
+ std::list<T> new_lower_chunk;
+ new_lower_chunk.splice(new_lower_chunk.end(), chunk_data, chunk_data.begin(), divide_point);
+
+ boost::future<std::list<T> > new_lower = boost::async(pool, &sorter::do_sort, this, std::move(new_lower_chunk));
+ //boost::future<std::list<T> > new_lower = boost::async<return_type>(pool, &sorter::do_sort, this, std::move(new_lower_chunk));
+
+ std::list<T> new_higher(do_sort(chunk_data));
+
+ result.splice(result.end(),new_higher);
+ while(!new_lower.is_ready())
+ {
+ pool.schedule_one_or_yield();
+ }
+
+ result.splice(result.begin(),new_lower.get());
+ return result;
+ }
+};
+
+
+template<typename T>
+std::list<T> parallel_quick_sort(std::list<T>& input)
+{
+ if(input.empty())
+ {
+ return input;
+ }
+ sorter<T> s;
+
+ return s.do_sort(input);
+}
+
+
+int main()
+{
+ try
+ {
+ const int s = 101;
+ std::list<int> lst;
+ for (int i=0; i<s;++i)
+ lst.push_back(100-i);
+ std::list<int> r = parallel_quick_sort(lst);
+ for (std::list<int>::const_iterator it=r.begin(); it != r.end(); ++it)
+ std::cout << *it << std::endl;
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ return 0;
+}
+#else
+//#warning "This compiler doesn't supports variadics and move semantics"
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/example/perf_condition_variable.cpp b/src/boost/libs/thread/example/perf_condition_variable.cpp
new file mode 100644
index 000000000..058386125
--- /dev/null
+++ b/src/boost/libs/thread/example/perf_condition_variable.cpp
@@ -0,0 +1,237 @@
+// (C) Copyright 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)
+//
+// This performance test is based on the performance test provided by maxim.yegorushkin
+// at https://svn.boost.org/trac/boost/ticket/7422
+
+#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/chrono/stopwatches/simple_stopwatch.hpp>
+
+#include <condition_variable>
+#include <future>
+#include <limits>
+#include <cstdio>
+#include <thread>
+#include <mutex>
+#include <vector>
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+// class Stopwatch
+// {
+// public:
+// typedef long long rep;
+//
+// static rep now()
+// {
+// timespec ts;
+// if (clock_gettime(CLOCK_MONOTONIC, &ts)) abort();
+// return ts.tv_sec * rep(1000000000) + ts.tv_nsec;
+// }
+//
+// Stopwatch() :
+// start_(now())
+// {
+// }
+//
+// rep elapsed() const
+// {
+// return now() - start_;
+// }
+//
+// private:
+// rep start_;
+// };
+
+ typedef boost::chrono::simple_stopwatch<> Stopwatch;
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct BoostTypes
+ {
+ typedef boost::condition_variable condition_variable;
+ typedef boost::mutex mutex;
+ typedef boost::mutex::scoped_lock scoped_lock;
+ };
+
+ struct StdTypes
+ {
+ typedef std::condition_variable condition_variable;
+ typedef std::mutex mutex;
+ typedef std::unique_lock<std::mutex> scoped_lock;
+ };
+
+ template <class Types>
+ struct SharedData: Types
+ {
+ unsigned const iterations;
+ unsigned counter;
+ unsigned semaphore;
+ typename Types::condition_variable cnd;
+ typename Types::mutex mtx;
+ Stopwatch::rep producer_time;
+
+ SharedData(unsigned iterations, unsigned consumers) :
+ iterations(iterations), counter(), semaphore(consumers) // Initialize to the number of consumers. (*)
+ , producer_time()
+ {
+ }
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template <class S>
+ void producer_thread(S* shared_data)
+ {
+ Stopwatch sw;
+
+ unsigned const consumers = shared_data->semaphore; // (*)
+ for (unsigned i = shared_data->iterations; i--;)
+ {
+ {
+ typename S::scoped_lock lock(shared_data->mtx);
+ // Wait till all consumers signal.
+ while (consumers != shared_data->semaphore)
+ {
+ shared_data->cnd.wait(lock);
+ }
+ shared_data->semaphore = 0;
+ // Signal consumers.
+ ++shared_data->counter;
+ }
+ shared_data->cnd.notify_all();
+ }
+
+ shared_data->producer_time = sw.elapsed().count();
+ }
+
+ template <class S>
+ void consumer_thread(S* shared_data)
+ {
+ unsigned counter = 0;
+ while (counter != shared_data->iterations)
+ {
+ {
+ typename S::scoped_lock lock(shared_data->mtx);
+ // Wait till the producer signals.
+ while (counter == shared_data->counter)
+ {
+ shared_data->cnd.wait(lock);
+ }
+ counter = shared_data->counter;
+ // Signal the producer.
+ ++shared_data->semaphore;
+ }
+ shared_data->cnd.notify_all();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template <class Types>
+ Stopwatch::rep benchmark_ping_pong(unsigned consumer_count)
+ {
+ typedef SharedData<Types> S;
+
+ auto best_producer_time = std::numeric_limits<Stopwatch::rep>::max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+
+ std::vector<std::thread> consumers
+ { consumer_count };
+
+ // Run the benchmark 10 times and report the best time.
+ for (int times = 10; times--;)
+ {
+ S shared_data
+ { 100000, consumer_count };
+
+ // Start the consumers.
+ for (unsigned i = 0; i < consumer_count; ++i)
+ consumers[i] = std::thread
+ { consumer_thread<S> , &shared_data };
+ // Start the producer and wait till it finishes.
+ std::thread
+ { producer_thread<S> , &shared_data }.join();
+ // Wait till consumers finish.
+ for (unsigned i = 0; i < consumer_count; ++i)
+ consumers[i].join();
+
+ best_producer_time = std::min BOOST_PREVENT_MACRO_SUBSTITUTION (best_producer_time, shared_data.producer_time);
+
+ }
+
+ return best_producer_time;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+// sudo chrt -f 99 /usr/bin/time -f "\n***\ntime: %E\ncontext switches: %c\nwaits: %w" /home/max/otsquant/build/Linux-x86_64-64.g++-release/test/test
+
+/*
+
+ Producer-consumer ping-pong tests. It aims to benchmark condition variables with and without
+ thread cancellation support by comparing the time it took to complete the benchmark.
+
+ Condition variable with thread cancellation support is boost::condition_variable from
+ boost-1.51. Without - std::condition_variable that comes with gcc-4.7.2.
+
+ One producer, one to CONSUMER_MAX consumers. The benchmark calls
+ condition_variable::notify_all() without holding a mutex to maximize contention within this
+ function. Each benchmark for a number of consumers is run three times and the best time is
+ picked to get rid of outliers.
+
+ The results are reported for each benchmark for a number of consumers. The most important number
+ is (std - boost) / std * 100. Positive numbers are when boost::condition_variable is faster,
+ negative it is slower.
+
+ */
+
+int main()
+{
+ std::printf("MAIN\n");
+ enum
+ {
+ CONSUMER_MAX = 2
+ };
+
+ struct
+ {
+ Stopwatch::rep boost, std;
+ } best_times[CONSUMER_MAX] = {};
+
+ for (unsigned i = 1; i <= CONSUMER_MAX; ++i)
+ {
+ auto& b = best_times[i - 1];
+ std::printf("STD: %d\n", i);
+ b.std = benchmark_ping_pong<StdTypes> (i);
+ std::printf("BOOST: %d\n", i);
+ b.boost = benchmark_ping_pong<BoostTypes> (i);
+
+ std::printf("consumers: %4d\n", i);
+ std::printf("best std producer time: %15.9fsec\n", b.std * 1e-9);
+ std::printf("best boost producer time: %15.9fsec\n", b.boost * 1e-9);
+ std::printf("(std - boost) / std: %7.2f%%\n", (b.std - b.boost) * 100. / b.std);
+ }
+
+ printf("\ncsv:\n\n");
+ printf("consumers,(std-boost)/std,std,boost\n");
+ for (unsigned i = 1; i <= CONSUMER_MAX; ++i)
+ {
+ auto& b = best_times[i - 1];
+ printf("%d,%f,%lld,%lld\n", i, (b.std - b.boost) * 100. / b.std, b.std, b.boost);
+ }
+ return 1;
+}
diff --git a/src/boost/libs/thread/example/perf_shared_mutex.cpp b/src/boost/libs/thread/example/perf_shared_mutex.cpp
new file mode 100644
index 000000000..b58c0079c
--- /dev/null
+++ b/src/boost/libs/thread/example/perf_shared_mutex.cpp
@@ -0,0 +1,72 @@
+// (C) Copyright 2013 Andrey
+// (C) Copyright 2013 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)
+//
+// This performance test is based on the performance test provided by maxim.yegorushkin
+// at https://svn.boost.org/trac/boost/ticket/7422
+
+#define BOOST_THREAD_USES_CHRONO
+
+#include <iostream>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+#include <boost/thread/shared_mutex.hpp>
+
+using namespace boost;
+
+shared_mutex mtx;
+const int cycles = 10000;
+
+void shared()
+{
+ int cycle(0);
+ while (++cycle < cycles)
+ {
+ shared_lock<shared_mutex> lock(mtx);
+ }
+}
+
+void unique()
+{
+ int cycle(0);
+ while (++cycle < cycles)
+ {
+ unique_lock<shared_mutex> lock(mtx);
+ }
+}
+
+int main()
+{
+ boost::chrono::high_resolution_clock::duration best_time(std::numeric_limits<boost::chrono::high_resolution_clock::duration::rep>::max BOOST_PREVENT_MACRO_SUBSTITUTION ());
+ for (int i =100; i>0; --i) {
+ boost::chrono::high_resolution_clock clock;
+ boost::chrono::high_resolution_clock::time_point s1 = clock.now();
+ thread t0(shared);
+ thread t1(shared);
+ thread t2(unique);
+ //thread t11(shared);
+ //thread t12(shared);
+ //thread t13(shared);
+
+ t0.join();
+ t1.join();
+ t2.join();
+ //t11.join();
+// t12.join();
+ // t13.join();
+ boost::chrono::high_resolution_clock::time_point f1 = clock.now();
+ //std::cout << " Time spent:" << (f1 - s1) << std::endl;
+ best_time = std::min BOOST_PREVENT_MACRO_SUBSTITUTION (best_time, f1 - s1);
+
+ }
+ std::cout << "Best Time spent:" << best_time << std::endl;
+ std::cout << "Time spent/cycle:" << best_time/cycles/3 << std::endl;
+
+ return 1;
+}
+
diff --git a/src/boost/libs/thread/example/producer_consumer.cpp b/src/boost/libs/thread/example/producer_consumer.cpp
new file mode 100644
index 000000000..73ad04fb7
--- /dev/null
+++ b/src/boost/libs/thread/example/producer_consumer.cpp
@@ -0,0 +1,147 @@
+// (C) Copyright 2012 Howard Hinnant
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+// adapted from the example given by Howard Hinnant in
+
+#include <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#ifdef XXXX
+#include <boost/thread/externally_locked_stream.hpp>
+ typedef boost::externally_locked_stream<std::ostream> the_ostream;
+#else
+ typedef std::ostream the_ostream;
+ typedef std::istream the_istream;
+#endif
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+
+void producer(the_ostream & /*mos*/, boost::sync_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ sbq.push(i);
+ //sbq << i;
+ //mos << "push(" << i << ") "<< sbq.size()<<"\n";
+ this_thread::sleep_for(chrono::milliseconds(200));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+
+void consumer(
+ the_ostream & /*mos*/,
+ boost::sync_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ sbq.pull(r);
+ //sbq >> r;
+ //mos << i << " pull(" << r << ") "<< sbq.size()<<"\n";
+
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+void consumer2(the_ostream &/*mos*/, boost::sync_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ queue_op_status st = sbq.try_pull(r);
+ if (queue_op_status::closed == st) break;
+ if (queue_op_status::success == st) {
+ //mos << i << " pull(" << r << ")\n";
+ }
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+void consumer3(the_ostream &/*mos*/, boost::sync_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ queue_op_status res = sbq.wait_pull(r);
+ if (res==queue_op_status::closed) break;
+ //mos << i << " wait_pull(" << r << ")\n";
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+
+int main()
+{
+ using namespace boost;
+
+#ifdef XXXX
+ recursive_mutex terminal_mutex;
+
+ externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex);
+ externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
+ externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
+#else
+ the_ostream &mcerr = std::cout;
+ the_ostream &mcout = std::cerr;
+ //the_istream &mcin = std::cin;
+#endif
+
+ sync_queue<int> sbq;
+
+ {
+ mcout << "begin of main" << std::endl;
+ scoped_thread<> t11(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
+ scoped_thread<> t12(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
+ scoped_thread<> t2(boost::thread(consumer, boost::ref(mcout), boost::ref(sbq)));
+
+ this_thread::sleep_for(chrono::seconds(1));
+
+ mcout << "closed()" << std::endl;
+ sbq.close();
+ mcout << "closed()" << std::endl;
+
+ } // all threads joined here.
+ mcout << "end of main" << std::endl;
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/producer_consumer2.cpp b/src/boost/libs/thread/example/producer_consumer2.cpp
new file mode 100644
index 000000000..a8264a9bb
--- /dev/null
+++ b/src/boost/libs/thread/example/producer_consumer2.cpp
@@ -0,0 +1,150 @@
+// (C) Copyright 2014 Vicente Botet
+//
+// 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)
+
+// adapted from the example given by Howard Hinnant in
+
+#include <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#ifdef XXXX
+#include <boost/thread/externally_locked_stream.hpp>
+ typedef boost::externally_locked_stream<std::ostream> the_ostream;
+#else
+ typedef std::ostream the_ostream;
+ typedef std::istream the_istream;
+#endif
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/concurrent_queues/queue_adaptor.hpp>
+#include <boost/thread/concurrent_queues/queue_views.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+
+void producer(the_ostream &/*mos*/, boost::queue_back<int> sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ sbq.push(i);
+ //sbq << i;
+ //mos << "push(" << i << ") " << sbq.size() <<"\n";
+ this_thread::sleep_for(chrono::milliseconds(200));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+
+void consumer(
+ the_ostream &/*mos*/,
+ boost::queue_front<int> sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ sbq.pull(r);
+ //sbq >> r;
+ //mos << i << " pull(" << r << ") " << sbq.size() <<"\n";
+
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+void consumer2(the_ostream &/*mos*/, boost::queue_front<int> sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ queue_op_status st = sbq.try_pull(r);
+ if (queue_op_status::closed == st) break;
+ if (queue_op_status::success == st) {
+ //mos << i << " try_pull(" << r << ")\n";
+ }
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+void consumer3(the_ostream &/*mos*/, boost::queue_front<int> sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ queue_op_status res = sbq.wait_pull(r);
+ if (res==queue_op_status::closed) break;
+ //mos << i << " wait_pull(" << r << ")\n";
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+
+int main()
+{
+ using namespace boost;
+
+#ifdef XXXX
+ recursive_mutex terminal_mutex;
+
+ externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex);
+ externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
+ externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
+#else
+ the_ostream &mcerr = std::cout;
+ the_ostream &mcout = std::cerr;
+ //the_istream &mcin = std::cin;
+#endif
+
+ queue_adaptor<sync_queue<int> > sbq;
+
+ {
+ mcout << "begin of main" << std::endl;
+ scoped_thread<> t11(boost::thread(producer, boost::ref(mcerr), concurrent::queue_back<int>(sbq)));
+ scoped_thread<> t12(boost::thread(producer, boost::ref(mcerr), concurrent::queue_back<int>(sbq)));
+ scoped_thread<> t2(boost::thread(consumer, boost::ref(mcout), concurrent::queue_front<int>(sbq)));
+
+ this_thread::sleep_for(chrono::seconds(1));
+
+ mcout << "closed()" << std::endl;
+ sbq.close();
+ mcout << "closed()" << std::endl;
+
+ } // all threads joined here.
+ mcout << "end of main" << std::endl;
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/producer_consumer_bounded.cpp b/src/boost/libs/thread/example/producer_consumer_bounded.cpp
new file mode 100644
index 000000000..70158a3e9
--- /dev/null
+++ b/src/boost/libs/thread/example/producer_consumer_bounded.cpp
@@ -0,0 +1,146 @@
+// (C) Copyright 2012 Howard Hinnant
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+// adapted from the example given by Howard Hinnant in
+
+#include <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+//#define XXXX
+
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#ifdef XXXX
+#include <boost/thread/externally_locked_stream.hpp>
+ typedef boost::externally_locked_stream<std::ostream> the_ostream;
+#else
+ typedef std::ostream the_ostream;
+ typedef std::istream the_istream;
+#endif
+
+#include <boost/thread/sync_bounded_queue.hpp>
+
+void producer(the_ostream &/*mos*/, boost::sync_bounded_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ sbq.push_back(i);
+ //sbq << i;
+ //mos << "push_back(" << i << ") "<< sbq.size()<<"\n";
+ this_thread::sleep_for(chrono::milliseconds(200));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+
+void consumer(the_ostream &/*mos*/, boost::sync_bounded_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ sbq.pull_front(r);
+ //sbq >> r;
+ //mos << i << " pull_front(" << r << ") "<< sbq.size()<<"\n";
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(sync_queue_is_closed&)
+ {
+ //mos << "closed !!!\n";
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+void consumer2(the_ostream &/*mos*/, boost::sync_bounded_queue<int> & sbq)
+{
+ using namespace boost;
+ try {
+ for(int i=0; ;++i)
+ {
+ int r;
+ queue_op_status st = sbq.try_pull_front(r);
+ if (queue_op_status::closed == st) break;
+ if (queue_op_status::success == st) {
+ //mos << i << " pull(" << r << ")\n";
+ }
+ this_thread::sleep_for(chrono::milliseconds(250));
+ }
+ }
+ catch(...)
+ {
+ //mos << "exception !!!\n";
+ }
+}
+//void consumer3(the_ostream &mos, boost::sync_bounded_queue<int> & sbq)
+//{
+// using namespace boost;
+// bool closed=false;
+// try {
+// for(int i=0; ;++i)
+// {
+// int r;
+// queue_op_status res = sbq.wait_and_pull(r);
+// if (res==queue_op_status::closed) break;
+// //mos << i << " wait_and_pull(" << r << ")\n";
+// this_thread::sleep_for(chrono::milliseconds(250));
+// }
+// }
+// catch(...)
+// {
+// //mos << "exception !!!\n";
+// }
+//}
+
+int main()
+{
+ using namespace boost;
+#ifdef XXXX
+ recursive_mutex terminal_mutex;
+
+ externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex);
+ externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
+ externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
+#else
+ the_ostream &mcerr = std::cout;
+ the_ostream &mcout = std::cerr;
+ //the_istream &mcin = std::cin;
+#endif
+
+ sync_bounded_queue<int> sbq(10);
+
+ {
+ mcout << "begin of main" << std::endl;
+ scoped_thread<> t11(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
+ scoped_thread<> t12(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
+ scoped_thread<> t2(boost::thread(consumer, boost::ref(mcout), boost::ref(sbq)));
+
+ this_thread::sleep_for(chrono::seconds(1));
+
+ sbq.close();
+ mcout << "closed()" << std::endl;
+
+ } // all threads joined here.
+ mcout << "end of main" << std::endl;
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/recursive_mutex.cpp b/src/boost/libs/thread/example/recursive_mutex.cpp
new file mode 100644
index 000000000..8cb99d30d
--- /dev/null
+++ b/src/boost/libs/thread/example/recursive_mutex.cpp
@@ -0,0 +1,49 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+class counter
+{
+public:
+ counter() : count(0) { }
+
+ int add(int val) {
+ boost::unique_lock<boost::recursive_mutex> scoped_lock(mutex);
+ count += val;
+ return count;
+ }
+ int increment() {
+ boost::unique_lock<boost::recursive_mutex> scoped_lock(mutex);
+ return add(1);
+ }
+
+private:
+ boost::recursive_mutex mutex;
+ int count;
+};
+
+counter c;
+
+void change_count()
+{
+ //std::cout << "count == " << c.increment() << std::endl;
+}
+
+int main(int, char*[])
+{
+ const int num_threads=4;
+
+ boost::thread_group threads;
+ for (int i=0; i < num_threads; ++i)
+ threads.create_thread(&change_count);
+
+ threads.join_all();
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/scoped_thread.cpp b/src/boost/libs/thread/example/scoped_thread.cpp
new file mode 100644
index 000000000..9242f5803
--- /dev/null
+++ b/src/boost/libs/thread/example/scoped_thread.cpp
@@ -0,0 +1,83 @@
+// (C) Copyright 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 3
+
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+
+void do_something(int& i)
+{
+ ++i;
+}
+void f(int, int)
+{
+}
+
+struct func
+{
+ int& i;
+
+ func(int& i_) :
+ i(i_)
+ {
+ }
+
+ void operator()()
+ {
+ for (unsigned j = 0; j < 1000000; ++j)
+ {
+ do_something(i);
+ }
+ }
+};
+
+void do_something_in_current_thread()
+{
+}
+
+int main()
+{
+ {
+ int some_local_state=0;
+ boost::strict_scoped_thread<> t( (boost::thread(func(some_local_state))));
+
+ do_something_in_current_thread();
+ }
+ {
+ int some_local_state=0;
+ boost::thread t(( func(some_local_state) ));
+ boost::strict_scoped_thread<> g( (boost::move(t)) );
+
+ do_something_in_current_thread();
+ }
+ {
+ int some_local_state=0;
+ boost::scoped_thread<> t( (boost::thread(func(some_local_state))));
+
+ if (t.joinable())
+ t.join();
+ else
+ do_something_in_current_thread();
+ }
+#if 0
+ {
+ int some_local_state=0;
+ boost::thread t(( func(some_local_state) ));
+ boost::scoped_thread<> g( (boost::move(t)) );
+ if (g.joinable())
+ g.detach();
+
+ do_something_in_current_thread();
+ }
+#endif
+ {
+ boost::scoped_thread<> g( &f, 1, 2 );
+ do_something_in_current_thread();
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/serial_executor.cpp b/src/boost/libs/thread/example/serial_executor.cpp
new file mode 100644
index 000000000..e3c2c340a
--- /dev/null
+++ b/src/boost/libs/thread/example/serial_executor.cpp
@@ -0,0 +1,107 @@
+// Copyright (C) 2015 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/serial_executor.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/executor_adaptor.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+
+void p1()
+{
+ //std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(30));
+ //std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+void p2()
+{
+ //std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
+ //std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+int f1()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ return 1;
+}
+int f2(int i)
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(2));
+ return i + 1;
+}
+
+void submit_some(boost::serial_executor& tp)
+{
+ for (int i = 0; i < 3; ++i) {
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ tp.submit(&p2);
+ }
+ for (int i = 0; i < 3; ++i) {
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ tp.submit(&p1);
+ }
+
+}
+
+
+void at_th_entry(boost::basic_thread_pool& )
+{
+
+}
+
+int test_executor_adaptor()
+{
+ {
+ try
+ {
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ {
+ boost::basic_thread_pool ea1(4);
+ boost::serial_executor ea2(ea1);
+ submit_some(ea2);
+ boost::this_thread::sleep_for(boost::chrono::seconds(10));
+ }
+#endif
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ }
+ return 0;
+}
+
+
+int main()
+{
+ return test_executor_adaptor();
+}
diff --git a/src/boost/libs/thread/example/serial_executor_cont.cpp b/src/boost/libs/thread/example/serial_executor_cont.cpp
new file mode 100644
index 000000000..1883b0718
--- /dev/null
+++ b/src/boost/libs/thread/example/serial_executor_cont.cpp
@@ -0,0 +1,113 @@
+// Copyright (C) 2015 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/serial_executor_cont.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/executor_adaptor.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/assert.hpp>
+#include <string>
+#include <iostream>
+
+void p1()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(30));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+void p2()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+int f1()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ return 1;
+}
+int f2(int i)
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::seconds(2));
+ return i + 1;
+}
+
+void submit_some(boost::serial_executor_cont& tp)
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ for (int i = 0; i < 3; ++i) {
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ tp.submit(&p2);
+ }
+ for (int i = 0; i < 3; ++i) {
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ tp.submit(&p1);
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+}
+
+
+void at_th_entry(boost::basic_thread_pool& )
+{
+
+}
+
+int test_executor_adaptor()
+{
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ try
+ {
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea1(4);
+ boost::serial_executor_cont ea2(ea1);
+ submit_some(ea2);
+ boost::this_thread::sleep_for(boost::chrono::seconds(10));
+ }
+#endif
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "ERROR= " << ex.what() << "" << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << " ERROR= exception thrown" << std::endl;
+ return 2;
+ }
+ }
+ // std::cout << BOOST_CONTEXTOF << std::endl;
+ return 0;
+}
+
+
+int main()
+{
+ return test_executor_adaptor();
+}
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 000000000..d1996588e
--- /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;
+}
diff --git a/src/boost/libs/thread/example/shared_mutex.cpp b/src/boost/libs/thread/example/shared_mutex.cpp
new file mode 100644
index 000000000..c0ef7a522
--- /dev/null
+++ b/src/boost/libs/thread/example/shared_mutex.cpp
@@ -0,0 +1,746 @@
+// 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)
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#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>
+#include <vector>
+
+#if defined BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/chrono_io.hpp>
+
+
+enum {reading, writing};
+int state = reading;
+
+#if 1
+
+boost::mutex&
+cout_mut()
+{
+ static boost::mutex m;
+ return m;
+}
+
+void
+print(const char* tag, unsigned count, char ch)
+{
+ boost::lock_guard<boost::mutex> _(cout_mut());
+ std::cout << tag << count << ch;
+}
+
+#elif 0
+
+boost::recursive_mutex&
+cout_mut()
+{
+ static boost::recursive_mutex m;
+ return m;
+}
+
+void print() {}
+
+template <class A0, class ...Args>
+void
+print(const A0& a0, const Args& ...args)
+{
+ boost::lock_guard<boost::recursive_mutex> _(cout_mut());
+ std::cout << a0;
+ print(args...);
+}
+
+#else
+
+template <class A0, class A1, class A2>
+void
+print(const A0&, const A1& a1, const A2&)
+{
+ assert(a1 > 10000);
+}
+
+#endif
+
+namespace S
+{
+
+boost::shared_mutex mut;
+
+void reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ print("reader = ", count, '\n');
+}
+
+void writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock();
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ print("writer = ", count, '\n');
+}
+
+void try_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_reader = ", count, '\n');
+}
+
+void try_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock())
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_writer = ", count, '\n');
+}
+
+void try_for_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_for_reader = ", count, '\n');
+}
+
+void try_for_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_for_writer = ", count, '\n');
+}
+
+void
+test_shared_mutex()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_reader);
+ boost::thread t2(try_writer);
+ boost::thread t3(try_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_for_reader);
+ boost::thread t2(try_for_writer);
+ boost::thread t3(try_for_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+}
+
+}
+
+namespace U
+{
+
+boost::upgrade_mutex mut;
+
+void reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ print("reader = ", count, '\n');
+}
+
+void writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock();
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ print("writer = ", count, '\n');
+}
+
+void try_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_reader = ", count, '\n');
+}
+
+void try_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock())
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_writer = ", count, '\n');
+}
+
+void try_for_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_for_reader = ", count, '\n');
+}
+
+void try_for_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_for_writer = ", count, '\n');
+}
+
+void upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_upgrade();
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ print("upgradable = ", count, '\n');
+}
+
+void try_upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ }
+ print("try_upgradable = ", count, '\n');
+}
+
+void try_for_upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ }
+ print("try_for_upgradable = ", count, '\n');
+}
+
+void clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock())
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade())
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ print("clockwise = ", count, '\n');
+}
+
+void counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ print("counter_clockwise = ", count, '\n');
+}
+
+void try_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock())
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade())
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ }
+ print("try_clockwise = ", count, '\n');
+}
+
+void try_for_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ }
+ print("try_for_clockwise = ", count, '\n');
+}
+
+void try_counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade())
+ {
+ assert(state == reading);
+ if (mut.try_unlock_upgrade_and_lock())
+ {
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ else
+ {
+ mut.unlock_upgrade();
+ }
+ }
+ }
+ print("try_counter_clockwise = ", count, '\n');
+}
+
+void try_for_counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ if (mut.try_unlock_upgrade_and_lock_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ else
+ {
+ mut.unlock_upgrade();
+ }
+ }
+ }
+ print("try_for_counter_clockwise = ", count, '\n');
+}
+
+void
+test_upgrade_mutex()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_reader);
+ boost::thread t2(try_writer);
+ boost::thread t3(try_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_for_reader);
+ boost::thread t2(try_for_writer);
+ boost::thread t3(try_for_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(try_upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(try_for_upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ state = reading;
+ boost::thread t1(clockwise);
+ boost::thread t2(counter_clockwise);
+ boost::thread t3(clockwise);
+ boost::thread t4(counter_clockwise);
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ state = reading;
+ boost::thread t1(try_clockwise);
+ boost::thread t2(try_counter_clockwise);
+ t1.join();
+ t2.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+// {
+// state = reading;
+// boost::thread t1(try_for_clockwise);
+// boost::thread t2(try_for_counter_clockwise);
+// t1.join();
+// t2.join();
+// }
+// std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+}
+
+}
+
+namespace Assignment
+{
+
+class A
+{
+ typedef boost::upgrade_mutex mutex_type;
+ typedef boost::shared_lock<mutex_type> SharedLock;
+ typedef boost::upgrade_lock<mutex_type> UpgradeLock;
+ typedef boost::unique_lock<mutex_type> Lock;
+
+ mutable mutex_type mut_;
+ std::vector<double> data_;
+
+public:
+
+ A(const A& a)
+ {
+ SharedLock _(a.mut_);
+ data_ = a.data_;
+ }
+
+ A& operator=(const A& a)
+ {
+ if (this != &a)
+ {
+ Lock this_lock(mut_, boost::defer_lock);
+ SharedLock that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, that_lock);
+ data_ = a.data_;
+ }
+ return *this;
+ }
+
+ void swap(A& a)
+ {
+ Lock this_lock(mut_, boost::defer_lock);
+ Lock that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, that_lock);
+ data_.swap(a.data_);
+ }
+
+ void average(A& a)
+ {
+ assert(data_.size() == a.data_.size());
+ assert(this != &a);
+
+ Lock this_lock(mut_, boost::defer_lock);
+ UpgradeLock share_that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, share_that_lock);
+
+ for (unsigned i = 0; i < data_.size(); ++i)
+ data_[i] = (data_[i] + a.data_[i]) / 2;
+
+ SharedLock share_this_lock(boost::move(this_lock));
+ Lock that_lock(boost::move(share_that_lock));
+ a.data_ = data_;
+ }
+};
+
+} // Assignment
+
+void temp()
+{
+ using namespace boost;
+ static upgrade_mutex mut;
+ unique_lock<upgrade_mutex> ul(mut);
+ shared_lock<upgrade_mutex> sl;
+ sl = BOOST_THREAD_MAKE_RV_REF(shared_lock<upgrade_mutex>(boost::move(ul)));
+}
+
+int main()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ typedef boost::chrono::high_resolution_clock Clock;
+ typedef boost::chrono::duration<double> sec;
+ Clock::time_point t0 = Clock::now();
+
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ S::test_shared_mutex();
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ U::test_upgrade_mutex();
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ Clock::time_point t1 = Clock::now();
+ std::cout << sec(t1 - t0) << '\n';
+ return 0;
+}
+
+#else
+#error "This platform doesn't support Boost.Chrono"
+#endif
diff --git a/src/boost/libs/thread/example/starvephil.cpp b/src/boost/libs/thread/example/starvephil.cpp
new file mode 100644
index 000000000..467d0b3c4
--- /dev/null
+++ b/src/boost/libs/thread/example/starvephil.cpp
@@ -0,0 +1,187 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+#include <time.h>
+
+namespace
+{
+boost::mutex iomx;
+} // namespace
+
+class canteen
+{
+public:
+ canteen() : m_chickens(0) { }
+
+ void get(int id)
+ {
+ boost::unique_lock<boost::mutex> lock(m_mutex);
+ while (m_chickens == 0)
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock() << ") Phil" << id <<
+ ": wot, no chickens? I'll WAIT ..." << std::endl;
+ }
+ m_condition.wait(lock);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock() << ") Phil" << id <<
+ ": those chickens look good ... one please ..." << std::endl;
+ }
+ m_chickens--;
+ }
+ void put(int value)
+ {
+ boost::unique_lock<boost::mutex> lock(m_mutex);
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock()
+ << ") Chef: ouch ... make room ... this dish is "
+ << "very hot ..." << std::endl;
+ }
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += 3;
+ boost::thread::sleep(xt);
+ m_chickens += value;
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock() <<
+ ") Chef: more chickens ... " << m_chickens <<
+ " now available ... NOTIFYING ..." << std::endl;
+ }
+ m_condition.notify_all();
+ }
+
+private:
+ boost::mutex m_mutex;
+ boost::condition m_condition;
+ int m_chickens;
+};
+
+canteen g_canteen;
+
+void chef()
+{
+ const int chickens = 4;
+ {
+ boost::unique_lock<boost::mutex> lock(iomx);
+ std::cout << "(" << clock() << ") Chef: starting ..." << std::endl;
+ }
+ for (;;)
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(iomx);
+ std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
+ }
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += 2;
+ boost::thread::sleep(xt);
+ {
+ boost::unique_lock<boost::mutex> lock(iomx);
+ std::cout << "(" << clock() << ") Chef: " << chickens
+ << " chickens, ready-to-go ..." << std::endl;
+ }
+ g_canteen.put(chickens);
+ }
+}
+
+struct phil
+{
+ phil(int id) : m_id(id) { }
+ void run() {
+ {
+ boost::unique_lock<boost::mutex> lock(iomx);
+ std::cout << "(" << clock() << ") Phil" << m_id
+ << ": starting ..." << std::endl;
+ }
+ for (;;)
+ {
+ if (m_id > 0)
+ {
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += 3;
+ boost::thread::sleep(xt);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock() << ") Phil" << m_id
+ << ": gotta eat ..." << std::endl;
+ }
+ g_canteen.get(m_id);
+ {
+ boost::unique_lock<boost::mutex> lk(iomx);
+ std::cout << "(" << clock() << ") Phil" << m_id
+ << ": mmm ... that's good ..." << std::endl;
+ }
+ }
+ }
+ static void do_thread(void* param) {
+ static_cast<phil*>(param)->run();
+ }
+
+ int m_id;
+};
+
+struct thread_adapt
+{
+ thread_adapt(void (*func)(void*), void* param)
+ : _func(func), _param(param)
+ {
+ }
+ int operator()() const
+ {
+ _func(_param);
+ return 0;
+ }
+
+ void (*_func)(void*);
+ void* _param;
+};
+
+class thread_adapter
+{
+public:
+ thread_adapter(void (*func)(void*), void* param)
+ : _func(func), _param(param)
+ {
+ }
+ void operator()() const { _func(_param); }
+private:
+ void (*_func)(void*);
+ void* _param;
+};
+
+int main()
+{
+ boost::thread thrd_chef(&chef);
+ phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
+ boost::thread thrd_phil0(thread_adapter(&phil::do_thread, &p[0]));
+ boost::thread thrd_phil1(thread_adapter(&phil::do_thread, &p[1]));
+ boost::thread thrd_phil2(thread_adapter(&phil::do_thread, &p[2]));
+ boost::thread thrd_phil3(thread_adapter(&phil::do_thread, &p[3]));
+ boost::thread thrd_phil4(thread_adapter(&phil::do_thread, &p[4]));
+
+ thrd_chef.join();
+ thrd_phil0.join();
+ thrd_phil1.join();
+ thrd_phil2.join();
+ thrd_phil3.join();
+ thrd_phil4.join();
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/std_scoped_thread.cpp b/src/boost/libs/thread/example/std_scoped_thread.cpp
new file mode 100644
index 000000000..5e9e7bd65
--- /dev/null
+++ b/src/boost/libs/thread/example/std_scoped_thread.cpp
@@ -0,0 +1,112 @@
+// (C) Copyright 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+#if __cplusplus < 201103L
+int main()
+{
+ return 0;
+}
+#else
+
+#define BOOST_THREAD_VERSION 3
+
+#include <iostream>
+#include <boost/thread/scoped_thread.hpp>
+#include <thread>
+#include <cassert>
+
+void do_something(int& i)
+{
+ ++i;
+}
+void f(int, int)
+{
+}
+
+struct func
+{
+ int& i;
+
+ func(int& i_) :
+ i(i_)
+ {
+ }
+
+ void operator()()
+ {
+ for (unsigned j = 0; j < 1000000; ++j)
+ {
+ do_something(i);
+ }
+ }
+};
+
+void do_something_in_current_thread()
+{
+}
+
+using strict_scoped_thread = boost::strict_scoped_thread<boost::join_if_joinable, std::thread>;
+using scoped_thread = boost::scoped_thread<boost::join_if_joinable, std::thread>;
+
+int main()
+{
+ {
+ int some_local_state=0;
+ strict_scoped_thread t( (std::thread(func(some_local_state))));
+
+ do_something_in_current_thread();
+ }
+ {
+ int some_local_state=0;
+ std::thread t(( func(some_local_state) ));
+ strict_scoped_thread g( (boost::move(t)) );
+
+ do_something_in_current_thread();
+ }
+ {
+ int some_local_state=0;
+ std::thread t(( func(some_local_state) ));
+ strict_scoped_thread g( (std::move(t)) );
+
+ do_something_in_current_thread();
+ }
+ {
+ int some_local_state=1;
+ scoped_thread t( (std::thread(func(some_local_state))));
+
+ if (t.joinable()) {
+ t.join();
+ assert( ! t.joinable() );
+ }
+ else
+ do_something_in_current_thread();
+ }
+#if 0
+ try
+ {
+ int some_local_state=1;
+ std::thread t(( func(some_local_state) ));
+ scoped_thread g( (boost::move(t)) );
+ if (g.joinable()) {
+ // CLANG crash here
+ g.detach();
+ assert( ! g.joinable() );
+ }
+
+ do_something_in_current_thread();
+ }
+ catch (...) {
+ assert( false);
+ }
+#endif
+ {
+ scoped_thread g( &f, 1, 2 );
+ do_something_in_current_thread();
+ }
+ return 0;
+}
+
+#endif
diff --git a/src/boost/libs/thread/example/std_thread_guard.cpp b/src/boost/libs/thread/example/std_thread_guard.cpp
new file mode 100644
index 000000000..ebf5a4173
--- /dev/null
+++ b/src/boost/libs/thread/example/std_thread_guard.cpp
@@ -0,0 +1,66 @@
+// (C) Copyright 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+#if __cplusplus < 201103L
+int main()
+{
+ return 0;
+}
+#else
+#include <iostream>
+#include <string>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/thread_guard.hpp>
+#include <thread>
+
+void do_something(int& i)
+{
+ ++i;
+}
+
+struct func
+{
+ int& i;
+
+ func(int& i_):i(i_){}
+
+ void operator()()
+ {
+ for(unsigned j=0;j<1000000;++j)
+ {
+ do_something(i);
+ }
+ }
+
+private:
+ func& operator=(func const&);
+
+};
+
+void do_something_in_current_thread()
+{}
+
+using thread_guard = boost::thread_guard<boost::join_if_joinable, std::thread>;
+
+
+void f()
+{
+ int some_local_state;
+ func my_func(some_local_state);
+ std::thread t(my_func);
+ thread_guard g(t);
+
+ do_something_in_current_thread();
+}
+
+int main()
+{
+ f();
+ return 0;
+}
+
+
+#endif
diff --git a/src/boost/libs/thread/example/strict_lock.cpp b/src/boost/libs/thread/example/strict_lock.cpp
new file mode 100644
index 000000000..43cfe5dfc
--- /dev/null
+++ b/src/boost/libs/thread/example/strict_lock.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2012 Vicente Botet
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_traits.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <iostream>
+
+
+BOOST_STATIC_ASSERT(boost::is_strict_lock<boost::strict_lock<boost::mutex> >::value);
+BOOST_CONCEPT_ASSERT(( boost::BasicLockable<boost::mutex> ));
+BOOST_CONCEPT_ASSERT(( boost::StrictLock<boost::strict_lock<boost::mutex> > ));
+
+int main()
+{
+ {
+ boost::mutex mtx;
+ boost::strict_lock<boost::mutex> lk(mtx);
+ std::cout << __FILE__ << std::endl;
+ }
+ {
+ boost::timed_mutex mtx;
+ boost::unique_lock<boost::timed_mutex> lk(mtx);
+ boost::nested_strict_lock<boost::unique_lock<boost::timed_mutex> > nlk(lk);
+ std::cout << __FILE__ << std::endl;
+ }
+ {
+ boost::mutex mtx;
+ boost::unique_lock<boost::mutex> lk(mtx, boost::defer_lock);
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk);
+ std::cout << __FILE__ << std::endl;
+ }
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/synchronized_person.cpp b/src/boost/libs/thread/example/synchronized_person.cpp
new file mode 100644
index 000000000..7930c0b00
--- /dev/null
+++ b/src/boost/libs/thread/example/synchronized_person.cpp
@@ -0,0 +1,282 @@
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <string>
+#include <boost/thread/synchronized_value.hpp>
+
+//class SafePerson {
+//public:
+// std::string GetName() const {
+// const_unique_access<std::string> name(nameGuard);
+// return *name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<std::string> name(nameGuard);
+// *name = newName;
+// }
+//private:
+// unique_access_guard<std::string> nameGuard;
+//};
+
+class SafePerson {
+public:
+ std::string GetName() const {
+ return *name;
+ }
+ void SetName(const std::string& newName) {
+ *name = newName;
+ }
+
+private:
+ boost::synchronized_value<std::string> name;
+};
+
+class Person {
+public:
+ std::string GetName() const {
+ return name;
+ }
+ void SetName(const std::string& newName) {
+ name = newName;
+ }
+private:
+ std::string name;
+};
+typedef boost::synchronized_value<Person> Person_ts;
+
+
+//class SafeMemberPerson {
+//public:
+// SafeMemberPerson(unsigned int age) :
+// memberGuard(age)
+// { }
+// std::string GetName() const {
+// const_unique_access<Member> member(memberGuard);
+// return member->name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<Member> member(memberGuard);
+// member->name = newName;
+// }
+//private:
+// struct Member
+// {
+// Member(unsigned int age) :
+// age(age)
+// { }
+// std::string name;
+// unsigned int age;
+// };
+// unique_access_guard<Member> memberGuard;
+//};
+
+class SafeMemberPerson {
+public:
+ SafeMemberPerson(unsigned int age) :
+ member(Member(age))
+ { }
+ std::string GetName() const {
+ return member->name;
+ }
+ void SetName(const std::string& newName) {
+ member->name = newName;
+ }
+private:
+ struct Member {
+ Member(unsigned int age) :
+ age(age)
+ { }
+ std::string name;
+ unsigned int age;
+ };
+ boost::synchronized_value<Member> member;
+};
+
+
+class Person2 {
+public:
+ Person2(unsigned int age) : age_(age)
+ {}
+ std::string GetName() const {
+ return name_;
+ }
+ void SetName(const std::string& newName) {
+ name_ = newName;
+ }
+ unsigned int GetAge() const {
+ return age_;
+ }
+
+private:
+ std::string name_;
+ unsigned int age_;
+};
+typedef boost::synchronized_value<Person2> Person2_ts;
+
+//===================
+
+//class HelperPerson {
+//public:
+// HelperPerson(unsigned int age) :
+// memberGuard(age)
+// { }
+// std::string GetName() const {
+// const_unique_access<Member> member(memberGuard);
+// Invariant(member);
+// return member->name;
+// }
+// void SetName(const std::string& newName) {
+// unique_access<Member> member(memberGuard);
+// Invariant(member);
+// member->name = newName;
+// }
+//private:
+// void Invariant(const_unique_access<Member>& member) const {
+// if (member->age < 0) throw std::runtime_error("Age cannot be negative");
+// }
+// struct Member {
+// Member(unsigned int age) :
+// age(age)
+// { }
+// std::string name;
+// unsigned int age;
+// };
+// unique_access_guard<Member> memberGuard;
+//};
+
+class HelperPerson {
+public:
+ HelperPerson(unsigned int age) :
+ member(age)
+ { }
+ std::string GetName() const {
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ auto memberSync = member.synchronize();
+#else
+ boost::const_strict_lock_ptr<Member> memberSync = member.synchronize();
+#endif
+ Invariant(memberSync);
+ return memberSync->name;
+ }
+ void SetName(const std::string& newName) {
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ auto memberSync = member.synchronize();
+#else
+ boost::strict_lock_ptr<Member> memberSync = member.synchronize();
+#endif
+ Invariant(memberSync);
+ memberSync->name = newName;
+ }
+private:
+ struct Member {
+ Member(unsigned int age) :
+ age(age)
+ { }
+ std::string name;
+ unsigned int age;
+ };
+ void Invariant(boost::const_strict_lock_ptr<Member> & mbr) const
+ {
+ if (mbr->age < 1) throw std::runtime_error("Age cannot be negative");
+ }
+ boost::synchronized_value<Member> member;
+};
+
+class Person3 {
+public:
+ Person3(unsigned int age) :
+ age_(age)
+ { }
+ std::string GetName() const {
+ Invariant();
+ return name_;
+ }
+ void SetName(const std::string& newName) {
+ Invariant();
+ name_ = newName;
+ }
+private:
+ std::string name_;
+ unsigned int age_;
+ void Invariant() const {
+ if (age_ < 1) throw std::runtime_error("Age cannot be negative");
+ }
+};
+
+typedef boost::synchronized_value<Person3> Person3_ts;
+
+int main()
+{
+ {
+ SafePerson p;
+ p.SetName("Vicente");
+ }
+ {
+ Person_ts p;
+ p->SetName("Vicente");
+ }
+ {
+ SafeMemberPerson p(1);
+ p.SetName("Vicente");
+ }
+ {
+ Person2_ts p(1);
+ p->SetName("Vicente");
+ }
+ {
+ HelperPerson p(1);
+ p.SetName("Vicente");
+ }
+ {
+ Person3_ts p(1);
+ p->SetName("Vicente");
+ }
+ {
+ Person3_ts p1(1);
+ Person3_ts p2(2);
+ Person3_ts p3(3);
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ auto lk1 = p1.unique_synchronize(boost::defer_lock);
+ auto lk2 = p2.unique_synchronize(boost::defer_lock);
+ auto lk3 = p3.unique_synchronize(boost::defer_lock);
+#else
+ boost::unique_lock_ptr<Person3> lk1 = p1.unique_synchronize(boost::defer_lock);
+ boost::unique_lock_ptr<Person3> lk2 = p2.unique_synchronize(boost::defer_lock);
+ boost::unique_lock_ptr<Person3> lk3 = p3.unique_synchronize(boost::defer_lock);
+#endif
+ boost::lock(lk1,lk2,lk3);
+
+ lk1->SetName("Carmen");
+ lk2->SetName("Javier");
+ lk3->SetName("Matias");
+ }
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS \
+&& ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+ {
+ Person3_ts p1(1);
+ Person3_ts p2(2);
+ Person3_ts p3(3);
+
+ auto t = boost::synchronize(p1,p2,p3);
+ std::get<0>(t)->SetName("Carmen");
+ std::get<1>(t)->SetName("Javier");
+ std::get<2>(t)->SetName("Matias");
+ }
+ {
+ const Person3_ts p1(1);
+ Person3_ts p2(2);
+ const Person3_ts p3(3);
+
+ auto t = boost::synchronize(p1,p2,p3);
+ //std::get<0>(t)->SetName("Carmen");
+ std::get<1>(t)->SetName("Javier");
+ //std::get<2>(t)->SetName("Matias");
+ }
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/synchronized_value.cpp b/src/boost/libs/thread/example/synchronized_value.cpp
new file mode 100644
index 000000000..61480a57c
--- /dev/null
+++ b/src/boost/libs/thread/example/synchronized_value.cpp
@@ -0,0 +1,147 @@
+// (C) Copyright 2010 Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
+// (C) Copyright 2012 Vicente Botet
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <string>
+#include <boost/thread/synchronized_value.hpp>
+
+ void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
+ {
+ boost::strict_lock_ptr<std::string> u=path.synchronize();
+
+ if(u->empty() || (*u->rbegin()!='/'))
+ {
+ *u+='/';
+ }
+ }
+
+void f(const boost::synchronized_value<int> &v) {
+ std::cout<<"v="<<*v<<std::endl;
+}
+
+void g(const boost::const_strict_lock_ptr<int> &v) {
+ std::cout<<"v="<<*v<<std::endl;
+}
+
+bool checkIfMissingTrailingSlash(boost::synchronized_value<std::string> & path)
+{
+ boost::strict_lock_ptr<std::string> u=path.synchronize();
+
+ return (u->empty() || (*u->rbegin()!='/'));
+}
+
+int main()
+{
+ {
+ boost::synchronized_value<int> v1;
+ *v1=42;
+ std::cout<<"v1="<<*v1<<std::endl;
+ f(v1);
+ int i=*v1;
+ std::cout<<"i="<<i<<std::endl;
+
+ {
+ boost::strict_lock_ptr<int> u=v1.synchronize();
+
+ *u+=43;
+ std::cout<<"v1="<<*u<<std::endl;
+ g(u);
+ }
+ boost::synchronized_value<int> v2(2);
+ std::cout<<"v2="<<*v2<<std::endl;
+ v2 = 3;
+ std::cout<<"v2="<<*v2<<std::endl;
+
+ boost::synchronized_value<int> v3(v2);
+ std::cout<<"v3="<<*v3<<std::endl;
+ v3 = v1;
+ std::cout<<"v3="<<*v3<<std::endl;
+
+ std::cout<<"v2="<<*v3<<std::endl;
+ std::cout<<"v3="<<*v3<<std::endl;
+ swap(v3,v2);
+ v1.swap(v2);
+ std::cout<<"v3="<<*v3<<std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s;
+ addTrailingSlashIfMissing(s);
+ std::cout<<"s="<<std::string(*s)<<std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s;
+ s->append("foo/");
+ s.synchronize()->append("foo");
+ addTrailingSlashIfMissing(s);
+ std::cout<<"s="<<std::string(*s)<<std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s;
+ s = std::string("foo/");
+ std::cout<<"ss="<< s << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s;
+ s = "foo/";
+ std::cout<<"ss="<< s << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s1("a");
+ boost::synchronized_value<std::string> s2;
+ s2=s1;
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s1("a");
+ boost::synchronized_value<std::string> s2("b");
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ swap(s1,s2);
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ }
+#if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ {
+ boost::synchronized_value<std::string> sts("a");
+ std::string s(sts);
+ std::cout<<"ssts="<< s << std::endl;
+ }
+#endif
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(1);
+ BOOST_ASSERT(s1==s2);
+ BOOST_ASSERT(s1<=s2);
+ BOOST_ASSERT(s1>=s2);
+ BOOST_ASSERT(s1==1);
+ BOOST_ASSERT(s1<=1);
+ BOOST_ASSERT(s1>=1);
+ }
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(2);
+ BOOST_ASSERT(s1!=s2);
+ BOOST_ASSERT(s1!=2);
+ BOOST_ASSERT(2!=s1);
+ }
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(2);
+ BOOST_ASSERT(s1<s2);
+ BOOST_ASSERT(s1<=s2);
+ BOOST_ASSERT(s2>s1);
+ BOOST_ASSERT(s2>=s1);
+ BOOST_ASSERT(s1<2);
+ BOOST_ASSERT(s1<=2);
+ BOOST_ASSERT(s2>1);
+ BOOST_ASSERT(s2>=1);
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/example/tennis.cpp b/src/boost/libs/thread/example/tennis.cpp
new file mode 100644
index 000000000..d560ecb92
--- /dev/null
+++ b/src/boost/libs/thread/example/tennis.cpp
@@ -0,0 +1,137 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+#undef BOOST_THREAD_VERSION
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+
+#if defined(BOOST_HAS_WINTHREADS)
+# include <windows.h>
+# include <process.h>
+#endif
+
+enum game_state
+{
+ START,
+ PLAYER_A,
+ PLAYER_B,
+ GAME_OVER,
+ ONE_PLAYER_GONE,
+ BOTH_PLAYERS_GONE
+};
+
+int state;
+boost::mutex mutex;
+boost::condition cond;
+
+const char* player_name(int state)
+{
+ if (state == PLAYER_A)
+ return "PLAYER-A";
+ if (state == PLAYER_B)
+ return "PLAYER-B";
+ throw "bad player";
+ //return 0;
+}
+
+void player(int active)
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
+
+ while (state < GAME_OVER)
+ {
+ //std::cout << player_name(active) << ": Play." << std::endl;
+ state = other;
+ cond.notify_all();
+ do
+ {
+ cond.wait(lock);
+ if (state == other)
+ {
+ std::cout << "---" << player_name(active)
+ << ": Spurious wakeup!" << std::endl;
+ }
+ } while (state == other);
+ }
+
+ ++state;
+ std::cout << player_name(active) << ": Gone." << std::endl;
+ cond.notify_all();
+}
+
+struct thread_adapt
+{
+ thread_adapt(void (*func)(void*), void* param)
+ : _func(func), _param(param)
+ {
+ }
+ int operator()() const
+ {
+ _func(_param);
+ return 0;
+ }
+
+ void (*_func)(void*);
+ void* _param;
+};
+
+class thread_adapter
+{
+public:
+ thread_adapter(void (*func)(void*), void* param)
+ : _func(func), _param(param)
+ {
+ }
+ void operator()() const { _func(_param); }
+private:
+ void (*_func)(void*);
+ void* _param;
+};
+
+int main()
+{
+ state = START;
+
+ boost::thread thrda(&player, PLAYER_A);
+ boost::thread thrdb(&player, PLAYER_B);
+
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += 1;
+ boost::thread::sleep(xt);
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << "---Noise ON..." << std::endl;
+ }
+
+ for (int i = 0; i < 10; ++i)
+ cond.notify_all();
+
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << "---Noise OFF..." << std::endl;
+ state = GAME_OVER;
+ cond.notify_all();
+ do
+ {
+ cond.wait(lock);
+ } while (state != BOTH_PLAYERS_GONE);
+ }
+
+ std::cout << "GAME OVER" << std::endl;
+
+ thrda.join();
+ thrdb.join();
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/this_executor.cpp b/src/boost/libs/thread/example/this_executor.cpp
new file mode 100644
index 000000000..e573f05c1
--- /dev/null
+++ b/src/boost/libs/thread/example/this_executor.cpp
@@ -0,0 +1,85 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// 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 <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 5
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+
+#include <boost/thread/caller_context.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <string>
+#include <iostream>
+
+#include <boost/thread/caller_context.hpp>
+
+struct current_executor_state_type {
+ boost::shared_ptr<boost::generic_executor_ref> current_executor_ptr;
+
+ template <class Executor>
+ void set_current_executor(Executor& ex)
+ {
+ current_executor_ptr = boost::make_shared<boost::generic_executor_ref>(ex);
+ }
+ boost::generic_executor_ref current_executor()
+ {
+ if (current_executor_ptr)
+ return *current_executor_ptr;
+ else
+ throw "";
+ }
+};
+
+thread_local current_executor_state_type current_executor_state;
+
+boost::generic_executor_ref current_executor()
+{
+ return current_executor_state.current_executor();
+}
+
+void p2()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+
+void p1()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ current_executor().submit(&p2);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(400));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+}
+
+int main()
+{
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+ boost::basic_thread_pool tp(4,
+ // at_thread_entry
+ [](boost::basic_thread_pool& pool)
+ {
+ current_executor_state.set_current_executor(pool);
+ }
+ );
+
+ tp.submit(&p1);
+
+ boost::this_thread::sleep_for(boost::chrono::seconds(5));
+
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
+ return 1;
+
+}
diff --git a/src/boost/libs/thread/example/thread.cpp b/src/boost/libs/thread/example/thread.cpp
new file mode 100644
index 000000000..d6bc6f23f
--- /dev/null
+++ b/src/boost/libs/thread/example/thread.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+
+struct thread_alarm
+{
+ thread_alarm(int secs) : m_secs(secs) { }
+ void operator()()
+ {
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += m_secs;
+
+ boost::thread::sleep(xt);
+
+ std::cout << "alarm sounded..." << std::endl;
+ }
+
+ int m_secs;
+};
+
+int main()
+{
+ int secs = 5;
+ std::cout << "setting alarm for 5 seconds..." << std::endl;
+ thread_alarm alarm(secs);
+ boost::thread thrd(alarm);
+ thrd.join();
+}
diff --git a/src/boost/libs/thread/example/thread_group.cpp b/src/boost/libs/thread/example/thread_group.cpp
new file mode 100644
index 000000000..1256a1045
--- /dev/null
+++ b/src/boost/libs/thread/example/thread_group.cpp
@@ -0,0 +1,73 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <boost/thread/thread.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+boost::mutex mutex;
+
+void increment_count()
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << "count = " << ++count << std::endl;
+}
+
+boost::thread_group threads2;
+boost::thread* th2 = 0;
+
+void increment_count_2()
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+ BOOST_TEST(threads2.is_this_thread_in());
+ std::cout << "count = " << ++count << std::endl;
+}
+
+int main()
+{
+ {
+ boost::thread_group threads;
+ for (int i = 0; i < 3; ++i)
+ threads.create_thread(&increment_count);
+ threads.join_all();
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ {
+ boost::thread_group threads;
+ for (int i = 0; i < 3; ++i)
+ threads.create_thread(&increment_count);
+ threads.interrupt_all();
+ threads.join_all();
+ }
+#endif
+ {
+ boost::thread_group threads;
+ boost::thread* th = new boost::thread(&increment_count);
+ threads.add_thread(th);
+ BOOST_TEST(! threads.is_this_thread_in());
+ threads.join_all();
+ }
+ {
+ boost::thread_group threads;
+ boost::thread* th = new boost::thread(&increment_count);
+ threads.add_thread(th);
+ BOOST_TEST(threads.is_thread_in(th));
+ threads.remove_thread(th);
+ BOOST_TEST(! threads.is_thread_in(th));
+ th->join();
+ delete th;
+ }
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ boost::thread* th2 = new boost::thread(&increment_count_2);
+ threads2.add_thread(th2);
+ }
+ threads2.join_all();
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/example/thread_guard.cpp b/src/boost/libs/thread/example/thread_guard.cpp
new file mode 100644
index 000000000..a8b285deb
--- /dev/null
+++ b/src/boost/libs/thread/example/thread_guard.cpp
@@ -0,0 +1,58 @@
+// (C) Copyright 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente Botet
+//
+// 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 <string>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/thread_guard.hpp>
+
+void do_something(int& i)
+{
+ ++i;
+}
+
+struct func
+{
+ int& i;
+
+ func(int& i_):i(i_){}
+ func(func const& other):i(other.i){}
+
+ void operator()()
+ {
+ for(unsigned j=0;j<1000000;++j)
+ {
+ do_something(i);
+ }
+ }
+
+private:
+ func& operator=(func const&);
+
+};
+
+void do_something_in_current_thread()
+{}
+
+
+void f()
+{
+ int some_local_state;
+ func my_func(some_local_state);
+ boost::thread t(my_func);
+ boost::thread_guard<> g(t);
+
+ do_something_in_current_thread();
+}
+
+int main()
+{
+ f();
+ return 0;
+}
+
+
diff --git a/src/boost/libs/thread/example/thread_pool.cpp b/src/boost/libs/thread/example/thread_pool.cpp
new file mode 100644
index 000000000..bf9b64e1d
--- /dev/null
+++ b/src/boost/libs/thread/example/thread_pool.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 5
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/assert.hpp>
+#include <string>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+void p1()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " P1" << BOOST_THREAD_END_LOG;
+}
+
+void p2()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " P2" << BOOST_THREAD_END_LOG;
+}
+
+void submit_some(boost::basic_thread_pool& tp) {
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+}
+
+
+int main()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " <MAIN" << BOOST_THREAD_END_LOG;
+ {
+ try
+ {
+ boost::basic_thread_pool tp;
+ submit_some(tp);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/tss.cpp b/src/boost/libs/thread/example/tss.cpp
new file mode 100644
index 000000000..f5f108e11
--- /dev/null
+++ b/src/boost/libs/thread/example/tss.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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 <boost/thread/thread.hpp>
+#include <boost/thread/tss.hpp>
+#include <cassert>
+
+boost::thread_specific_ptr<int> value;
+
+void increment()
+{
+ int* p = value.get();
+ ++*p;
+}
+
+void thread_proc()
+{
+ value.reset(new int(0)); // initialize the thread's storage
+ for (int i=0; i<10; ++i)
+ {
+ increment();
+ int* p = value.get();
+ assert(*p == i+1);
+ (void)(p);
+ }
+}
+
+int main()
+{
+ boost::thread_group threads;
+ for (int i=0; i<5; ++i)
+ threads.create_thread(&thread_proc);
+ threads.join_all();
+}
diff --git a/src/boost/libs/thread/example/user_scheduler.cpp b/src/boost/libs/thread/example/user_scheduler.cpp
new file mode 100644
index 000000000..7bb02602b
--- /dev/null
+++ b/src/boost/libs/thread/example/user_scheduler.cpp
@@ -0,0 +1,79 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// 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 <boost/config.hpp>
+
+#define BOOST_THREAD_VERSION 5
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <boost/thread/detail/log.hpp>
+#include <boost/thread/executors/loop_executor.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <string>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+void p1()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " P1" << BOOST_THREAD_END_LOG;
+}
+
+void p2()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " P2" << BOOST_THREAD_END_LOG;
+}
+
+void submit_some(boost::loop_executor& tp) {
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+ tp.submit(&p1);
+ tp.submit(&p2);
+}
+
+int main()
+{
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << " <MAIN" << BOOST_THREAD_END_LOG;
+ {
+ try
+ {
+ boost::loop_executor tp;
+ submit_some(tp);
+ tp.run_queued_closures();
+ submit_some(tp);
+ tp.run_queued_closures();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG
+ << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
+ return 1;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG
+ << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ return 2;
+ }
+ }
+
+ BOOST_THREAD_LOG
+ << boost::this_thread::get_id() << "MAIN>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/with_lock_guard.cpp b/src/boost/libs/thread/example/with_lock_guard.cpp
new file mode 100644
index 000000000..f3a4cd806
--- /dev/null
+++ b/src/boost/libs/thread/example/with_lock_guard.cpp
@@ -0,0 +1,53 @@
+// (C) Copyright 2013 Ruslan Baratov
+// Copyright (C) 2014 Vicente Botet
+//
+// 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)
+
+// See www.boost.org/libs/thread for documentation.
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream> // std::cout
+#include <boost/thread/scoped_thread.hpp>
+#include <boost/thread/with_lock_guard.hpp>
+
+boost::mutex m; // protection for 'x' and 'std::cout'
+int x;
+
+#if defined(BOOST_NO_CXX11_LAMBDAS) || (defined BOOST_MSVC && _MSC_VER < 1700)
+void print_x() {
+ ++x;
+ std::cout << "x = " << x << std::endl;
+}
+
+void job() {
+ for (int i = 0; i < 10; ++i) {
+ boost::with_lock_guard(m, print_x);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ }
+}
+#else
+void job() {
+ for (int i = 0; i < 10; ++i) {
+ boost::with_lock_guard(
+ m,
+ []() {
+ ++x;
+ std::cout << "x = " << x << std::endl;
+ }
+ );
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ }
+}
+#endif
+
+int main() {
+#if defined(BOOST_NO_CXX11_LAMBDAS) || (defined BOOST_MSVC && _MSC_VER < 1700)
+ std::cout << "(no lambdas)" << std::endl;
+#endif
+ boost::scoped_thread<> thread_1((boost::thread(job)));
+ boost::scoped_thread<> thread_2((boost::thread(job)));
+ boost::scoped_thread<> thread_3((boost::thread(job)));
+ return 0;
+}
diff --git a/src/boost/libs/thread/example/xtime.cpp b/src/boost/libs/thread/example/xtime.cpp
new file mode 100644
index 000000000..a873085b3
--- /dev/null
+++ b/src/boost/libs/thread/example/xtime.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+
+int main()
+{
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.sec += 1;
+ boost::thread::sleep(xt); // Sleep for 1 second
+}