From c4df935113c33f00394065c833f3e65d3a9cae36 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 15 Dec 2008 06:18:38 +0100 Subject: [PATCH] add draft impl for Monitor storage; dummy impl running todo: actually do any locking, improve handling of the forThis parameter --- src/lib/concurrency.hpp | 50 +++++++++++++++++++---- tests/common/concurrency-locking-test.cpp | 3 +- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/lib/concurrency.hpp b/src/lib/concurrency.hpp index e00f1bd5d..369afa01a 100644 --- a/src/lib/concurrency.hpp +++ b/src/lib/concurrency.hpp @@ -40,8 +40,15 @@ #include "include/nobugcfg.h" #include "lib/util.hpp" +#include + +#include ///////////////////////////TODO +using std::cerr; + namespace lib { + + using boost::scoped_ptr; /** * Facility for monitor object based locking. @@ -58,20 +65,38 @@ namespace lib { { struct Monitor { - void acquireLock() { TODO ("acquire Thread Lock"); } - void releaseLock() { TODO ("release Thread Lock"); } + Monitor() { TODO ("maybe create mutex struct here?"); } + ~Monitor() { TODO ("destroy mutex, assert it isn't locked!"); } /////TODO: Probably need to unlock it silently in case of a class-level monitor? + + void acquireLock() { cerr << "acquire Thread Lock\n"; } + void releaseLock() { cerr << "release Thread Lock\n"; } }; + Monitor objectMonitor_; + + /////////////////////////////////////////////////////////////////////////TODO: any better idea for where to put the template parameter? so we can get rid of it for the typical usage scenario? + /////////////////////////////////////////////////////////////////////////TODO: better solution for the storage? Implement the per-this locking without subclassing! + /////////////////////////////////////////////////////////////////////////TODO: factor out the recursive/non-recursive mutex case as policy... + template - static Monitor& getMonitor(X* forThis); + static inline Monitor& getMonitor(); + + static inline Monitor& getMonitor(Concurrency* forThis); + template class Lock { Monitor& mon_; public: - Lock(X* it=0) - : mon_(getMonitor (it)) + Lock(X* it) + : mon_(getMonitor(it)) + { + mon_.acquireLock(); + } + + Lock() + : mon_(getMonitor()) { mon_.acquireLock(); } @@ -85,11 +110,22 @@ namespace lib { + Concurrency::Monitor& + Concurrency::getMonitor(Concurrency* forThis) + { + REQUIRE (forThis); + return forThis->objectMonitor_; + } + template Concurrency::Monitor& - Concurrency::getMonitor(X* forThis) + Concurrency::getMonitor() { - UNIMPLEMENTED ("get moni"); + //TODO: guard this by a Mutex? consider double checked locking? (but then class Monitor needs to be volatile, thus is it worth the effort?) + + static scoped_ptr classMonitor_ (0); + if (!classMonitor_) classMonitor_.reset (new Monitor ()); + return *classMonitor_; } diff --git a/tests/common/concurrency-locking-test.cpp b/tests/common/concurrency-locking-test.cpp index 7729e4dc4..e3b0bbbe6 100644 --- a/tests/common/concurrency-locking-test.cpp +++ b/tests/common/concurrency-locking-test.cpp @@ -55,7 +55,7 @@ namespace lib { class Victim - : Concurrency + : public Concurrency { volatile long cnt_[NUM_COUNTERS]; volatile uint step_; ///< @note stored as instance variable @@ -64,6 +64,7 @@ namespace lib { pause () { Lock guard (this); // note recursive lock + for ( uint i=0, lim=(rand() % MAX_PAUSE); i