From 8103d00b39b918e178e3a99f09f321546caf8bcf Mon Sep 17 00:00:00 2001 From: Jerin Philip Date: Wed, 29 Sep 2021 17:17:02 +0100 Subject: [PATCH] Remove boost dependency - Explicit inlining from boost source to not pull entire boost. - Does dangerous things for any inter-process hooks, however unneeded for out use-case. --- CMakeLists.txt | 79 +++++++------ Unittests/EpochManagerTest.cpp | 4 +- inc/L4/Epoch/EpochQueue.h | 12 +- inc/L4/Epoch/EpochRefPolicy.h | 8 +- inc/L4/HashTable/Common/Record.h | 11 +- inc/L4/HashTable/Common/SettingAdapter.h | 8 +- inc/L4/HashTable/Config.h | 26 ++--- inc/L4/HashTable/IHashTable.h | 5 +- inc/L4/HashTable/ReadWrite/HashTable.h | 6 +- inc/L4/HashTable/ReadWrite/Serializer.h | 7 +- inc/L4/Interprocess/Container/Vector.h | 10 +- inc/L4/LocalMemory/EpochManager.h | 4 +- inc/L4/LocalMemory/HashTableManager.h | 12 +- inc/L4/Log/IPerfLogger.h | 3 +- inc/L4/Serialization/SerializerHelper.h | 1 + inc/L4/Utils/AtomicOffsetPtr.h | 8 +- inc/L4/Utils/ComparerHasher.h | 22 +++- inc/L4/Utils/Containers.h | 7 +- inc/L4/Utils/Properties.h | 22 +--- inc/L4/detail/ToRawPointer.h | 139 ++++++++++++++++++++++- src/MurmurHash3.cpp | 6 +- src/PerfLogger.cpp | 12 +- 22 files changed, 276 insertions(+), 136 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f6fbdf..5f171f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,31 @@ cmake_minimum_required(VERSION 2.8.12) project(L4 CXX) -if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - message(FATAL_ERROR "Use provided solution file.") -elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - add_compile_options(-std=c++14) - add_definitions(-DBOOST_TEST_DYN_LINK) +# Enable setting options from repository above. +if (POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) endif() -set(Boost_USE_STATIC_LIBS OFF) -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) -find_package(Boost 1.45.0 COMPONENTS unit_test_framework REQUIRED) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + if(L4_COMPILE_UNIT_TESTS) + add_definitions(-DBOOST_TEST_DYN_LINK) + endif(L4_COMPILE_UNIT_TESTS) -if(Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) endif() +if(L4_COMPILE_UNIT_TESTS) + set(Boost_USE_STATIC_LIBS OFF) + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + find_package(Boost 1.45.0 COMPONENTS unit_test_framework REQUIRED) + if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + endif() +endif(L4_COMPILE_UNIT_TESTS) + include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/inc ${CMAKE_CURRENT_SOURCE_DIR}/inc/L4) @@ -34,26 +43,28 @@ add_library(L4 ${L4_SOURCES} ${L4_HEADERS}) -enable_testing() - -add_executable(L4.UnitTests - Unittests/CacheHashTableTest.cpp - Unittests/EpochManagerTest.cpp - Unittests/HashTableManagerTest.cpp - Unittests/HashTableRecordTest.cpp - Unittests/HashTableServiceTest.cpp - Unittests/PerfInfoTest.cpp - Unittests/ReadWriteHashTableSerializerTest.cpp - Unittests/ReadWriteHashTableTest.cpp - Unittests/SettingAdapterTest.cpp - Unittests/Utils.cpp - Unittests/UtilsTest.cpp - Unittests/Main.cpp) - -target_link_libraries(L4.UnitTests - L4 - ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} - -lpthread) - #${CMAKE_THREAD_LIBS_INIT}) - -add_test(NAME L4UnitTests COMMAND L4.UnitTests) +if(L4_COMPILE_UNIT_TESTS) + enable_testing() + add_executable(L4.UnitTests + Unittests/CacheHashTableTest.cpp + Unittests/EpochManagerTest.cpp + Unittests/HashTableManagerTest.cpp + Unittests/HashTableRecordTest.cpp + Unittests/HashTableServiceTest.cpp + Unittests/PerfInfoTest.cpp + Unittests/ReadWriteHashTableSerializerTest.cpp + Unittests/ReadWriteHashTableTest.cpp + Unittests/SettingAdapterTest.cpp + Unittests/Utils.cpp + Unittests/UtilsTest.cpp + Unittests/Main.cpp) + + target_link_libraries(L4.UnitTests + L4 + ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} + -lpthread) + #${CMAKE_THREAD_LIBS_INIT}) + + add_test(NAME L4UnitTests COMMAND L4.UnitTests) + +endif(L4_COMPILE_UNIT_TESTS) diff --git a/Unittests/EpochManagerTest.cpp b/Unittests/EpochManagerTest.cpp index cfe7b87..18cd6a9 100644 --- a/Unittests/EpochManagerTest.cpp +++ b/Unittests/EpochManagerTest.cpp @@ -17,7 +17,7 @@ BOOST_AUTO_TEST_CASE(EpochRefManagerTest) { const std::uint32_t c_epochQueueSize = 100U; using EpochQueue = - EpochQueue, + EpochQueue, std::lock_guard>; EpochQueue epochQueue(currentEpochCounter, c_epochQueueSize); @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(EpochCounterManagerTest) { const std::uint32_t c_epochQueueSize = 100U; using EpochQueue = - EpochQueue, + EpochQueue, std::lock_guard>; EpochQueue epochQueue(currentEpochCounter, c_epochQueueSize); diff --git a/inc/L4/Epoch/EpochQueue.h b/inc/L4/Epoch/EpochQueue.h index 6d0a02e..d4d34e3 100644 --- a/inc/L4/Epoch/EpochQueue.h +++ b/inc/L4/Epoch/EpochQueue.h @@ -1,9 +1,9 @@ #pragma once +#include #include #include #include -#include "Interprocess/Container/Vector.h" #include "Utils/Exception.h" #include "Utils/Lock.h" @@ -38,18 +38,20 @@ struct EpochQueue { using SharableLock = TSharableLock; using ExclusiveLock = TExclusiveLock; using RefCount = std::atomic; - using RefCounts = Interprocess::Container:: - Vector::other>; + // @jerinphilip: dirty-fix, browsermt/L4 hopefully does not need IPC. + // using RefCounts = Interprocess::Container:: + // Vector::other>; + using RefCounts = std::vector::other>; // The followings (m_frontIndex and m_backIndex) are // accessed/updated only by the owner thread (only one thread), thus // they don't require any synchronization. - std::size_t m_frontIndex; + std::uint64_t m_frontIndex; // Back index represents the latest epoch counter value. Note that // this is accessed/updated by multiple threads, thus requires // synchronization. - std::size_t m_backIndex; + std::uint64_t m_backIndex; // Read/Write lock for m_backIndex. typename SharableLock::mutex_type m_mutexForBackIndex; diff --git a/inc/L4/Epoch/EpochRefPolicy.h b/inc/L4/Epoch/EpochRefPolicy.h index 37a6784..d56ac80 100644 --- a/inc/L4/Epoch/EpochRefPolicy.h +++ b/inc/L4/Epoch/EpochRefPolicy.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace L4 { @@ -17,11 +17,11 @@ class EpochRefPolicy { : m_epochRefManager{epochRefPolicy.m_epochRefManager}, m_epochCounter{epochRefPolicy.m_epochCounter} { epochRefPolicy.m_epochCounter = - boost::integer_traits::const_max; + std::numeric_limits::max(); } ~EpochRefPolicy() { - if (m_epochCounter != boost::integer_traits::const_max) { + if (m_epochCounter != std::numeric_limits::max()) { m_epochRefManager.RemoveRef(m_epochCounter); } } @@ -34,4 +34,4 @@ class EpochRefPolicy { std::uint64_t m_epochCounter; }; -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/HashTable/Common/Record.h b/inc/L4/HashTable/Common/Record.h index 515d741..61cc45b 100644 --- a/inc/L4/HashTable/Common/Record.h +++ b/inc/L4/HashTable/Common/Record.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "HashTable/IHashTable.h" #include "Utils/Exception.h" @@ -73,14 +74,8 @@ class RecordSerializer { const auto start = SerializeSizes(buffer, key.m_size, value.m_size); -#if defined(_MSC_VER) - memcpy_s(buffer + start, key.m_size, key.m_data, key.m_size); - memcpy_s(buffer + start + key.m_size, value.m_size, value.m_data, - value.m_size); -#else - memcpy(buffer + start, key.m_data, key.m_size); - memcpy(buffer + start + key.m_size, value.m_data, value.m_size); -#endif + std::memcpy(buffer + start, key.m_data, key.m_size); + std::memcpy(buffer + start + key.m_size, value.m_data, value.m_size); return reinterpret_cast(buffer); } diff --git a/inc/L4/HashTable/Common/SettingAdapter.h b/inc/L4/HashTable/Common/SettingAdapter.h index aab19e6..8d8f640 100644 --- a/inc/L4/HashTable/Common/SettingAdapter.h +++ b/inc/L4/HashTable/Common/SettingAdapter.h @@ -18,13 +18,13 @@ class SettingAdapter { to.m_numBuckets = from.m_numBuckets; to.m_numBucketsPerMutex = - (std::max)(from.m_numBucketsPerMutex.get_value_or(1U), 1U); - to.m_fixedKeySize = from.m_fixedKeySize.get_value_or(0U); - to.m_fixedValueSize = from.m_fixedValueSize.get_value_or(0U); + (std::max)(from.m_numBucketsPerMutex.value_or(1U), 1U); + to.m_fixedKeySize = from.m_fixedKeySize.value_or(0U); + to.m_fixedValueSize = from.m_fixedValueSize.value_or(0U); return to; } }; } // namespace HashTable -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/HashTable/Config.h b/inc/L4/HashTable/Config.h index 965483c..8c84d48 100644 --- a/inc/L4/HashTable/Config.h +++ b/inc/L4/HashTable/Config.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -17,18 +17,18 @@ struct HashTableConfig { using ValueSize = IReadOnlyHashTable::Value::size_type; explicit Setting(std::uint32_t numBuckets, - boost::optional numBucketsPerMutex = {}, - boost::optional fixedKeySize = {}, - boost::optional fixedValueSize = {}) + std::optional numBucketsPerMutex = {}, + std::optional fixedKeySize = {}, + std::optional fixedValueSize = {}) : m_numBuckets{numBuckets}, m_numBucketsPerMutex{numBucketsPerMutex}, m_fixedKeySize{fixedKeySize}, m_fixedValueSize{fixedValueSize} {} std::uint32_t m_numBuckets; - boost::optional m_numBucketsPerMutex; - boost::optional m_fixedKeySize; - boost::optional m_fixedValueSize; + std::optional m_numBucketsPerMutex; + std::optional m_fixedKeySize; + std::optional m_fixedValueSize; }; struct Cache { @@ -48,17 +48,17 @@ struct HashTableConfig { using Properties = Utils::Properties; Serializer(std::shared_ptr stream = {}, - boost::optional properties = {}) + std::optional properties = {}) : m_stream{stream}, m_properties{properties} {} std::shared_ptr m_stream; - boost::optional m_properties; + std::optional m_properties; }; HashTableConfig(std::string name, Setting setting, - boost::optional cache = {}, - boost::optional serializer = {}) + std::optional cache = {}, + std::optional serializer = {}) : m_name{std::move(name)}, m_setting{std::move(setting)}, m_cache{cache}, @@ -69,8 +69,8 @@ struct HashTableConfig { std::string m_name; Setting m_setting; - boost::optional m_cache; - boost::optional m_serializer; + std::optional m_cache; + std::optional m_serializer; }; } // namespace L4 diff --git a/inc/L4/HashTable/IHashTable.h b/inc/L4/HashTable/IHashTable.h index 645758a..2dc002e 100644 --- a/inc/L4/HashTable/IHashTable.h +++ b/inc/L4/HashTable/IHashTable.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "Log/PerfCounter.h" #include "Utils/Properties.h" @@ -21,7 +22,7 @@ struct IReadOnlyHashTable { } bool operator==(const Blob& other) const { - return (m_size == other.m_size) && !memcmp(m_data, other.m_data, m_size); + return (m_size == other.m_size) && !std::memcmp(m_data, other.m_data, m_size); } bool operator!=(const Blob& other) const { return !(*this == other); } @@ -80,4 +81,4 @@ struct IWritableHashTable::ISerializer { const Utils::Properties& properties) = 0; }; -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/HashTable/ReadWrite/HashTable.h b/inc/L4/HashTable/ReadWrite/HashTable.h index c925ba6..3a79b34 100644 --- a/inc/L4/HashTable/ReadWrite/HashTable.h +++ b/inc/L4/HashTable/ReadWrite/HashTable.h @@ -1,8 +1,8 @@ #pragma once -#include #include #include +#include #include "Epoch/IEpochActionManager.h" #include "HashTable/Common/Record.h" #include "HashTable/Common/SharedHashTable.h" @@ -32,10 +32,10 @@ class ReadOnlyHashTable : public virtual IReadOnlyHashTable { explicit ReadOnlyHashTable( HashTable& hashTable, - boost::optional recordSerializer = boost::none) + std::optional recordSerializer = std::nullopt) : m_hashTable{hashTable}, m_recordSerializer{ - recordSerializer + recordSerializer.has_value() ? *recordSerializer : RecordSerializer{m_hashTable.m_setting.m_fixedKeySize, m_hashTable.m_setting.m_fixedValueSize}} {} diff --git a/inc/L4/HashTable/ReadWrite/Serializer.h b/inc/L4/HashTable/ReadWrite/Serializer.h index f6ec89a..5a74e57 100644 --- a/inc/L4/HashTable/ReadWrite/Serializer.h +++ b/inc/L4/HashTable/ReadWrite/Serializer.h @@ -1,8 +1,9 @@ #pragma once -#include #include #include +#include +#include #include "Epoch/IEpochActionManager.h" #include "Log/PerfCounter.h" #include "Serialization/SerializerHelper.h" @@ -203,8 +204,8 @@ class Deserializer { m_properties} .Deserialize(memory, stream); default: - boost::format err("Unsupported version '%1%' is given."); - err % version; + std::ostringstream err; + err << std::string("Unsupported version ") << version << std::string(" is given."); throw RuntimeException(err.str()); } } diff --git a/inc/L4/Interprocess/Container/Vector.h b/inc/L4/Interprocess/Container/Vector.h index d54d5df..2b80270 100644 --- a/inc/L4/Interprocess/Container/Vector.h +++ b/inc/L4/Interprocess/Container/Vector.h @@ -1,14 +1,18 @@ #pragma once -#include +// #include +#include namespace L4 { namespace Interprocess { namespace Container { +// template +// using Vector = boost::interprocess::vector; +// @jerinphilip: This is probably a bad idea. template -using Vector = boost::interprocess::vector; +using Vector = std::vector; } // namespace Container } // namespace Interprocess -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/LocalMemory/EpochManager.h b/inc/L4/LocalMemory/EpochManager.h index 0b0cd8a..a601766 100644 --- a/inc/L4/LocalMemory/EpochManager.h +++ b/inc/L4/LocalMemory/EpochManager.h @@ -1,8 +1,8 @@ #pragma once #include -#include #include +#include #include "Epoch/Config.h" #include "Epoch/EpochActionManager.h" #include "Epoch/EpochQueue.h" @@ -19,7 +19,7 @@ namespace LocalMemory { class EpochManager : public IEpochActionManager { public: using TheEpochQueue = - EpochQueue, + EpochQueue, std::lock_guard>; using TheEpochRefManager = EpochRefManager; diff --git a/inc/L4/LocalMemory/HashTableManager.h b/inc/L4/LocalMemory/HashTableManager.h index 048aa0a..12436e3 100644 --- a/inc/L4/LocalMemory/HashTableManager.h +++ b/inc/L4/LocalMemory/HashTableManager.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Epoch/IEpochActionManager.h" @@ -46,18 +46,18 @@ class HashTableManager { (serializerConfig && serializerConfig->m_stream != nullptr) ? ReadWrite::Deserializer( - serializerConfig->m_properties.get_value_or( + serializerConfig->m_properties.value_or( HashTableConfig::Serializer::Properties())) .Deserialize(memory, *(serializerConfig->m_stream)) : memory.template MakeUnique( typename InternalHashTable::Setting{ config.m_setting.m_numBuckets, (std::max)( - config.m_setting.m_numBucketsPerMutex.get_value_or( + config.m_setting.m_numBucketsPerMutex.value_or( 1U), 1U), - config.m_setting.m_fixedKeySize.get_value_or(0U), - config.m_setting.m_fixedValueSize.get_value_or(0U)}, + config.m_setting.m_fixedKeySize.value_or(0U), + config.m_setting.m_fixedValueSize.value_or(0U)}, memory.GetAllocator()); auto hashTable = @@ -92,7 +92,7 @@ class HashTableManager { private: Utils::StdStringKeyMap m_hashTableNameToIndex; - std::vector m_internalHashTables; + std::vector m_internalHashTables; std::vector> m_hashTables; }; diff --git a/inc/L4/Log/IPerfLogger.h b/inc/L4/Log/IPerfLogger.h index f079c3b..198ab5b 100644 --- a/inc/L4/Log/IPerfLogger.h +++ b/inc/L4/Log/IPerfLogger.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "PerfCounter.h" namespace L4 { @@ -28,4 +29,4 @@ struct IPerfLogger::IData { virtual const HashTablesPerfData& GetHashTablesPerfData() const = 0; }; -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/Serialization/SerializerHelper.h b/inc/L4/Serialization/SerializerHelper.h index 75b2c1b..fb7adb8 100644 --- a/inc/L4/Serialization/SerializerHelper.h +++ b/inc/L4/Serialization/SerializerHelper.h @@ -2,6 +2,7 @@ #include #include +#include namespace L4 { diff --git a/inc/L4/Utils/AtomicOffsetPtr.h b/inc/L4/Utils/AtomicOffsetPtr.h index 55883a1..c99b343 100644 --- a/inc/L4/Utils/AtomicOffsetPtr.h +++ b/inc/L4/Utils/AtomicOffsetPtr.h @@ -1,8 +1,7 @@ #pragma once #include -#include -#include +#include #include namespace L4 { @@ -26,15 +25,14 @@ class AtomicOffsetPtr { T* Load(std::memory_order memoryOrder = std::memory_order_seq_cst) const { return static_cast( - boost::interprocess::ipcdetail::offset_ptr_to_raw_pointer( + L4::Detail::offset_ptr_to_raw_pointer( this, m_offset.load(memoryOrder))); } void Store(T* ptr, std::memory_order memoryOrder = std::memory_order_seq_cst) { m_offset.store( - boost::interprocess::ipcdetail::offset_ptr_to_offset( - ptr, this), + L4::Detail::offset_ptr_to_offset(ptr, this), memoryOrder); } diff --git a/inc/L4/Utils/ComparerHasher.h b/inc/L4/Utils/ComparerHasher.h index 142a4d0..e566e4d 100644 --- a/inc/L4/Utils/ComparerHasher.h +++ b/inc/L4/Utils/ComparerHasher.h @@ -1,17 +1,29 @@ #pragma once -#include #include #include #include #if defined(__GNUC__) +#include #define _stricmp strcasecmp #endif namespace L4 { namespace Utils { +namespace { + +// https://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine +// http://burtleburtle.net/bob/hash/doobs.html +template +inline void hash_combine(std::size_t& seed, const T& v) { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +} // namespace + // CaseInsensitiveStdStringComparer is a STL-compatible case-insensitive ANSI // std::string comparer. struct CaseInsensitiveStdStringComparer { @@ -23,9 +35,7 @@ struct CaseInsensitiveStdStringComparer { // CaseInsensitiveStringComparer is a STL-compatible case-insensitive ANSI // string comparer. struct CaseInsensitiveStringComparer { - bool operator()(const char* const str1, const char* const str2) const { - return _stricmp(str1, str2) == 0; - } + bool operator()(const char* const str1, const char* const str2) const { return _stricmp(str1, str2) == 0; } }; // CaseInsensitiveStringHasher is a STL-compatible case-insensitive ANSI @@ -35,7 +45,7 @@ struct CaseInsensitiveStdStringHasher { std::size_t seed = 0; for (auto c : str) { - boost::hash_combine(seed, std::toupper(c)); + hash_combine(seed, std::toupper(c)); } return seed; @@ -51,7 +61,7 @@ struct CaseInsensitiveStringHasher { std::size_t seed = 0; while (*str) { - boost::hash_combine(seed, std::toupper(*str++)); + hash_combine(seed, std::toupper(*str++)); } return seed; diff --git a/inc/L4/Utils/Containers.h b/inc/L4/Utils/Containers.h index 010a179..7d770f3 100644 --- a/inc/L4/Utils/Containers.h +++ b/inc/L4/Utils/Containers.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -28,10 +27,10 @@ using StringKeyMap = std::unordered_map; -// IntegerKeyMap using boost::hash and std::equal_to comparer and hasher. +// IntegerKeyMap using std::hash and std::equal_to comparer and hasher. template using IntegerKeyMap = - std::unordered_map, std::equal_to>; + std::unordered_map, std::equal_to>; } // namespace Utils -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/Utils/Properties.h b/inc/L4/Utils/Properties.h index f65ee25..533d797 100644 --- a/inc/L4/Utils/Properties.h +++ b/inc/L4/Utils/Properties.h @@ -2,7 +2,6 @@ #include "Utils/Containers.h" -#include namespace L4 { namespace Utils { @@ -19,26 +18,7 @@ class Properties : public StdStringKeyMap { // Expose a constructor with initializer_list for convenience. Properties(std::initializer_list values) : Base(values) {} - // Returns true if the given key exists and the value associated with - // the key can be converted to the TValue type. If the conversion fails, the - // value of the given val is guaranteed to remain the same. - template - bool TryGet(const std::string& key, TValue& val) const { - const auto it = find(key); - if (it == end()) { - return false; - } - - TValue tmp; - if (!boost::conversion::try_lexical_convert(it->second, tmp)) { - return false; - } - - val = tmp; - - return true; - } }; } // namespace Utils -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/inc/L4/detail/ToRawPointer.h b/inc/L4/detail/ToRawPointer.h index 73f3aaf..dbca646 100644 --- a/inc/L4/detail/ToRawPointer.h +++ b/inc/L4/detail/ToRawPointer.h @@ -1,11 +1,144 @@ #pragma once -#include namespace L4 { namespace Detail { -using boost::interprocess::ipcdetail::to_raw_pointer; +// #include +// using boost::interprocess::ipcdetail::to_raw_pointer; + +// The following subset of functions are copied over from the above header file +// (or further includes) and are the minimum required ones to get L4 working +// without pulling boost sources in entirety. + +#define L4_MAYBE_INLINE + +template +class pointer_uintptr_caster; + +template +class pointer_uintptr_caster +{ + public: + L4_MAYBE_INLINE explicit pointer_uintptr_caster(uintptr_t sz) + : m_uintptr(sz) + {} + + L4_MAYBE_INLINE explicit pointer_uintptr_caster(const volatile T *p) + : m_uintptr(reinterpret_cast(p)) + {} + + L4_MAYBE_INLINE uintptr_t uintptr() const + { return m_uintptr; } + + L4_MAYBE_INLINE T* pointer() const + { return reinterpret_cast(m_uintptr); } + + private: + uintptr_t m_uintptr; +}; + +template +class pointer_size_t_caster +{ + public: + explicit pointer_size_t_caster(std::size_t sz) + : m_ptr(reinterpret_cast(sz)) + {} + + explicit pointer_size_t_caster(RawPointer p) + : m_ptr(p) + {} + + std::size_t size() const + { return reinterpret_cast(m_ptr); } + + RawPointer pointer() const + { return m_ptr; } + + private: + RawPointer m_ptr; +}; + + +template +class pointer_offset_caster; + +template +class pointer_offset_caster +{ + public: + L4_MAYBE_INLINE explicit pointer_offset_caster(OffsetType offset) + : m_offset(offset) + {} + + L4_MAYBE_INLINE explicit pointer_offset_caster(const volatile T *p) + : m_offset(reinterpret_cast(p)) + {} + + L4_MAYBE_INLINE OffsetType offset() const + { return m_offset; } + + L4_MAYBE_INLINE T* pointer() const + { return reinterpret_cast(m_offset); } + + private: + OffsetType m_offset; +}; + + + +#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR +template +L4_MAYBE_INLINE void *offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset) { + typedef pointer_offset_caster caster_t; +#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR + if (offset == 1) { + return 0; + } else { + return caster_t(caster_t(this_ptr).offset() + offset).pointer(); + } +#else + OffsetType mask = offset == 1; + --mask; + OffsetType target_offset = caster_t(this_ptr).offset() + offset; + target_offset &= mask; + return caster_t(target_offset).pointer(); +#endif +} + + +template +L4_MAYBE_INLINE T* to_raw_pointer(T* p) +{ return p; } + +template +L4_MAYBE_INLINE std::size_t offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr) +{ + typedef pointer_size_t_caster caster_t; + #ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF + //offset == 1 && ptr != 0 is not legal for this pointer + if(!ptr){ + return 1; + } + else{ + caster_t this_caster((void*)this_ptr); + caster_t ptr_caster((void*)ptr); + std::size_t offset = ptr_caster.size() - this_caster.size(); + assert(offset != 1); + return offset; + } + #else + caster_t this_caster((void*)this_ptr); + caster_t ptr_caster((void*)ptr); + std::size_t offset = (ptr_caster.size() - this_caster.size() - 1) & -std::size_t(ptr != 0); + ++offset; + return offset; + #endif +} + + + } // namespace Detail -} // namespace L4 \ No newline at end of file +} // namespace L4 diff --git a/src/MurmurHash3.cpp b/src/MurmurHash3.cpp index e08d5a3..889d149 100644 --- a/src/MurmurHash3.cpp +++ b/src/MurmurHash3.cpp @@ -29,7 +29,9 @@ #else // defined(_MSC_VER) -#define FORCE_INLINE __attribute__((always_inline)) +// For position independent compiles +// https://rt.cpan.org/Public/Bug/Display.html?id=91280 +#define FORCE_INLINE inline __attribute__((always_inline)) inline uint32_t rotl32(uint32_t x, int8_t r) { @@ -331,4 +333,4 @@ void MurmurHash3_x64_128(const void * key, const int len, ((uint64_t*)out)[1] = h2; } -//----------------------------------------------------------------------------- \ No newline at end of file +//----------------------------------------------------------------------------- diff --git a/src/PerfLogger.cpp b/src/PerfLogger.cpp index 8fbe305..eb0cce8 100644 --- a/src/PerfLogger.cpp +++ b/src/PerfLogger.cpp @@ -1,6 +1,7 @@ +#include "Log/PerfCounter.h" #include "Log/PerfLogger.h" -#include #include "Utils/Exception.h" +#include namespace L4 { @@ -12,10 +13,11 @@ void PerfData::AddHashTablePerfData(const char* hashTableName, std::make_pair(hashTableName, HashTablesPerfData::mapped_type(perfData))); if (!result.second) { - boost::format err("Duplicate hash table name found: '%1%'."); - err % hashTableName; - throw RuntimeException(err.str()); + std::stringstream stream; + stream << "Duplicate hash table name found: "; + stream << hashTableName; + throw RuntimeException(stream.str()); } } -} // namespace L4 \ No newline at end of file +} // namespace L4