mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
make pool_alloc public
This commit is contained in:
parent
e6fab3edeb
commit
cba780e9dc
@ -24,6 +24,7 @@ HEADERS += \
|
|||||||
../include/def.h \
|
../include/def.h \
|
||||||
../include/rw_lock.h \
|
../include/rw_lock.h \
|
||||||
../include/tls_pointer.h \
|
../include/tls_pointer.h \
|
||||||
|
../include/pool_alloc.h \
|
||||||
../src/channel.inc \
|
../src/channel.inc \
|
||||||
../src/route.inc \
|
../src/route.inc \
|
||||||
../src/id_pool.inc \
|
../src/id_pool.inc \
|
||||||
@ -33,7 +34,8 @@ HEADERS += \
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
../src/shm.cpp \
|
../src/shm.cpp \
|
||||||
../src/ipc.cpp
|
../src/ipc.cpp \
|
||||||
|
../src/pool_alloc.cpp
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
|
|
||||||
|
|||||||
17
include/pool_alloc.h
Normal file
17
include/pool_alloc.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "export.h"
|
||||||
|
#include "def.h"
|
||||||
|
|
||||||
|
namespace ipc {
|
||||||
|
namespace mem {
|
||||||
|
|
||||||
|
class IPC_EXPORT pool_alloc {
|
||||||
|
public:
|
||||||
|
static void clear();
|
||||||
|
static void* alloc(std::size_t size);
|
||||||
|
static void free(void* p, std::size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mem
|
||||||
|
} // namespace ipc
|
||||||
@ -26,46 +26,34 @@ constexpr decltype(auto) static_switch(std::size_t i, std::index_sequence<N, I..
|
|||||||
static_switch(i, std::index_sequence<I...>{}, f, def);
|
static_switch(i, std::index_sequence<I...>{}, f, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
template <std::size_t Size>
|
||||||
|
auto& fixed() {
|
||||||
|
static synchronized<fixed_pool<Size>> pool;
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
decltype(auto) choose(std::size_t size, F&& f) {
|
||||||
|
enum : std::size_t { base_size = sizeof(void*) };
|
||||||
|
size = ((size - 1) & (~(base_size - 1))) + base_size;
|
||||||
|
return detail::static_switch(size, std::index_sequence<
|
||||||
|
base_size , base_size * 2 ,
|
||||||
|
base_size * 3 , base_size * 4 ,
|
||||||
|
base_size * 5 , base_size * 6 ,
|
||||||
|
base_size * 7 , base_size * 8 ,
|
||||||
|
base_size * 9 , base_size * 10,
|
||||||
|
base_size * 11, base_size * 12,
|
||||||
|
base_size * 13, base_size * 14,
|
||||||
|
base_size * 15, base_size * 16
|
||||||
|
>{}, [&f](auto index) {
|
||||||
|
return f(fixed<decltype(index)::value>());
|
||||||
|
}, [&f] { return f(static_alloc{}); });
|
||||||
|
}
|
||||||
|
|
||||||
class pool_alloc {
|
class pool_alloc {
|
||||||
private:
|
|
||||||
template <std::size_t Size>
|
|
||||||
static auto& fixed() {
|
|
||||||
static synchronized<fixed_pool<Size>> pool;
|
|
||||||
return pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename F>
|
|
||||||
static decltype(auto) choose(std::size_t size, F&& f) {
|
|
||||||
enum : std::size_t { base_size = sizeof(void*) };
|
|
||||||
size = ((size - 1) & (~(base_size - 1))) + base_size;
|
|
||||||
return detail::static_switch(size, std::index_sequence<
|
|
||||||
base_size , base_size * 2 ,
|
|
||||||
base_size * 3 , base_size * 4 ,
|
|
||||||
base_size * 5 , base_size * 6 ,
|
|
||||||
base_size * 7 , base_size * 8 ,
|
|
||||||
base_size * 9 , base_size * 10,
|
|
||||||
base_size * 11, base_size * 12,
|
|
||||||
base_size * 13, base_size * 14,
|
|
||||||
base_size * 15, base_size * 16
|
|
||||||
>{}, [&f](auto index) {
|
|
||||||
return f(fixed<decltype(index)::value>());
|
|
||||||
}, [&f] { return f(static_alloc{}); });
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pool_alloc() = default;
|
|
||||||
pool_alloc(const pool_alloc&) = default;
|
|
||||||
pool_alloc& operator=(const pool_alloc&) = default;
|
|
||||||
pool_alloc(pool_alloc&&) = default;
|
|
||||||
pool_alloc& operator=(pool_alloc&&) = default;
|
|
||||||
|
|
||||||
static constexpr std::size_t remain() {
|
|
||||||
return (std::numeric_limits<std::size_t>::max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr void clear() {}
|
static constexpr void clear() {}
|
||||||
|
static constexpr void swap(pool_alloc&) {}
|
||||||
|
|
||||||
static void* alloc(std::size_t size) {
|
static void* alloc(std::size_t size) {
|
||||||
return choose(size, [size](auto&& fp) { return fp.alloc(size); });
|
return choose(size, [size](auto&& fp) { return fp.alloc(size); });
|
||||||
@ -76,8 +64,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using allocator = allocator_wrapper<T, pool_alloc>;
|
using allocator = allocator_wrapper<T, detail::pool_alloc>;
|
||||||
|
|
||||||
template <typename Key, typename T>
|
template <typename Key, typename T>
|
||||||
using unordered_map = std::unordered_map<
|
using unordered_map = std::unordered_map<
|
||||||
|
|||||||
21
src/pool_alloc.cpp
Normal file
21
src/pool_alloc.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "pool_alloc.h"
|
||||||
|
|
||||||
|
#include "memory/resource.hpp"
|
||||||
|
|
||||||
|
namespace ipc {
|
||||||
|
namespace mem {
|
||||||
|
|
||||||
|
void pool_alloc::clear() {
|
||||||
|
detail::pool_alloc::clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pool_alloc::alloc(std::size_t size) {
|
||||||
|
return detail::pool_alloc::alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_alloc::free(void* p, std::size_t size) {
|
||||||
|
detail::pool_alloc::free(p, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mem
|
||||||
|
} // namespace ipc
|
||||||
@ -115,7 +115,7 @@ void benchmark_prod_cons(T* cq) {
|
|||||||
// std::cout << cid << "-consumer-disconnect" << std::endl;
|
// std::cout << cid << "-consumer-disconnect" << std::endl;
|
||||||
// }
|
// }
|
||||||
tcq.disconnect(cn);
|
tcq.disconnect(cn);
|
||||||
if (++fini_c != std::extent<decltype(consumers)>::value) {
|
if ((fini_c.fetch_add(1, std::memory_order_relaxed) + 1) != std::extent<decltype(consumers)>::value) {
|
||||||
// std::unique_lock<capo::spin_lock> guard { lc };
|
// std::unique_lock<capo::spin_lock> guard { lc };
|
||||||
// std::cout << cid << "-consumer-end" << std::endl;
|
// std::cout << cid << "-consumer-end" << std::endl;
|
||||||
return;
|
return;
|
||||||
@ -141,7 +141,9 @@ void benchmark_prod_cons(T* cq) {
|
|||||||
// }
|
// }
|
||||||
tcq.send(cn, { pid, i });
|
tcq.send(cn, { pid, i });
|
||||||
}
|
}
|
||||||
if (++fini_p != std::extent<decltype(producers)>::value) return;
|
if ((fini_p.fetch_add(1, std::memory_order_relaxed) + 1) != std::extent<decltype(producers)>::value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// quit
|
// quit
|
||||||
tcq.send(cn, { -1, -1 });
|
tcq.send(cn, { -1, -1 });
|
||||||
}};
|
}};
|
||||||
|
|||||||
@ -258,7 +258,7 @@ void benchmark_lc() {
|
|||||||
}
|
}
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
if (++fini == std::extent<decltype(r_trd)>::value) {
|
if ((fini.fetch_add(1, std::memory_order_relaxed) + 1) == std::extent<decltype(r_trd)>::value) {
|
||||||
sw.print_elapsed(W, R, Loops);
|
sw.print_elapsed(W, R, Loops);
|
||||||
}
|
}
|
||||||
std::uint64_t sum = 0;
|
std::uint64_t sum = 0;
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
|
|
||||||
#include "memory/resource.hpp"
|
#include "memory/resource.hpp"
|
||||||
|
#include "pool_alloc.h"
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -21,7 +23,8 @@ private slots:
|
|||||||
void initTestCase();
|
void initTestCase();
|
||||||
void cleanupTestCase();
|
void cleanupTestCase();
|
||||||
|
|
||||||
void test_alloc();
|
void test_alloc_free();
|
||||||
|
void test_linear();
|
||||||
} unit__;
|
} unit__;
|
||||||
|
|
||||||
#include "test_mem.moc"
|
#include "test_mem.moc"
|
||||||
@ -91,6 +94,27 @@ void Unit::cleanupTestCase() {
|
|||||||
sizes__.clear();
|
sizes__.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AllocT>
|
||||||
|
void benchmark_alloc() {
|
||||||
|
std::cout << std::endl << type_name<AllocT>() << std::endl;
|
||||||
|
|
||||||
|
test_stopwatch sw;
|
||||||
|
sw.start();
|
||||||
|
|
||||||
|
for (std::size_t x = 0; x < 10; ++x)
|
||||||
|
for (std::size_t n = 0; n < LoopCount; ++n) {
|
||||||
|
std::size_t s = sizes__[n];
|
||||||
|
AllocT::free(AllocT::alloc(s), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::test_alloc_free() {
|
||||||
|
benchmark_alloc<ipc::mem::static_alloc>();
|
||||||
|
benchmark_alloc<ipc::mem::pool_alloc>();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename AllocT, typename ModeT, int ThreadsN>
|
template <typename AllocT, typename ModeT, int ThreadsN>
|
||||||
void benchmark_alloc() {
|
void benchmark_alloc() {
|
||||||
std::cout << std::endl
|
std::cout << std::endl
|
||||||
@ -126,7 +150,7 @@ void benchmark_alloc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (++fini == ThreadsN) {
|
if ((fini.fetch_add(1, std::memory_order_relaxed) + 1) == ThreadsN) {
|
||||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount);
|
sw.print_elapsed<1>(DataMin, DataMax, LoopCount);
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
@ -152,7 +176,7 @@ struct test_performance<AllocT, ModeT, 1> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Unit::test_alloc() {
|
void Unit::test_linear() {
|
||||||
// malloc
|
// malloc
|
||||||
test_performance<ipc::mem::static_alloc, alloc_random, 8>::start();
|
test_performance<ipc::mem::static_alloc, alloc_random, 8>::start();
|
||||||
test_performance<ipc::mem::static_alloc, alloc_LIFO , 8>::start();
|
test_performance<ipc::mem::static_alloc, alloc_LIFO , 8>::start();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user