Join LAYOUT and DATA shared memory blocks into REGION

This commit is contained in:
Michael Krasnyk
2016-12-23 00:18:57 +01:00
committed by Patrick Niklaus
parent 7b11cd3a11
commit b376c97db8
8 changed files with 99 additions and 149 deletions
+12 -17
View File
@@ -32,15 +32,15 @@ class DataWatchdog
public:
DataWatchdog()
: shared_barriers{std::make_shared<storage::SharedBarriers>()},
shared_regions(storage::makeSharedMemory(storage::CURRENT_REGIONS)),
current_timestamp{storage::LAYOUT_NONE, storage::DATA_NONE, 0}
shared_regions(storage::makeSharedMemory(storage::CURRENT_REGION)),
current_timestamp{storage::REGION_NONE, 0}
{
}
// Tries to connect to the shared memory containing the regions table
static bool TryConnect()
{
return storage::SharedMemory::RegionExists(storage::CURRENT_REGIONS);
return storage::SharedMemory::RegionExists(storage::CURRENT_REGION);
}
using RegionsLock =
@@ -52,22 +52,20 @@ class DataWatchdog
LockAndFacade GetDataFacade()
{
const boost::interprocess::sharable_lock<boost::interprocess::named_upgradable_mutex> lock(
shared_barriers->current_regions_mutex);
shared_barriers->current_region_mutex);
const auto shared_timestamp =
static_cast<const storage::SharedDataTimestamp *>(shared_regions->Ptr());
const auto get_locked_facade = [this, shared_timestamp]() {
if (current_timestamp.data == storage::DATA_1)
if (current_timestamp.region == storage::REGION_1)
{
BOOST_ASSERT(current_timestamp.layout == storage::LAYOUT_1);
return std::make_pair(RegionsLock(shared_barriers->regions_1_mutex), facade);
return std::make_pair(RegionsLock(shared_barriers->region_1_mutex), facade);
}
else
{
BOOST_ASSERT(current_timestamp.layout == storage::LAYOUT_2);
BOOST_ASSERT(current_timestamp.data == storage::DATA_2);
return std::make_pair(RegionsLock(shared_barriers->regions_2_mutex), facade);
BOOST_ASSERT(current_timestamp.region == storage::REGION_2);
return std::make_pair(RegionsLock(shared_barriers->region_2_mutex), facade);
}
};
@@ -78,8 +76,7 @@ class DataWatchdog
if (shared_timestamp->timestamp == current_timestamp.timestamp)
{
BOOST_ASSERT(shared_timestamp->layout == current_timestamp.layout);
BOOST_ASSERT(shared_timestamp->data == current_timestamp.data);
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
return get_locked_facade();
}
}
@@ -89,11 +86,10 @@ class DataWatchdog
boost::upgrade_lock<boost::shared_mutex> facade_lock(facade_mutex);
// we might get overtaken before we actually do the writing
// in that case we don't modify anthing
// in that case we don't modify anything
if (shared_timestamp->timestamp == current_timestamp.timestamp)
{
BOOST_ASSERT(shared_timestamp->layout == current_timestamp.layout);
BOOST_ASSERT(shared_timestamp->data == current_timestamp.data);
BOOST_ASSERT(shared_timestamp->region == current_timestamp.region);
return get_locked_facade();
}
@@ -103,8 +99,7 @@ class DataWatchdog
current_timestamp = *shared_timestamp;
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(shared_barriers,
current_timestamp.layout,
current_timestamp.data,
current_timestamp.region,
current_timestamp.timestamp);
return get_locked_facade();
@@ -24,10 +24,8 @@ class SharedMemoryDataFacade : public ContiguousInternalMemoryDataFacadeBase
{
protected:
std::unique_ptr<storage::SharedMemory> m_layout_memory;
std::unique_ptr<storage::SharedMemory> m_large_memory;
std::shared_ptr<storage::SharedBarriers> shared_barriers;
storage::SharedDataType layout_region;
storage::SharedDataType data_region;
unsigned shared_timestamp;
@@ -40,12 +38,12 @@ class SharedMemoryDataFacade : public ContiguousInternalMemoryDataFacadeBase
{
// Now check if this is still the newest dataset
boost::interprocess::sharable_lock<boost::interprocess::named_upgradable_mutex>
current_regions_lock(shared_barriers->current_regions_mutex,
current_regions_lock(shared_barriers->current_region_mutex,
boost::interprocess::defer_lock);
boost::interprocess::scoped_lock<boost::interprocess::named_sharable_mutex> exclusive_lock(
data_region == storage::DATA_1 ? shared_barriers->regions_1_mutex
: shared_barriers->regions_2_mutex,
data_region == storage::REGION_1 ? shared_barriers->region_1_mutex
: shared_barriers->region_2_mutex,
boost::interprocess::defer_lock);
// if this returns false this is still in use
@@ -53,45 +51,36 @@ class SharedMemoryDataFacade : public ContiguousInternalMemoryDataFacadeBase
{
if (storage::SharedMemory::RegionExists(data_region))
{
BOOST_ASSERT(storage::SharedMemory::RegionExists(layout_region));
auto shared_regions = storage::makeSharedMemory(storage::CURRENT_REGIONS);
auto shared_region = storage::makeSharedMemory(storage::CURRENT_REGION);
const auto current_timestamp =
static_cast<const storage::SharedDataTimestamp *>(shared_regions->Ptr());
static_cast<const storage::SharedDataTimestamp *>(shared_region->Ptr());
// check if the memory region referenced by this facade needs cleanup
if (current_timestamp->data == data_region)
if (current_timestamp->region == data_region)
{
BOOST_ASSERT(current_timestamp->layout == layout_region);
util::Log(logDEBUG) << "Retaining data with shared timestamp "
<< shared_timestamp;
}
else
{
storage::SharedMemory::Remove(data_region);
storage::SharedMemory::Remove(layout_region);
}
}
}
}
SharedMemoryDataFacade(const std::shared_ptr<storage::SharedBarriers> &shared_barriers_,
storage::SharedDataType layout_region_,
storage::SharedDataType data_region_,
unsigned shared_timestamp_)
: shared_barriers(shared_barriers_), layout_region(layout_region_),
data_region(data_region_), shared_timestamp(shared_timestamp_)
: shared_barriers(shared_barriers_), data_region(data_region_), shared_timestamp(shared_timestamp_)
{
util::Log(logDEBUG) << "Loading new data with shared timestamp " << shared_timestamp;
BOOST_ASSERT(storage::SharedMemory::RegionExists(layout_region));
m_layout_memory = storage::makeSharedMemory(layout_region);
BOOST_ASSERT(storage::SharedMemory::RegionExists(data_region));
m_large_memory = storage::makeSharedMemory(data_region);
InitializeInternalPointers(*reinterpret_cast<storage::DataLayout *>(m_layout_memory->Ptr()),
reinterpret_cast<char *>(m_large_memory->Ptr()));
InitializeInternalPointers(*reinterpret_cast<storage::DataLayout *>(m_large_memory->Ptr()),
reinterpret_cast<char *>(m_large_memory->Ptr()) + sizeof(storage::DataLayout));
}
};
}
+10 -10
View File
@@ -13,22 +13,22 @@ struct SharedBarriers
{
SharedBarriers()
: current_regions_mutex(boost::interprocess::open_or_create, "current_regions"),
regions_1_mutex(boost::interprocess::open_or_create, "regions_1"),
regions_2_mutex(boost::interprocess::open_or_create, "regions_2")
: current_region_mutex(boost::interprocess::open_or_create, "current_region"),
region_1_mutex(boost::interprocess::open_or_create, "region_1"),
region_2_mutex(boost::interprocess::open_or_create, "region_2")
{
}
static void resetCurrentRegions()
static void resetCurrentRegion()
{
boost::interprocess::named_sharable_mutex::remove("current_regions");
boost::interprocess::named_sharable_mutex::remove("current_region");
}
static void resetRegions1() { boost::interprocess::named_sharable_mutex::remove("regions_1"); }
static void resetRegions2() { boost::interprocess::named_sharable_mutex::remove("regions_2"); }
static void resetRegion1() { boost::interprocess::named_sharable_mutex::remove("region_1"); }
static void resetRegion2() { boost::interprocess::named_sharable_mutex::remove("region_2"); }
boost::interprocess::named_upgradable_mutex current_regions_mutex;
boost::interprocess::named_sharable_mutex regions_1_mutex;
boost::interprocess::named_sharable_mutex regions_2_mutex;
boost::interprocess::named_upgradable_mutex current_region_mutex;
boost::interprocess::named_sharable_mutex region_1_mutex;
boost::interprocess::named_sharable_mutex region_2_mutex;
};
}
}
+13 -23
View File
@@ -192,19 +192,15 @@ struct DataLayout
enum SharedDataType
{
CURRENT_REGIONS,
LAYOUT_1,
DATA_1,
LAYOUT_2,
DATA_2,
LAYOUT_NONE,
DATA_NONE
CURRENT_REGION,
REGION_1,
REGION_2,
REGION_NONE
};
struct SharedDataTimestamp
{
SharedDataType layout;
SharedDataType data;
SharedDataType region;
unsigned timestamp;
};
@@ -212,20 +208,14 @@ inline std::string regionToString(const SharedDataType region)
{
switch (region)
{
case CURRENT_REGIONS:
return "CURRENT_REGIONS";
case LAYOUT_1:
return "LAYOUT_1";
case DATA_1:
return "DATA_1";
case LAYOUT_2:
return "LAYOUT_2";
case DATA_2:
return "DATA_2";
case LAYOUT_NONE:
return "LAYOUT_NONE";
case DATA_NONE:
return "DATA_NONE";
case CURRENT_REGION:
return "CURRENT_REGION";
case REGION_1:
return "REGION_1";
case REGION_2:
return "REGION_2";
case REGION_NONE:
return "REGION_NONE";
default:
return "INVALID_REGION";
}