make pool_alloc public

This commit is contained in:
mutouyun 2018-12-30 20:34:00 +08:00
parent e6fab3edeb
commit cba780e9dc
7 changed files with 100 additions and 44 deletions

View File

@ -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
View 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

View File

@ -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
View 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

View File

@ -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 });
}}; }};

View File

@ -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;

View File

@ -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();