diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b268253..16c14325 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,10 +101,6 @@ set(INITIAL_SEGMENT_SIZE "0" CACHE STRING "Set the initial segment size (use the internally defined value if 0 is specified)") # ---------- Experimental options ---------- # -# This mode still uses multiple threads inside Metall. -# However, applications must not use metall with multiple threads. -option(SINGLE_THREAD_ALLOC "Optimize Metall kernel for single thread usage" OFF) - option(USE_ANONYMOUS_NEW_MAP "Use the anonymous map when creating a new map region" OFF) set(UMAP_ROOT "" CACHE PATH "UMap installed root directory") @@ -215,11 +211,6 @@ if (USE_ANONYMOUS_NEW_MAP) message(STATUS "Use the anonymous map for new map region") endif () -if (SINGLE_THREAD_ALLOC) - list(APPEND METALL_DEFS "METALL_SINGLE_THREAD_ALLOC") - message(STATUS "Optimize Metall kernel for single thread usage") -endif () - # Requirements for GCC if (NOT RUN_BUILD_AND_TEST_WITH_CI) if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")) diff --git a/include/metall/basic_manager.hpp b/include/metall/basic_manager.hpp index fb18ca9f..8b9c3066 100644 --- a/include/metall/basic_manager.hpp +++ b/include/metall/basic_manager.hpp @@ -6,6 +6,17 @@ #ifndef METALL_BASIC_MANAGER_HPP #define METALL_BASIC_MANAGER_HPP +#ifdef DOXYGEN_SKIP +/// \brief A macro to disable concurrency support. +/// \details +/// If this macro is defined, Metall disables concurrency support and optimizes +/// the internal behavior for single-thread usage. Applications must not call +/// any Metall functions concurrently if this macro is defined. On the other +/// hand, Metall still may use multi-threading for internal operations, such +/// as synchronizing data with files. +#define METALL_DISABLE_CONCURRENCY +#endif + #include #include diff --git a/include/metall/kernel/manager_kernel.hpp b/include/metall/kernel/manager_kernel.hpp index f5ca062b..04ab6391 100644 --- a/include/metall/kernel/manager_kernel.hpp +++ b/include/metall/kernel/manager_kernel.hpp @@ -43,8 +43,10 @@ #include #endif -#define ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL 1 -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifndef METALL_DISABLE_CONCURRENCY +#define METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL +#endif +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL #include #endif @@ -140,7 +142,7 @@ class manager_kernel { using json_store = mdtl::ptree::node_type; -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL using mutex_type = mdtl::mutex; using lock_guard_type = mdtl::mutex_lock_guard; #endif @@ -596,7 +598,7 @@ class manager_kernel { segment_memory_allocator m_segment_memory_allocator{nullptr}; std::unique_ptr m_manager_metadata{nullptr}; -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL std::unique_ptr m_object_directories_mutex{nullptr}; #endif }; diff --git a/include/metall/kernel/manager_kernel_impl.ipp b/include/metall/kernel/manager_kernel_impl.ipp index 6f4eaa20..2d9f7641 100644 --- a/include/metall/kernel/manager_kernel_impl.ipp +++ b/include/metall/kernel/manager_kernel_impl.ipp @@ -21,7 +21,7 @@ manager_kernel::manager_kernel() if (!m_manager_metadata) { return; } -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL m_object_directories_mutex = std::make_unique(); if (!m_object_directories_mutex) { return; @@ -177,7 +177,7 @@ bool manager_kernel::destroy(char_ptr_holder_type name) { size_type length = 0; { -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL lock_guard_type guard(*m_object_directories_mutex); #endif @@ -204,7 +204,7 @@ bool manager_kernel::destroy_ptr(const T *ptr) { size_type length = 0; { -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL lock_guard_type guard(*m_object_directories_mutex); #endif @@ -820,7 +820,7 @@ T *manager_kernel::priv_generic_construct( void *ptr = nullptr; try { -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL lock_guard_type guard(*m_object_directories_mutex); #endif @@ -856,7 +856,7 @@ T *manager_kernel::priv_generic_construct( ptr, [this](void *const ptr) { try { { -#if ENABLE_MUTEX_IN_METALL_MANAGER_KERNEL +#ifdef METALL_ENABLE_MUTEX_IN_MANAGER_KERNEL lock_guard_type guard(*m_object_directories_mutex); #endif priv_remove_attr_object_no_mutex(priv_to_offset(ptr)); diff --git a/include/metall/kernel/object_cache.hpp b/include/metall/kernel/object_cache.hpp index 4c2890a0..0d84f706 100644 --- a/include/metall/kernel/object_cache.hpp +++ b/include/metall/kernel/object_cache.hpp @@ -20,12 +20,12 @@ #include #include -#ifndef METALL_SINGLE_THREAD_ALLOC +#ifndef METALL_DISABLE_CONCURRENCY #define METALL_ENABLE_MUTEX_IN_OBJECT_CACHE +#endif #ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE #include #endif -#endif namespace metall::kernel { @@ -58,7 +58,7 @@ class object_cache { // -------------------- // static constexpr std::size_t k_num_cache_per_core = -#ifdef METALL_SINGLE_THREAD_ALLOC +#ifdef METALL_DISABLE_CONCURRENCY 1; #else 4; @@ -232,7 +232,7 @@ class object_cache { } std::size_t priv_comp_cache_no() const { -#ifdef METALL_SINGLE_THREAD_ALLOC +#ifdef METALL_DISABLE_CONCURRENCY return 0; #endif #if SUPPORT_GET_CPU_CORE_NO @@ -252,7 +252,7 @@ class object_cache { /// \brief Get CPU core number. /// This function does not call the system call every time as it is slow. static std::size_t priv_get_core_no() { -#ifdef METALL_SINGLE_THREAD_ALLOC +#ifdef METALL_DISABLE_CONCURRENCY return 0; #endif thread_local static int cached_core_no = 0; @@ -265,7 +265,7 @@ class object_cache { } static std::size_t get_num_cores() { -#ifdef METALL_SINGLE_THREAD_ALLOC +#ifdef METALL_DISABLE_CONCURRENCY return 1; #else return std::thread::hardware_concurrency(); diff --git a/include/metall/kernel/segment_allocator.hpp b/include/metall/kernel/segment_allocator.hpp index 08afc38d..a92895cd 100644 --- a/include/metall/kernel/segment_allocator.hpp +++ b/include/metall/kernel/segment_allocator.hpp @@ -24,8 +24,11 @@ #include #include -#define ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR 1 -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifndef METALL_DISABLE_CONCURRENCY +#define METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR +#endif + +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR #include #endif @@ -94,7 +97,7 @@ class segment_allocator { myself>; #endif -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR using mutex_type = mdtl::mutex; using lock_guard_type = mdtl::mutex_lock_guard; #endif @@ -114,13 +117,13 @@ class segment_allocator { , m_object_cache() #endif -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR , m_chunk_mutex(nullptr), m_bin_mutex(nullptr) #endif { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR m_chunk_mutex = std::make_unique(); m_bin_mutex = std::make_unique>(); #endif @@ -217,7 +220,7 @@ class segment_allocator { /// This function is not cheap if many objects are allocated. /// \return Returns true if all memory is deallocated. bool all_memory_deallocated() const { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type chunk_guard(*m_chunk_mutex); #endif @@ -384,7 +387,7 @@ class segment_allocator { void priv_allocate_small_objects_from_global( const bin_no_type bin_no, const size_type num_allocates, difference_type *const allocated_offsets) { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type bin_guard(m_bin_mutex->at(bin_no)); #endif @@ -470,7 +473,7 @@ class segment_allocator { bool priv_insert_new_small_object_chunk(const bin_no_type bin_no) { chunk_no_type new_chunk_no; -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type chunk_guard(*m_chunk_mutex); #endif new_chunk_no = m_chunk_directory.insert(bin_no); @@ -482,7 +485,7 @@ class segment_allocator { } difference_type priv_allocate_large_object(const bin_no_type bin_no) { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type chunk_guard(*m_chunk_mutex); #endif const chunk_no_type new_chunk_no = m_chunk_directory.insert(bin_no); @@ -535,7 +538,7 @@ class segment_allocator { void priv_deallocate_small_objects_from_global( const bin_no_type bin_no, const size_type num_deallocates, const difference_type offsets[]) { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type bin_guard(m_bin_mutex->at(bin_no)); #endif for (size_type i = 0; i < num_deallocates; ++i) { @@ -559,7 +562,7 @@ class segment_allocator { } else if (m_chunk_directory.all_slots_unmarked(chunk_no)) { // All slots in the chunk are not used, deallocate it { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type chunk_guard(*m_chunk_mutex); #endif m_chunk_directory.erase(chunk_no); @@ -639,7 +642,7 @@ class segment_allocator { void priv_deallocate_large_object(const chunk_no_type chunk_no, const bin_no_type bin_no) { -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR lock_guard_type chunk_guard(*m_chunk_mutex); #endif m_chunk_directory.erase(chunk_no); @@ -717,7 +720,7 @@ class segment_allocator { small_object_cache_type m_object_cache; #endif -#if ENABLE_MUTEX_IN_METALL_SEGMENT_ALLOCATOR +#ifdef METALL_ENABLE_MUTEX_IN_SEGMENT_ALLOCATOR std::unique_ptr m_chunk_mutex{nullptr}; std::unique_ptr> m_bin_mutex{ nullptr}; diff --git a/test/kernel/CMakeLists.txt b/test/kernel/CMakeLists.txt index ee042dd8..6f2c75a2 100644 --- a/test/kernel/CMakeLists.txt +++ b/test/kernel/CMakeLists.txt @@ -11,7 +11,7 @@ add_metall_test_executable(chunk_directory_test chunk_directory_test.cpp) add_metall_test_executable(manager_test manager_test.cpp) add_metall_test_executable(manager_test_single_thread manager_test.cpp) -target_compile_definitions(manager_test_single_thread PRIVATE METALL_SINGLE_THREAD_ALLOC) +target_compile_definitions(manager_test_single_thread PRIVATE METALL_DISABLE_CONCURRENCY) add_metall_test_executable(snapshot_test snapshot_test.cpp)