basic wait/notify impl added, waiting-test pass

This commit is contained in:
Fischlurch 2008-12-23 04:27:11 +01:00
parent 59a7270f5d
commit 36704a856e
4 changed files with 63 additions and 35 deletions

View file

@ -53,7 +53,7 @@ namespace lumiera {
bool
Subsys::isRunning()
{
//Lock guard (*this);
//Lock guard (this);
return checkRunningState();
}

View file

@ -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
}

View file

@ -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
{

View file

@ -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();
}
};