Fix alignments in shared facade via alignof/std::align

This commit is contained in:
Michael Krasnyk 2016-11-16 14:40:11 +01:00 committed by Patrick Niklaus
parent 47b097038a
commit d5bf508046
5 changed files with 38 additions and 34 deletions

View File

@ -143,15 +143,12 @@ class FileReader
// To make function calls consistent, this function returns the fixed number of properties
inline std::size_t readPropertiesCount() { return 1; }
#pragma pack(push, 1)
struct HSGRHeader
{
std::uint32_t checksum;
std::uint64_t number_of_nodes;
std::uint64_t number_of_edges;
};
#pragma pack(pop)
static_assert(sizeof(HSGRHeader) == 20, "HSGRHeader is not packed");
// Reads the checksum, number of nodes and number of edges written in the header file of a `.hsgr`
// file and returns them in a HSGRHeader struct

View File

@ -4,9 +4,9 @@
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include <cstdint>
#include <array>
#include <cstdint>
#include <memory>
namespace osrm
{
@ -98,21 +98,17 @@ struct DataLayout
NUM_BLOCKS
};
std::array<uint64_t, NUM_BLOCKS> num_entries;
std::array<uint64_t, NUM_BLOCKS> entry_size;
std::array<std::uint64_t, NUM_BLOCKS> num_entries;
std::array<std::size_t, NUM_BLOCKS> entry_size;
std::array<std::size_t, NUM_BLOCKS> entry_align;
DataLayout() : num_entries(), entry_size() {}
DataLayout() : num_entries(), entry_size(), entry_align() {}
template <typename T> inline void SetBlockSize(BlockID bid, uint64_t entries)
{
num_entries[bid] = entries;
entry_size[bid] = sizeof(T);
}
inline uint64_t AlignBlockSize(uint64_t block_size) const
{
const uint64_t alignment = 4;
return (block_size + (alignment - 1)) & ~(alignment - 1);
entry_align[bid] = alignof(T);
}
inline uint64_t GetBlockSize(BlockID bid) const
@ -120,41 +116,53 @@ struct DataLayout
// special bit encoding
if (bid == CORE_MARKER)
{
return AlignBlockSize((num_entries[bid] / 32 + 1) * entry_size[bid]);
return (num_entries[bid] / 32 + 1) * entry_size[bid];
}
return AlignBlockSize(num_entries[bid] * entry_size[bid]);
return num_entries[bid] * entry_size[bid];
}
inline uint64_t GetSizeOfLayout() const
{
return GetBlockOffset(NUM_BLOCKS) + NUM_BLOCKS * 2 * sizeof(CANARY);
}
inline uint64_t GetBlockOffset(BlockID bid) const
uint64_t result = 0;
for (auto i = 0; i < NUM_BLOCKS; i++)
{
uint64_t result = sizeof(CANARY);
for (auto i = 0; i < bid; i++)
{
result += GetBlockSize((BlockID)i) + 2 * sizeof(CANARY);
result += 2 * sizeof(CANARY) + GetBlockSize((BlockID)i) + entry_align[i];
}
return result;
}
inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const
{
for (auto i = 0; i < bid; i++)
{
ptr = static_cast<char *>(ptr) + sizeof(CANARY);
std::size_t space = 2 * entry_align[i] + entry_size[i];
ptr = std::align(entry_align[i], entry_size[i], ptr, space);
ptr = static_cast<char *>(ptr) + GetBlockSize((BlockID)i);
ptr = static_cast<char *>(ptr) + sizeof(CANARY);
}
ptr = static_cast<char *>(ptr) + sizeof(CANARY);
std::size_t space = 2 * entry_align[bid] + entry_size[bid];
ptr = std::align(entry_align[bid], entry_size[bid], ptr, space);
return ptr;
}
template <typename T, bool WRITE_CANARY = false>
inline T *GetBlockPtr(char *shared_memory, BlockID bid) const
{
T *ptr = (T *)(shared_memory + GetBlockOffset(bid));
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, bid);
if (WRITE_CANARY)
{
char *start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
char *end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
char *start_canary_ptr = ptr - sizeof(CANARY);
char *end_canary_ptr = ptr + GetBlockSize(bid);
std::copy(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
std::copy(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
}
else
{
char *start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
char *end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
char *start_canary_ptr = ptr - sizeof(CANARY);
char *end_canary_ptr = ptr + GetBlockSize(bid);
bool start_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
if (!start_canary_alive)
@ -169,7 +177,7 @@ struct DataLayout
}
}
return ptr;
return (T *)ptr;
}
};

View File

@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STORAGE_HPP
#define STORAGE_HPP
#include "storage/storage_config.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/storage_config.hpp"
#include <boost/filesystem/path.hpp>

View File

@ -14,8 +14,8 @@
#include <stxxl/vector>
#include <vector>
#include "util/fingerprint.hpp"
#include "storage/io.hpp"
#include "util/fingerprint.hpp"
namespace osrm
{

View File

@ -520,8 +520,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
const auto name_char_ptr =
layout.GetBlockPtr<char, true>(memory_ptr, DataLayout::NAME_CHAR_LIST);
BOOST_ASSERT_MSG(layout.AlignBlockSize(temp_count) ==
layout.GetBlockSize(DataLayout::NAME_CHAR_LIST),
BOOST_ASSERT_MSG(temp_count == layout.GetBlockSize(DataLayout::NAME_CHAR_LIST),
"Name file corrupted!");
name_file.ReadInto(name_char_ptr, temp_count);