shared monitor implementation with a conditional variable

or a ring buffer with semaphores
This commit is contained in:
Michael Krasnyk
2017-02-03 13:39:44 +01:00
committed by Patrick Niklaus
parent 438aa66b4c
commit 82acd59a8e
10 changed files with 310 additions and 170 deletions
+17 -17
View File
@@ -4,9 +4,9 @@
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "storage/shared_barrier.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "storage/shared_monitor.hpp"
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
#include <boost/thread/lock_types.hpp>
@@ -26,17 +26,18 @@ namespace engine
// once a new dataset arrives.
class DataWatchdog
{
using mutex_type = typename storage::SharedMonitor<storage::SharedDataTimestamp>::mutex_type;
public:
DataWatchdog() : barrier(boost::interprocess::open_only), active(true), timestamp(0)
DataWatchdog() : active(true), timestamp(0)
{
// create the initial facade before launching the watchdog thread
{
boost::interprocess::scoped_lock<storage::SharedBarrier::mutex_type>
current_region_lock(barrier.GetMutex());
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.GetRegion()));
timestamp = barrier.GetTimestamp();
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.data().region));
timestamp = barrier.data().timestamp;
}
watcher = std::thread(&DataWatchdog::Run, this);
@@ -45,7 +46,7 @@ class DataWatchdog
~DataWatchdog()
{
active = false;
barrier.NotifyAll();
barrier.notify_all();
watcher.join();
}
@@ -56,21 +57,20 @@ class DataWatchdog
{
while (active)
{
boost::interprocess::scoped_lock<storage::SharedBarrier::mutex_type>
current_region_lock(barrier.GetMutex());
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
while (active && timestamp == barrier.GetTimestamp())
while (active && timestamp == barrier.data().timestamp)
{
barrier.Wait(current_region_lock);
barrier.wait(current_region_lock);
}
if (timestamp != barrier.GetTimestamp())
if (timestamp != barrier.data().timestamp)
{
auto region = barrier.data().region;
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.GetRegion()));
timestamp = barrier.GetTimestamp();
util::Log() << "updated facade to region "
<< storage::regionToString(barrier.GetRegion()) << " with timestamp "
std::make_unique<datafacade::SharedMemoryAllocator>(region));
timestamp = barrier.data().timestamp;
util::Log() << "updated facade to region " << region << " with timestamp "
<< timestamp;
}
}
@@ -78,7 +78,7 @@ class DataWatchdog
util::Log() << "DataWatchdog thread stopped";
}
storage::SharedBarrier barrier;
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
std::thread watcher;
bool active;
unsigned timestamp;