basic wait/notify impl added, waiting-test pass
This commit is contained in:
parent
59a7270f5d
commit
36704a856e
4 changed files with 63 additions and 35 deletions
|
|
@ -53,7 +53,7 @@ namespace lumiera {
|
|||
bool
|
||||
Subsys::isRunning()
|
||||
{
|
||||
//Lock guard (*this);
|
||||
//Lock guard (this);
|
||||
return checkRunningState();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<class BF>
|
||||
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<class X>
|
||||
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<typename C>
|
||||
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<class X>
|
||||
struct ClassLock : Lock
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue