mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
add IPC_CONSTEXPR_;
add variable_wrapper instead of fixed_alloc_policy
This commit is contained in:
parent
4aecd5b28b
commit
15e71bd1a1
@ -22,7 +22,6 @@ HEADERS += \
|
||||
../../include/tls_pointer.h \
|
||||
../../include/pool_alloc.h \
|
||||
../../include/buffer.h \
|
||||
../../src/memory/detail.h \
|
||||
../../src/memory/alloc.h \
|
||||
../../src/memory/wrapper.h \
|
||||
../../src/memory/resource.h \
|
||||
|
||||
16
src/ipc.cpp
16
src/ipc.cpp
@ -91,13 +91,15 @@ struct conn_info_head {
|
||||
shm::handle acc_h_;
|
||||
|
||||
/*
|
||||
<Remarks> thread_local may have some bugs.
|
||||
See: https://sourceforge.net/p/mingw-w64/bugs/727/
|
||||
https://sourceforge.net/p/mingw-w64/bugs/527/
|
||||
https://github.com/Alexpux/MINGW-packages/issues/2519
|
||||
https://github.com/ChaiScript/ChaiScript/issues/402
|
||||
https://developercommunity.visualstudio.com/content/problem/124121/thread-local-variables-fail-to-be-initialized-when.html
|
||||
https://software.intel.com/en-us/forums/intel-c-compiler/topic/684827
|
||||
* <Remarks> thread_local may have some bugs.
|
||||
*
|
||||
* <Reference>
|
||||
* - https://sourceforge.net/p/mingw-w64/bugs/727/
|
||||
* - https://sourceforge.net/p/mingw-w64/bugs/527/
|
||||
* - https://github.com/Alexpux/MINGW-packages/issues/2519
|
||||
* - https://github.com/ChaiScript/ChaiScript/issues/402
|
||||
* - https://developercommunity.visualstudio.com/content/problem/124121/thread-local-variables-fail-to-be-initialized-when.html
|
||||
* - https://software.intel.com/en-us/forums/intel-c-compiler/topic/684827
|
||||
*/
|
||||
tls::pointer<ipc::unordered_map<msg_id_t, cache_t>> recv_cache_;
|
||||
|
||||
|
||||
@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "memory/alloc.h"
|
||||
#include "platform/detail.h"
|
||||
|
||||
namespace ipc {
|
||||
namespace mem {
|
||||
namespace detail {
|
||||
|
||||
enum : std::size_t {
|
||||
base_size = sizeof(void*)
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
constexpr std::size_t classify(std::size_t size) {
|
||||
constexpr std::size_t mapping[] = {
|
||||
#else /*__cplusplus < 201703L*/
|
||||
inline std::size_t classify(std::size_t size) {
|
||||
static const std::size_t mapping[] = {
|
||||
#endif/*__cplusplus < 201703L*/
|
||||
/* 1 */
|
||||
0 , 1 , 2 , 3 ,
|
||||
/* 2 */
|
||||
5 , 5 , 7 , 7 ,
|
||||
9 , 9 , 11, 11,
|
||||
13, 13, 15, 15,
|
||||
/* 4 */
|
||||
19, 19, 19, 19,
|
||||
23, 23, 23, 23,
|
||||
27, 27, 27, 27,
|
||||
31, 31, 31, 31
|
||||
};
|
||||
size = (size - 1) / base_size;
|
||||
#if __cplusplus >= 201703L
|
||||
return (size < std::size(mapping)) ? mapping[size] : 32;
|
||||
#else /*__cplusplus < 201703L*/
|
||||
return (size < (sizeof(mapping) / sizeof(mapping[0]))) ? mapping[size] : 32;
|
||||
#endif/*__cplusplus < 201703L*/
|
||||
}
|
||||
|
||||
template <template <std::size_t> class Fixed, typename F>
|
||||
decltype(auto) choose(std::size_t size, F&& f) {
|
||||
return ipc::detail::static_switch<32>(classify(size), [&f](auto index) {
|
||||
return f(Fixed<(decltype(index)::value + 1) * base_size>::instance());
|
||||
}, [&f] {
|
||||
return f(static_alloc{});
|
||||
});
|
||||
}
|
||||
|
||||
template <template <std::size_t> class Fixed>
|
||||
class fixed_alloc_policy {
|
||||
public:
|
||||
static void clear() {
|
||||
ipc::detail::static_for<32>([](auto index) {
|
||||
Fixed<(decltype(index)::value + 1) * base_size>::instance().clear();
|
||||
});
|
||||
}
|
||||
|
||||
static void* alloc(std::size_t size) {
|
||||
return choose<Fixed>(size, [size](auto&& fp) { return fp.alloc(size); });
|
||||
}
|
||||
|
||||
static void free(void* p, std::size_t size) {
|
||||
choose<Fixed>(size, [p](auto&& fp) { fp.free(p); });
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mem
|
||||
} // namespace ipc
|
||||
@ -12,15 +12,14 @@
|
||||
|
||||
#include "memory/alloc.h"
|
||||
#include "memory/wrapper.h"
|
||||
#include "memory/detail.h"
|
||||
#include "platform/detail.h"
|
||||
|
||||
namespace ipc {
|
||||
namespace mem {
|
||||
|
||||
template <std::size_t Size>
|
||||
using static_async_fixed = mem::static_wrapper<mem::async_wrapper<mem::fixed_alloc<Size>>>;
|
||||
using async_pool_alloc = mem::detail::fixed_alloc_policy<static_async_fixed>;
|
||||
using static_async_fixed = static_wrapper<async_wrapper<fixed_alloc<Size>>>;
|
||||
using async_pool_alloc = variable_wrapper<static_async_fixed>;
|
||||
|
||||
template <typename T>
|
||||
using allocator = allocator_wrapper<T, async_pool_alloc>;
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
#include "def.h"
|
||||
#include "rw_lock.h"
|
||||
#include "tls_pointer.h"
|
||||
|
||||
#include "memory/alloc.h"
|
||||
#include "platform/detail.h"
|
||||
|
||||
namespace ipc {
|
||||
@ -181,12 +183,8 @@ public:
|
||||
return get_alloc().alloc(size);
|
||||
}
|
||||
|
||||
void free(void* p) {
|
||||
get_alloc().free(p);
|
||||
}
|
||||
|
||||
void free(void* p, std::size_t /*size*/) {
|
||||
free(p);
|
||||
void free(void* p, std::size_t size) {
|
||||
get_alloc().free(p, size);
|
||||
}
|
||||
};
|
||||
|
||||
@ -217,5 +215,63 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/// Variable memory allocation wrapper
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
template <std::size_t BaseSize = sizeof(void*)>
|
||||
struct default_mapping_policy {
|
||||
|
||||
enum : std::size_t {
|
||||
base_size = BaseSize,
|
||||
classes_size = 32
|
||||
};
|
||||
|
||||
static const std::size_t table[classes_size];
|
||||
|
||||
constexpr static std::size_t classify(std::size_t size) {
|
||||
return (((size - 1) / base_size) < classes_size) ? table[((size - 1) / base_size)] : classes_size;
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t B>
|
||||
const std::size_t default_mapping_policy<B>::table[default_mapping_policy<B>::classes_size] = {
|
||||
/* 1 - 8 ~ 32 */
|
||||
0 , 1 , 2 , 3 ,
|
||||
/* 2 - 48 ~ 256 */
|
||||
5 , 5 , 7 , 7 , 9 , 9 , 11, 11, 13, 13, 15, 15, 17, 17,
|
||||
19, 19, 21, 21, 23, 23, 25, 25, 27, 27, 29, 29, 31, 31
|
||||
};
|
||||
|
||||
template <template <std::size_t> class Fixed,
|
||||
typename StaticAlloc = mem::static_alloc,
|
||||
typename MappingP = default_mapping_policy<>>
|
||||
class variable_wrapper {
|
||||
|
||||
template <typename F>
|
||||
constexpr static auto choose(std::size_t size, F&& f) {
|
||||
return ipc::detail::static_switch<MappingP::classes_size>(MappingP::classify(size), [&f](auto index) {
|
||||
return f(Fixed<(decltype(index)::value + 1) * MappingP::base_size>{});
|
||||
}, [&f] {
|
||||
return f(StaticAlloc{});
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
static void clear() {
|
||||
ipc::detail::static_for<MappingP::classes_size>([](auto index) {
|
||||
Fixed<(decltype(index)::value + 1) * MappingP::base_size>::clear();
|
||||
});
|
||||
}
|
||||
|
||||
static void* alloc(std::size_t size) {
|
||||
return choose(size, [size](auto&& alc) { return alc.alloc(size); });
|
||||
}
|
||||
|
||||
static void free(void* p, std::size_t size) {
|
||||
choose(size, [p, size](auto&& alc) { alc.free(p, size); });
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mem
|
||||
} // namespace ipc
|
||||
|
||||
@ -24,12 +24,16 @@
|
||||
#ifdef IPC_STBIND_
|
||||
# error "IPC_STBIND_ has been defined."
|
||||
#endif
|
||||
#ifdef IPC_CONSTEXPR_
|
||||
# error "IPC_CONSTEXPR_ has been defined."
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
#define IPC_UNUSED_ [[maybe_unused]]
|
||||
#define IPC_FALLTHROUGH_ [[fallthrough]]
|
||||
#define IPC_STBIND_(A, B, ...) auto [A, B] = __VA_ARGS__
|
||||
#define IPC_CONSTEXPR_ constexpr
|
||||
|
||||
#else /*__cplusplus < 201703L*/
|
||||
|
||||
@ -48,6 +52,8 @@
|
||||
auto A = std::get<0>(tp___); \
|
||||
auto B = std::get<1>(tp___)
|
||||
|
||||
#define IPC_CONSTEXPR_ inline
|
||||
|
||||
#endif/*__cplusplus < 201703L*/
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
@ -121,20 +127,12 @@ constexpr decltype(auto) static_switch(std::size_t i, F&& f, D&& def) {
|
||||
}
|
||||
|
||||
template <typename F, std::size_t...I>
|
||||
#if __cplusplus >= 201703L
|
||||
constexpr void static_for(std::index_sequence<I...>, F&& f) {
|
||||
#else /*__cplusplus < 201703L*/
|
||||
inline void static_for(std::index_sequence<I...>, F&& f) {
|
||||
#endif/*__cplusplus < 201703L*/
|
||||
IPC_CONSTEXPR_ void static_for(std::index_sequence<I...>, F&& f) {
|
||||
IPC_UNUSED_ auto expand = { (std::forward<F>(f)(std::integral_constant<size_t, I>{}), 0)... };
|
||||
}
|
||||
|
||||
template <std::size_t N, typename F>
|
||||
#if __cplusplus >= 201703L
|
||||
constexpr void static_for(F&& f) {
|
||||
#else /*__cplusplus < 201703L*/
|
||||
inline void static_for(F&& f) {
|
||||
#endif/*__cplusplus < 201703L*/
|
||||
IPC_CONSTEXPR_ void static_for(F&& f) {
|
||||
static_for(std::make_index_sequence<N>{}, std::forward<F>(f));
|
||||
}
|
||||
|
||||
|
||||
@ -6,15 +6,17 @@
|
||||
namespace ipc {
|
||||
|
||||
/*
|
||||
<Remarks>
|
||||
|
||||
Windows doesn't support a per-thread destructor with its TLS primitives.
|
||||
So, here will build it manually by inserting a function to be called on each thread's exit.
|
||||
See: https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
|
||||
https://src.chromium.org/viewvc/chrome/trunk/src/base/threading/thread_local_storage_win.cc
|
||||
https://github.com/mirror/mingw-org-wsl/blob/master/src/libcrt/crt/tlssup.c
|
||||
https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/tlssup.c
|
||||
http://svn.boost.org/svn/boost/trunk/libs/thread/src/win32/tss_pe.cpp
|
||||
* <Remarks>
|
||||
*
|
||||
* Windows doesn't support a per-thread destructor with its TLS primitives.
|
||||
* So, here will build it manually by inserting a function to be called on each thread's exit.
|
||||
*
|
||||
* <Reference>
|
||||
* - https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
|
||||
* - https://src.chromium.org/viewvc/chrome/trunk/src/base/threading/thread_local_storage_win.cc
|
||||
* - https://github.com/mirror/mingw-org-wsl/blob/master/src/libcrt/crt/tlssup.c
|
||||
* - https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/tlssup.c
|
||||
* - http://svn.boost.org/svn/boost/trunk/libs/thread/src/win32/tss_pe.cpp
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
@ -25,13 +25,13 @@ private slots:
|
||||
void test_alloc_free();
|
||||
void test_static();
|
||||
void test_pool();
|
||||
} /*unit__*/;
|
||||
} unit__;
|
||||
|
||||
#include "test_mem.moc"
|
||||
|
||||
constexpr int DataMin = sizeof(void*);
|
||||
constexpr int DataMax = sizeof(void*) * 16;
|
||||
constexpr int LoopCount = 10000000;
|
||||
constexpr int LoopCount = 1000000;
|
||||
|
||||
std::vector<std::size_t> sizes__;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user