|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r51161 - sandbox/synchro/libs/synchro/example
From: vicente.botet_at_[hidden]
Date: 2009-02-09 17:50:41
Author: viboes
Date: 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
New Revision: 51161
URL: http://svn.boost.org/trac/boost/changeset/51161
Log:
Boost.Synchro V0.0.0
Added:
sandbox/synchro/libs/synchro/example/Accumulator.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/BankAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/EL_BancAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/Factorial.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/Histogram.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/HotelReservation.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/IEL_Rec_Lockable_BancAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/IL_BancAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/IL_Lockable_BancAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/IL_Rec_Lockable_BancAccount.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/Master_Slave.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/QualifiedSingleBuf.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/SingleBuf.cpp (contents, props changed)
sandbox/synchro/libs/synchro/example/TrafficLight.cpp (contents, props changed)
Added: sandbox/synchro/libs/synchro/example/Accumulator.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/Accumulator.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,61 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/coroutine/coroutine.hpp"
+
+namespace coro=boost::coroutines;
+
+template <class Derived, typename Signature,
+typename ContextImpl = detail::default_context_impl>
+class coroutine_obj;
+
+template <class Derived, typename Res, typename Param1, typename ContextImpl>
+class coroutine_obj<Derived, Res(Param1), ContextImpl> {
+ typedef coro::coroutine<Res(Param1), ContextImpl> coroutine_type;
+ coroutine_type couroutine_;
+public:
+ coroutine_obj() : couroutine_(Derived::body_) {}
+ Res operator()(Param1 val) {
+ return couroutine_(val);
+ }
+};
+template <class Derived, typename ContextImpl>
+class coroutine_obj<Derived, void(), ContextImpl> {
+ typedef coro::coroutine<void()> coroutine_type;
+ coroutine_type couroutine_;
+public:
+ coroutine_obj() : couroutine_(Derived::body_) {}
+ void operator()() {
+ couroutine_();
+ }
+};
+
+//[Acumulator
+class Acumulator : public coroutine_obj<Acumulator, int(int)> {
+ typedef coroutine_obj<Acumulator, int(int)> super_type;
+ friend class super_type;
+ static int body(coroutine_type::self& this_coroutine, int val) {
+ while(true) {
+ val += this_coroutine.yield(val);
+ }
+ }
+};
+
+//]
+
+int main()
+{
+ Acumulator accumulator;
+ for(int i = 0; i < 1000; ++i)
+ std::cout << accumulator(i);
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/BankAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/BankAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,126 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/monitor.hpp"
+#include "boost/thread.hpp"
+#include <iostream>
+
+using namespace boost::synchro;
+using namespace boost;
+
+/*<< Note that BanckAcount is not a Lockable outside the BankAccount hierarchy >>*/
+
+//[BankAccount
+class BankAccount : protected exclusive_monitor<>
+{
+protected:
+ int balance_;
+public:
+ BankAccount() : balance_(0) {}
+ BankAccount(const BankAccount &rhs) {
+ synchronizer _(*rhs.mutex());
+ balance_=rhs.balance_;
+ }
+
+ BankAccount& operator=(BankAccount &rhs)
+ {
+ if(&rhs == this) return *this;
+
+ int balance=0;
+ {
+ synchronizer _(*rhs.mutex());
+ balance=rhs.balance_;
+ }
+ synchronizer _(*this.mutex());
+ balance_=balance;
+ return *this;
+ }
+#if 0
+ BankAccount& operator=(BankAccount &rhs)
+ {
+ if(&rhs == this) return *this;
+ int balance=0;
+ synchronize (*rhs.mutex()) balance=rhs.balance_;
+ synchronize (*this.mutex()) balance_=balance;
+ return *this;
+ }
+#endif
+
+ void Deposit(int amount) {
+ synchronizer _(*this->mutex());
+ balance_ += amount;
+ }
+ int Withdraw(int amount) {
+ synchronizer _(*this->mutex());
+ balance_ -= amount;
+ return amount;
+ }
+ int GetBalance() {
+ synchronizer _(*this->mutex());
+ return balance_;
+ }
+};
+//]
+
+#if 0
+//[BankAccount_raii
+class BankAccount {
+ boost::mutex mtx_; /*< explicit mutex declaration >*/
+ int balance_;
+public:
+ void Deposit(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ += amount;
+ }
+ int Withdraw(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ -= amount;
+ return amount
+ }
+ int GetBalance() {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ return balance_;
+ }
+};
+//]
+#endif
+
+//[BankAccount_ussage
+class BankAccount;
+
+BankAccount JoesAccount;
+
+void bankAgent()
+{
+ for (int i =10; i>0; --i) {
+ //...
+ JoesAccount.Deposit(500);
+ //...
+ }
+}
+
+void Joe() {
+ for (int i =10; i>0; --i) {
+ //...
+ int myPocket = JoesAccount.Withdraw(100);
+ std::cout << myPocket << std::endl;
+ //...
+ }
+}
+
+int main() {
+ //...
+ boost::thread thread1(bankAgent); // start concurrent execution of bankAgent
+ boost::thread thread2(Joe); // start concurrent execution of Joe
+ thread1.join();
+ thread2.join();
+ return 0;
+}
+//]
Added: sandbox/synchro/libs/synchro/example/EL_BancAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/EL_BancAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,103 @@
+#include <boost/synchro/make_lockable.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/synchro/thread/locks.hpp>
+#include <boost/synchro/lockers/strict_locker.hpp>
+#include <boost/synchro/lockers/externally_locked.hpp>
+
+
+using namespace boost::synchro;
+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 make_exclusive_lockable<boost::mutex>
+{
+public:
+ typedef make_exclusive_lockable<boost::mutex> lockable_base_type;
+ AccountManager()
+ : checkingAcct_(*this)
+ , savingsAcct_(*this)
+ {}
+ void Checking2Savings(int amount);
+ void AccountManager::AMoreComplicatedChecking2Savings(int amount);
+private:
+ /*<-*/ bool some_condition() { return true; } /*->*/
+ externally_locked_any<BankAccount, AccountManager> checkingAcct_;
+ externally_locked_any<BankAccount, AccountManager> savingsAcct_;
+};
+//]
+
+//[Checking2Savings
+void AccountManager::Checking2Savings(int amount) {
+ strict_locker<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_locker<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_locker<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;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/Factorial.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/Factorial.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/alt/alternating_component.hpp"
+
+using namespace boost::alt;
+using namespace boost;
+
+//[TrafficLight
+class factorial {
+ unsigned value[100];
+ unsigned top_
+ unsigned operator()(unsigned n) {
+ T[0]=top_=0;
+ for(;;) {
+ if (top_<n) {
+ for (i=top_+1; i<=n; ++i) {
+ value_[i]=value_[i-1]*i
+ }
+ top_ = n;
+ }
+ ++n;
+ alternating_component::yield(value_[n-1]);
+ }
+ }
+};
+
+class Controller {
+ alternating_component<TrafficLight> north, south;
+public:
+ Controller( alternating_component<TrafficLight> north, south)
+ void operator()() {
+ north.resume(); // north.state_==red
+ south.resume();
+ south.resume(); // south.state_==green
+ for(;;) {
+ // wait some time
+ sleep(2);
+ // switch the states
+ south.resume();
+ north.resume();
+ }
+ }
+};
+
+//]
+
+int main()
+{
+ alternating_component<TrafficLight> north, south;
+ alternating_component<Controller> controler(north, south); // Declaration of a singular component
+ controler.start();
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/Histogram.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/Histogram.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,125 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/conc/concurrent_component.hpp"
+#include "boost/synchro/monitor.hpp"
+#include "boost/synchro/thread/mutex.hpp"
+#include "boost/thread.hpp"
+#include "boost/ref.hpp"
+#include "boost/synchro/conc/conc_tuple.hpp"
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::synchro;
+using namespace boost;
+
+
+//[Histogram
+class Histogram : boost::synchro::concurrent_component {
+
+ class HistogramData : public exclusive_monitor<> {
+ unsigned R[100];
+ public:
+ HistogramData() {
+ for (int i = 0; i<100; i++) R[i] = 0;
+ }
+ void Add(unsigned i) {
+ synchronizer _(*this->mutex());
+ R[i]+=1;
+ }
+ void Sub(unsigned i) {
+ synchronizer _(*this->mutex());
+ R[i]=(R[i]>0)?R[i]-1:0;
+ }
+ unsigned Get(unsigned i) {
+ synchronizer _(*this->mutex());
+ return R[i];
+ }
+ };
+ class Display : boost::synchro::concurrent_component {
+ HistogramData& histogramData_;
+ public:
+ Display(HistogramData& histogramData) : histogramData_(histogramData) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ for (unsigned i =0; i<100; ++i) {
+ std::cout << "==(" << i << ", "
+ << histogramData_.Get(i) << ")"
+ << std::endl;
+ }
+ }
+ }
+ };
+ class Update : boost::synchro::concurrent_component {
+ Histogram::port& request_;
+ public:
+ Update(Histogram::port& req) : request_(req) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ accept(request_);
+ }
+ }
+ };
+ port request_;
+ HistogramData histogramData_;
+// friend class Update;
+ Display disp_;
+ Update updater_;
+public:
+ Histogram()
+ : disp_(histogramData_)
+ , updater_(request_)
+ {}
+ void NewValue(int V) {
+ port::synchronizer _(request_);
+ if (V>0) histogramData_.Add(V);
+ else histogramData_.Sub(-V);
+ }
+ void operator()() {
+ conc_tuple<Display,Update> conc_(disp_, updater_);
+ conc_();
+ conc_.join();
+ }
+};
+//]
+class S : boost::synchro::concurrent_component {
+ Histogram& histogram_;
+public:
+ S(Histogram& histogram) : histogram_(histogram) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ // TODO replace by random
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ histogram_.NewValue(i);
+
+ }
+ }
+};
+
+int main()
+{
+ Histogram histo;
+ S snd(histo);
+ conc_tuple<Histogram, S> conc(histo, snd);
+ conc();
+ boost::this_thread::sleep(boost::posix_time::seconds(10));
+
+ conc.join();
+
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/HotelReservation.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/HotelReservation.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,181 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/conc/concurrent_component.hpp"
+#include "boost/synchro/thread/mutex.hpp"
+#include "boost/thread.hpp"
+#include "boost/ref.hpp"
+#include <string>
+#include "boost/synchro/conc/conc_tuple.hpp"
+#include "boost/test/unit_test.hpp"
+
+
+#define ABOOST_TEST_MESSAGE(MSG) std::cout << MSG << std::endl
+#define ABOOST_TEST_CHECKPOINT(MSG) std::cout << MSG << std::endl
+
+using namespace boost::synchro;
+using namespace boost;
+
+//namespace {
+// volatile int Run = 1;
+//}
+
+//[ReservationHandler
+class ReservationHandler : public boost::synchro::concurrent_component
+{
+protected:
+ port start_;
+ object_port request_;
+ const concurrent_component_base* sender_;
+ bool closed_;
+ bool end_;
+public:
+ ReservationHandler() : sender_(0), closed_(true), end_(false) {}
+ void Lock(const concurrent_component_base* snd) {
+ ABOOST_TEST_CHECKPOINT("Lock");
+ port::synchronizer _(start_);
+ sender_ = snd;
+ closed_ =false;
+ }
+ void Interrupt() {
+ ABOOST_TEST_CHECKPOINT("Interrupt");
+ port::synchronizer _(start_);
+ end_ =true;
+ }
+// void Reserve(const concurrent_component_base& snd) {
+// object_port::synchronizer _(request_, snd);
+// Reserv();
+// }
+// virtual void Reserve()=0;
+
+ void Close(const concurrent_component_base* snd) {
+ ABOOST_TEST_CHECKPOINT("Close");
+ object_port::synchronizer _(request_, snd);
+ closed_ =true;
+ sender_ = 0;
+ DoClose();
+ }
+ virtual void DoClose() {};
+ void operator()() {
+ while (!end_) {
+ accept(start_);
+ if (end_) break;
+ while (!closed_) {
+ accept(request_, sender_);
+ }
+ }
+ }
+// ReservationHandler()
+// : closed_(false)
+// {}
+ virtual ~ReservationHandler() {};
+};
+//]
+
+//[HotelResHandler
+class HotelResHandler : public ReservationHandler
+{
+ unsigned roomNo;
+public:
+ unsigned Reserve(const concurrent_component_base* snd
+ , std::string guestName
+ , unsigned noOfPersons) {
+ ABOOST_TEST_CHECKPOINT("Reserve");
+ object_port::synchronizer _(request_, snd);
+ // ...
+ ++roomNo;
+ ABOOST_TEST_CHECKPOINT(roomNo<<":"<<guestName<<" #"<<noOfPersons);
+ return roomNo;
+ }
+ virtual void DoClose(){};
+ virtual ~HotelResHandler() {};
+};
+//]
+
+//[HotelResHandler_P
+class P : public boost::synchro::concurrent_component {
+public:
+ HotelResHandler& hrh_;
+ P(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ hrh_.Lock(this);
+ unsigned rno1 = hrh_.Reserve(this, std::string("Peter Olsen"),4);
+ ABOOST_TEST_CHECKPOINT(rno1);
+ unsigned rno2 = hrh_.Reserve(this, std::string("Anne Nielsen"),2);
+ ABOOST_TEST_CHECKPOINT(rno2);
+ hrh_.Close(this);
+ }
+};
+//]
+
+//[HotelResHandler_Q
+class Q : public boost::synchro::concurrent_component {
+public:
+ HotelResHandler& hrh_;
+ Q(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ hrh_.Lock(this);
+ unsigned rno1 = hrh_.Reserve(this, std::string("Carmen"),5);
+ ABOOST_TEST_CHECKPOINT(rno1);
+ unsigned rno2 = hrh_.Reserve(this, std::string("Javier"),1);
+ ABOOST_TEST_CHECKPOINT(rno2);
+ hrh_.Close(this);
+ }
+};
+//]
+
+class R : public boost::synchro::concurrent_component {
+public:
+ HotelResHandler& hrh_;
+ R(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ try {
+ unsigned rno1 = hrh_.Reserve(this, std::string("Carmen"),5);
+ }catch (bad_sender& exp) {
+ ABOOST_TEST_MESSAGE("You need to Lock first");
+ }catch (...) {
+ std::cout << "... You need to Lock first" << std::endl;
+ }
+ }
+};
+//]
+
+//[HotelResHandler_main
+int main() {
+ HotelResHandler hrh;
+ P p(hrh);
+ Q q(hrh);
+ R r(hrh);
+#if 1
+ conc_tuple<HotelResHandler, P, Q, R> conc(hrh, p, q, r);
+ conc();
+
+ boost::this_thread::sleep(boost::posix_time::seconds(4));
+
+ hrh.Interrupt();
+ conc.join();
+#else
+ boost::thread thread1(boost::ref(hrh));
+ boost::thread thread2(boost::ref(p));
+ boost::thread thread3(boost::ref(q));
+ boost::thread thread4(boost::ref(r));
+
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ hrh.Interrupt();
+
+ thread2.join();
+ thread3.join();
+ thread4.join();
+ thread1.join();
+#endif
+ return 0;
+}
+//]
+
Added: sandbox/synchro/libs/synchro/example/IEL_Rec_Lockable_BancAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/IEL_Rec_Lockable_BancAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,76 @@
+#include <boost/synchro/make_lockable.hpp>
+#include <boost/synchro/thread/recursive_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/synchro/lockers/strict_locker.hpp>
+
+using namespace boost::synchro;
+using namespace boost;
+
+class BankAccount_TN {
+ int balance_;
+public:
+ void Deposit(int amount) {
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ balance_ -= amount;
+ }
+ int GetBalance() {
+ return balance_;
+ }
+};
+
+class BankAccount
+: protected BankAccount_TN
+, public make_exclusive_lockable<boost::recursive_mutex>
+{
+// int balance_;
+ void throw_if_not_owned(strict_locker<BankAccount>&locker) {
+ if (locker.mutex() != this)
+ throw "Locking Error: Wrong Object Locked";
+ }
+
+public:
+ typedef make_exclusive_lockable<boost::recursive_mutex> lockable_base_type;
+ void Deposit(int amount) {
+ lock_guard<BankAccount> guard(*this);
+// lock_guard<boost::recursive_mutex> guard(*this->mutex());
+ BankAccount_TN::Deposit(amount);
+ }
+ void Deposit(int amount, strict_locker<BankAccount>&locker) {
+ throw_if_not_owned(locker);
+ BankAccount_TN::Deposit(amount);
+ }
+ void Withdraw(int amount) {
+ lock_guard<BankAccount> guard(*this);
+// lock_guard<boost::recursive_mutex> guard(*this->mutex());
+ BankAccount_TN::Withdraw(amount);
+ }
+ void Withdraw(int amount, strict_locker<BankAccount>&locker) {
+ throw_if_not_owned(locker);
+ BankAccount_TN::Withdraw(amount);
+ }
+ int GetBalance() {
+ lock_guard<BankAccount> guard(*this);
+// lock_guard<boost::recursive_mutex> guard(*this->mutex());
+ return BankAccount_TN::GetBalance();
+ }
+ int GetBalance(strict_locker<BankAccount>&locker) {
+ throw_if_not_owned(locker);
+ return BankAccount_TN::GetBalance();
+ }
+};
+
+void ATMWithdrawal(BankAccount& acct, int sum) {
+ strict_locker<BankAccount> guard(acct);
+ acct.Withdraw(sum, guard);
+ acct.Withdraw(2, guard);
+}
+
+int main() {
+ BankAccount acct;
+ ATMWithdrawal(acct, 100);
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/IL_BancAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/IL_BancAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,70 @@
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+#if IL_BankAccount_BankAccount_mutex
+//[IL_BankAccount_BankAccount_mutex
+class BankAccount {
+ boost::mutex mtx_;
+ int balance_;
+public:
+ void Deposit(int amount) {
+ mtx_.lock();
+ balance_ += amount;
+ mtx_.unlock();
+ }
+ void Withdraw(int amount) {
+ mtx_.lock();
+ balance_ -= amount;
+ mtx_.unlock();
+ }
+ int GetBalance() {
+ mtx_.lock();
+ int b = balance_;
+ mtx_.unlock();
+ return balance_;
+ }
+};
+//]
+#endif
+//[IL_BankAccount_BankAccount
+class BankAccount {
+ boost::mutex mtx_; /*< explicit mutex declaration >*/
+ int balance_;
+public:
+ void Deposit(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ -= amount;
+ }
+ int GetBalance() {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ return balance_;
+ }
+};
+//]
+#ifndef BOOST_SYNCHRO_DO_NOT_COMPILE
+//[IL_BankAccount_ATMWithdrawal
+void ATMWithdrawal(BankAccount& acct, int sum) {
+ acct.Withdraw(sum);
+ /*<preemption possible>*/
+ acct.Withdraw(2);
+}
+//]
+#else
+//[IL_BankAccount_ATMWithdrawal_do_not_compile
+void ATMWithdrawal(BankAccount& acct, int sum) {
+ boost::lock_guard<boost::mutex> guard(acct.mtx_); /*<mtx_ field is private>*/
+ acct.Withdraw(sum);
+ acct.Withdraw(2);
+//]
+#endif
+
+int main() {
+ BankAccount acct;
+ ATMWithdrawal(acct, 100);
+ return 0;
+}
+
Added: sandbox/synchro/libs/synchro/example/IL_Lockable_BancAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/IL_Lockable_BancAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,68 @@
+#include <boost/synchro/make_lockable.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+
+using namespace boost::synchro;
+#if 0
+//[IL_Lockable_BancAccount_BankAccount_explicit
+class BankAccount {
+ boost::mutex mtx_;
+ int balance_;
+public:
+ void Deposit(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ boost::lock_guard<boost::mutex> guard(mtx_);
+ balance_ -= amount;
+ }
+ void lock() {
+ mtx_.lock();
+ }
+ void unlock() {
+ mtx_.unlock();
+ }
+};
+//]
+#else
+//[IL_Lockable_BancAccount_BankAccount_inherit
+class BankAccount
+: public make_exclusive_lockable<boost::mutex>
+{
+ int balance_;
+public:
+ void Deposit(int amount) {
+ boost::lock_guard<BankAccount> guard(*this);
+// boost::lock_guard<boost::mutex> guard(*this->mutex());
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ boost::lock_guard<BankAccount> guard(*this);
+// boost::lock_guard<boost::mutex> guard(*this->mutex());
+ balance_ -= amount;
+ }
+ int GetBalance() {
+ boost::lock_guard<BankAccount> guard(*this);
+// boost::lock_guard<boost::mutex> guard(*this->mutex());
+ return balance_;
+ }
+};
+//]
+#endif
+//[IL_Lockable_BancAccount_ATMWithdrawal
+void ATMWithdrawal(BankAccount& acct, int sum) {
+// boost::lock_guard<boost::mutex> guard(*acct.mutex());
+ boost::lock_guard<BankAccount> guard(acct);
+ acct.Withdraw(sum);
+ acct.Withdraw(2);
+}
+//]
+
+int main() {
+ BankAccount acct;
+ ATMWithdrawal(acct, 100);
+ return 0;
+}
+
Added: sandbox/synchro/libs/synchro/example/IL_Rec_Lockable_BancAccount.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/IL_Rec_Lockable_BancAccount.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,43 @@
+#include <boost/synchro/make_lockable.hpp>
+#include <boost/synchro/thread/recursive_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+using namespace boost::synchro;
+using namespace boost;
+//[IL_Rec_Lockable_BancAccount_BankAccount
+class BankAccount
+: public make_exclusive_lockable<boost::recursive_mutex>
+{
+/*<-*/
+ int balance_;
+public:
+ void Deposit(int amount) {
+ lock_guard<BankAccount> guard(*this);
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ lock_guard<BankAccount> guard(*this);
+ balance_ -= amount;
+ }
+ int GetBalance() {
+ lock_guard<BankAccount> guard(*this);
+ return balance_;
+ }
+/*->*/
+ // ...
+};
+//]
+
+void ATMWithdrawal(BankAccount& acct, int sum) {
+ lock_guard<BankAccount> guard(acct);
+ acct.Withdraw(sum);
+ acct.Withdraw(2);
+}
+
+int main() {
+ BankAccount acct;
+ ATMWithdrawal(acct, 100);
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/Master_Slave.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/Master_Slave.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,116 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/conc/concurrent_component.hpp"
+#include "boost/synchro/thread/mutex.hpp"
+#include "boost/thread.hpp"
+#include "boost/ref.hpp"
+#include "boost/synchro/conc/conc_tuple.hpp"
+
+using namespace boost::synchro;
+using namespace boost;
+
+
+
+namespace {
+}
+
+//[Master_Slave_Slave
+class Slave : boost::synchro::concurrent_component
+{
+ port receive_;
+ unsigned sum_;
+ bool End;
+public:
+ Slave() : End(false) {}
+ void Clear() {
+// std::cout << "Clear()" << std::endl;
+ port::synchronizer _(receive_);
+ sum_ = 0;
+ }
+ void Add(unsigned v) {
+// std::cout << "Add(" << v << ")" << std::endl;
+ port::synchronizer _(receive_);
+ sum_+=v;
+ }
+ unsigned Result() {
+ port::synchronizer _(receive_);
+// std::cout << sum_ << "=Result()" << std::endl;
+ return sum_;
+ }
+ void Interrupt() {
+// std::cout << "Interrupt()" << std::endl;
+ port::synchronizer _(receive_);
+ End=true;
+ }
+ void operator()() {
+ while (!End) {
+// std::cout << "accept()" << std::endl;
+ accept(receive_);
+ }
+ }
+};
+//]
+//[Master_Slave_Master
+struct Master : boost::synchro::concurrent_component {
+ Slave& Slave1_;
+ Slave& Slave2_;
+
+ int V[100];
+ Master(Slave& slave1, Slave& slave2)
+ : Slave1_(slave1)
+ , Slave2_(slave2)
+ {}
+ void operator()()
+ {
+ for (int i=0; i<100; i++) {
+ V[i]=i;
+ }
+// std::cout << "before clear" << std::endl;
+ Slave1_.Clear();
+ Slave2_.Clear();
+// std::cout << "cleared" << std::endl;
+
+ for (int i=0; i<100; i++) {
+ if ((V[i]%2) > 0) Slave1_.Add(V[i]);
+ else Slave2_.Add(V[i]);
+ }
+ std::cout << Slave1_.Result() << std::endl;
+ std::cout << Slave2_.Result() << std::endl;
+ Slave1_.Interrupt();
+ Slave2_.Interrupt();
+ }
+};
+//]
+
+int main()
+{
+
+ std::cout << "BEGIN" << std::endl;
+ Slave slave1;
+ Slave slave2;
+ Master master(slave1, slave2);
+#if 1
+ conc_tuple<Slave, Slave, Master> conc(slave1, slave2, master);
+ conc();
+ conc.join();
+#else
+ boost::thread thread1(boost::ref(slave1));
+ boost::thread thread2(boost::ref(slave2));
+ boost::thread thread3(boost::ref(master));
+ std::cout << "wait" << std::endl;
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+#endif
+ return 0;
+}
+
Added: sandbox/synchro/libs/synchro/example/QualifiedSingleBuf.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/QualifiedSingleBuf.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/conc/concurrent_component.hpp"
+#include "boost/synchro/thread/mutex.hpp"
+#include "boost/thread.hpp"
+#include "boost/ref.hpp"
+#include "boost/synchro/conc/conc_tuple.hpp"
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::synchro;
+using namespace boost;
+
+struct Producer;
+struct Consumer;
+
+//[QualifiedSingleBuf
+class SingleBuf : boost::synchro::concurrent_component {
+ qualified_port<Producer> PutPort_;
+ qualified_port<Consumer> GetPort_;
+// const concurrent_component_base* sender_;
+ char bufCh_;
+public:
+ void Put(const Producer* snd, char ch) {
+ qualified_port<Producer>::synchronizer _(PutPort_, snd);
+ bufCh_ = ch;
+ }
+ char Get(const Consumer* snd) {
+ qualified_port<Consumer>::synchronizer _(GetPort_, snd);
+ return bufCh_;
+ }
+ void operator()() {
+ while (Run) {
+ accept(PutPort_);
+ if (!Run) break;
+ accept(GetPort_);
+ }
+ }
+};
+//]
+struct Producer : boost::synchro::concurrent_component {
+ SingleBuf& buf_;
+ Producer(SingleBuf& buf) : buf_(buf) {}
+ void operator()()
+ {
+ char ch=32;
+ while (Run) {
+ ch+=1;
+ if (ch > 65) ch = 32;
+ buf_.Put(this, ch);
+ }
+ }
+};
+struct Consumer : boost::synchro::concurrent_component {
+ SingleBuf& buf_;
+ Consumer(SingleBuf& buf) : buf_(buf) {}
+ void operator()() {
+ while (Run) {
+ char ch = buf_.Get(this);
+ std::cout << ch << std::endl;
+ }
+ }
+};
+
+int main()
+{
+ std::cout << "press <enter> to end the program" << std::endl;
+
+ SingleBuf buf;
+ Producer prod(buf);
+ Consumer cons(buf);
+ conc_tuple<SingleBuf, Producer, Consumer> conc(buf, prod, cons);
+ conc();
+
+ std::cin.get();
+ Run = 0;
+ conc.join();
+
+ return 0;
+}
+
+
Added: sandbox/synchro/libs/synchro/example/SingleBuf.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/SingleBuf.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/conc/concurrent_component.hpp"
+#include "boost/synchro/thread/mutex.hpp"
+#include "boost/thread.hpp"
+#include "boost/ref.hpp"
+#include "boost/synchro/conc/conc_tuple.hpp"
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::synchro;
+using namespace boost;
+
+//[SingleBuf
+class SingleBuf : boost::synchro::concurrent_component {
+ port PutPort_,GetPort_;
+ char bufCh_;
+ bool End;
+public:
+ SingleBuf() : End(false) {}
+ void Put(char ch) {
+ port::synchronizer _(PutPort_);
+// std::cout << "void Put("<<ch<<")" << std::endl;
+ bufCh_ = ch;
+ }
+ char Get() {
+ port::synchronizer _(GetPort_);
+// std::cout << bufCh_<<"=Get()" << std::endl;
+ return bufCh_;
+ }
+ void Interrupt() {
+ port::synchronizer _(PutPort_);
+// std::cout << "Interrupt()" << std::endl;
+ End=true;
+ }
+ void operator()() {
+ while (!End) {
+// std::cout << "port::accept(PutPort_)"<<std::endl;
+ accept(PutPort_);
+ if (End) break;
+// std::cout << "port::accept(GetPort_)"<<std::endl;
+ accept(GetPort_);
+ }
+ }
+};
+struct Producer : boost::synchro::concurrent_component{
+ SingleBuf& buf_;
+ Producer(SingleBuf& buf) : buf_(buf) {}
+ void operator()()
+ {
+ buf_.Put('h');
+ buf_.Put('e');
+ buf_.Put('l');
+ buf_.Put('l');
+ buf_.Put('o');
+ buf_.Put(' ');
+ buf_.Put('w');
+ buf_.Put('o');
+ buf_.Put('r');
+ buf_.Put('l');
+ buf_.Put('d');
+ buf_.Put('!');
+ buf_.Put('\n');
+ }
+};
+struct Consumer : boost::synchro::concurrent_component{
+ SingleBuf& buf_;
+ Consumer(SingleBuf& buf) : buf_(buf) {}
+ void operator()() {
+ for (;;) {
+// std::cout << "wait " << std::endl;
+ char ch = buf_.Get();
+ std::cout << ch;
+ if (ch=='\n') break;
+ }
+ }
+};
+//]
+
+int main()
+{
+// std::cout << "press <enter> to end the program" << std::endl;
+
+ SingleBuf buf;
+ Producer prod(buf);
+ Consumer cons(buf);
+ conc_tuple<SingleBuf, Producer, Consumer> conc(buf, prod, cons);
+ conc();
+
+ boost::this_thread::sleep(boost::posix_time::seconds(3));
+ buf.Interrupt();
+
+ conc.join();
+ return 0;
+}
+
Added: sandbox/synchro/libs/synchro/example/TrafficLight.cpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/libs/synchro/example/TrafficLight.cpp 2009-02-09 17:50:39 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,132 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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 http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/synchro/alt/alternating_component.hpp"
+
+using namespace boost::alt;
+using namespace boost;
+
+namespace color {
+ enum type {red, green};
+}
+
+//[TrafficLight
+# if 0
+class TrafficLight : public coroutine_obj<TrafficLight, void(void)> {
+ typedef coroutine_obj<TrafficLight, void(void)> super_type;
+ friend class super_type;
+ static void body(coroutine_type::self& this_coroutine) {
+ for(;;) {
+ state_ = color::red;
+ this_coroutine.yield();
+ state_ = color::green;
+ this_coroutine.yield();
+ }
+ }
+ color::type state_;
+public:
+ TrafficLight() : state_(color::red) {}
+};
+
+class Controller {
+ TrafficLight north_, south_;
+ operator() body() {
+ north_(); // north.state_==red
+ south_();
+ south_(); // south.state_==green
+ for(;;) {
+ // wait some time
+ sleep(2);
+ // switch the states
+ south_();
+ north_();
+ }
+ }
+public:
+ Controller(TrafficLight& north, TrafficLight& south);
+};
+#endif
+typedef coro::coroutine<void()> TrafficLight;
+
+void TrafficLightBody(TrafficLight::self& this_coroutine) {
+ color::type state_=color::red;
+ for(;;) {
+ state_ = color::red;
+ this_coroutine.yield();
+ state_ = color::green;
+ this_coroutine.yield();
+ }
+}
+
+void Controller(TrafficLight north_, TrafficLight south_) {
+ north_(); // north.state_==red
+ south_();
+ south_(); // south.state_==green
+ for(;;) {
+ // wait some time
+ sleep(2);
+ // switch the states
+ south_();
+ north_();
+ }
+}
+
+int main()
+{
+ TrafficLight north(TrafficLightBody);
+ TrafficLight south(TrafficLightBody);
+ Controller controler(north, south); // Declaration of a singular component
+ return 0;
+}
+
+
+class TrafficLight {
+ color::type state_;
+public:
+ TrafficLight() : state_(color::red) {}
+ void operator()() {
+ for(;;) {
+ state_ = color::red;
+ alternating_component::suspend();
+ state_ = color::green;
+ alternating_component::suspend();
+ }
+ }
+};
+
+class Controller {
+ alternating_component<TrafficLight> north, south;
+public:
+ Controller( alternating_component<TrafficLight> north, alternating_component<TrafficLight> south)
+ void operator()() {
+ north.resume(); // north.state_==red
+ south.resume();
+ south.resume(); // south.state_==green
+ for(;;) {
+ // wait some time
+ sleep(2);
+ // switch the states
+ south.resume();
+ north.resume();
+ }
+ }
+};
+
+//]
+
+int main()
+{
+ alternating_component<TrafficLight> north, south;
+ alternating_component<Controller> controler(north, south); // Declaration of a singular component
+ controler.start();
+ return 0;
+}
+
+
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk