From 36704a856ee5665b4cdecd953dd9033b36692946 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 23 Dec 2008 04:27:11 +0100 Subject: [PATCH] basic wait/notify impl added, waiting-test pass --- src/common/subsys.cpp | 2 +- src/common/subsystemrunner.hpp | 11 ++--- src/lib/sync.hpp | 76 ++++++++++++++++++++++----------- tests/lib/sync-waiting-test.cpp | 9 ++-- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/src/common/subsys.cpp b/src/common/subsys.cpp index 41f2fb845..44fc9075d 100644 --- a/src/common/subsys.cpp +++ b/src/common/subsys.cpp @@ -53,7 +53,7 @@ namespace lumiera { bool Subsys::isRunning() { - //Lock guard (*this); + //Lock guard (this); return checkRunningState(); } diff --git a/src/common/subsystemrunner.hpp b/src/common/subsystemrunner.hpp index 3b565de83..da1d39360 100644 --- a/src/common/subsystemrunner.hpp +++ b/src/common/subsystemrunner.hpp @@ -87,6 +87,7 @@ namespace lumiera { * @see main.cpp */ class SubsystemRunner +// : Sync { Option& opts_; volatile bool emergency_; @@ -108,7 +109,7 @@ namespace lumiera { void maybeRun (Subsys& susy) { - //Lock guard (*this); + //Lock guard (this); if (!susy.isRunning() && susy.shouldStart (opts_)) triggerStartup (&susy); @@ -119,14 +120,14 @@ namespace lumiera { void shutdownAll () { - //Lock guard (*this); + //Lock guard (this); for_each (running_, killIt_); } bool wait () { - //Lock(*this).wait (&SubsystemRunner::allDead); + //Lock(this).wait (&SubsystemRunner::allDead); return isEmergencyExit(); } @@ -160,7 +161,7 @@ namespace lumiera { sigTerm (Subsys* susy, Error* problem) ///< called from subsystem on termination { ASSERT (susy); - //Lock guard (*this); + //Lock guard (this); triggerEmergency(problem); ERROR_IF (susy->isRunning(), lumiera, "Subsystem '%s' signals termination, " "without resetting running state", cStr(*susy)); @@ -173,7 +174,7 @@ namespace lumiera { allDead () { if (isEmergencyExit()) - ; //Lock(*this).setTimeout(EMERGENCYTIMEOUT); + ; //Lock(this).setTimeout(EMERGENCYTIMEOUT); return isnil (running_); // end wait if no running subsystem left } diff --git a/src/lib/sync.hpp b/src/lib/sync.hpp index d614c96f1..47dc591ec 100644 --- a/src/lib/sync.hpp +++ b/src/lib/sync.hpp @@ -97,7 +97,7 @@ namespace lib { lumiera_condition cond_; public: - Condition() { lumiera_condition_init (&cond_, "Obj.Monitor Condition", &NOBUG_FLAG(sync) ); } + Condition() { lumiera_condition_init (&cond_, "Obj.Monitor Condition", &NOBUG_FLAG(sync) ); } ~Condition() { lumiera_condition_destroy (&cond_, &NOBUG_FLAG(sync) ); } void @@ -109,9 +109,10 @@ namespace lib { pthread_cond_signal (&cond_.cond); } + template bool - wait (volatile BF const& predicate, RecMutex& mtx, timespec* waitEndTime=0) + wait (BF& predicate, RecMutex& mtx, timespec* waitEndTime=0) { int err=0; while (!predicate() && !err) @@ -127,6 +128,43 @@ namespace lib { } }; + + struct Monitor + { + sync::RecMutex mtx_; + sync::Condition cond_; + + Monitor() {} + ~Monitor() {} + + void acquireLock() { mtx_.acquire(); } + void releaseLock() { mtx_.release(); } + + void signal(bool a){ cond_.signal(a);} + + inline bool wait (volatile bool&, ulong); + }; + + + typedef volatile bool& Flag; + + struct BoolFlagPredicate + { + Flag flag_; + BoolFlagPredicate (Flag f) : flag_(f) {} + + bool operator() () { return flag_; } + }; + + + bool + Monitor::wait(Flag flag, ulong timeoout) + { + BoolFlagPredicate checkFlag(flag); + return cond_.wait(checkFlag, mtx_, (timespec*)0); + } + + } // namespace sync @@ -144,17 +182,7 @@ namespace lib { */ struct Sync { - struct Monitor - { - sync::RecMutex mtx_; - sync::Condition cond_; - - Monitor() {} - ~Monitor() {} - - void acquireLock() { mtx_.acquire(); } - void releaseLock() { mtx_.release(); } - }; + typedef sync::Monitor Monitor; Monitor objectMonitor_; @@ -169,24 +197,22 @@ namespace lib { class Lock { Monitor& mon_; + public: template - Lock(X* it) : mon_(getMonitor(it)) - { - mon_.acquireLock(); - } + Lock(X* it) : mon_(getMonitor(it)){ mon_.acquireLock(); } + Lock(Monitor& m) : mon_(m) { mon_.acquireLock(); } + ~Lock() { mon_.releaseLock(); } - Lock(Monitor& m) : mon_(m) - { - mon_.acquireLock(); - } + template + bool wait (C& cond, ulong time=0) { return mon_.wait(cond,time);} + + void notifyAll() { mon_.signal(true); } + void notify() { mon_.signal(false);} - ~Lock() - { - mon_.releaseLock(); - } }; + template struct ClassLock : Lock { diff --git a/tests/lib/sync-waiting-test.cpp b/tests/lib/sync-waiting-test.cpp index 5a0a69a04..3bc087258 100644 --- a/tests/lib/sync-waiting-test.cpp +++ b/tests/lib/sync-waiting-test.cpp @@ -65,7 +65,8 @@ namespace lib { class SyncOnBool - : public Token + : public Token, + public Sync { bool got_new_data_; @@ -74,16 +75,16 @@ namespace lib { void getIt() { - //Lock(*this).wait (got_new_data_); + Lock(this).wait (got_new_data_); sum_ += input_; } void provide (uint val) { - //Lock sync(*this); + Lock sync(this); input_ = val; got_new_data_ = true; - //sync.notifyAll(); + sync.notifyAll(); } };