mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
libipc/memory/resource.h => libipc/mem/resource.h
This commit is contained in:
parent
e3c1755b9a
commit
ef9d3b3642
@ -25,7 +25,7 @@
|
|||||||
#include "libipc/utility/scope_guard.h"
|
#include "libipc/utility/scope_guard.h"
|
||||||
#include "libipc/utility/utility.h"
|
#include "libipc/utility/utility.h"
|
||||||
|
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#include "libipc/circ/elem_array.h"
|
#include "libipc/circ/elem_array.h"
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/shm.h"
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
#include "get_wait_time.h"
|
#include "get_wait_time.h"
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/utility/scope_guard.h"
|
#include "libipc/utility/scope_guard.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/shm.h"
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
#include "get_wait_time.h"
|
#include "get_wait_time.h"
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
#include "libipc/pool_alloc.h"
|
#include "libipc/pool_alloc.h"
|
||||||
|
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|||||||
@ -1,185 +1,185 @@
|
|||||||
|
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "libipc/shm.h"
|
#include "libipc/shm.h"
|
||||||
#include "libipc/def.h"
|
#include "libipc/def.h"
|
||||||
#include "libipc/pool_alloc.h"
|
#include "libipc/pool_alloc.h"
|
||||||
|
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
#include "to_tchar.h"
|
#include "to_tchar.h"
|
||||||
#include "get_sa.h"
|
#include "get_sa.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct info_t {
|
struct info_t {
|
||||||
std::atomic<std::int32_t> acc_;
|
std::atomic<std::int32_t> acc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct id_info_t {
|
struct id_info_t {
|
||||||
HANDLE h_ = NULL;
|
HANDLE h_ = NULL;
|
||||||
void* mem_ = nullptr;
|
void* mem_ = nullptr;
|
||||||
std::size_t size_ = 0;
|
std::size_t size_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::size_t calc_size(std::size_t size) {
|
constexpr std::size_t calc_size(std::size_t size) {
|
||||||
return ((((size - 1) / alignof(info_t)) + 1) * alignof(info_t)) + sizeof(info_t);
|
return ((((size - 1) / alignof(info_t)) + 1) * alignof(info_t)) + sizeof(info_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto& acc_of(void* mem, std::size_t size) {
|
inline auto& acc_of(void* mem, std::size_t size) {
|
||||||
return reinterpret_cast<info_t*>(static_cast<ipc::byte_t*>(mem) + size - sizeof(info_t))->acc_;
|
return reinterpret_cast<info_t*>(static_cast<ipc::byte_t*>(mem) + size - sizeof(info_t))->acc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // internal-linkage
|
} // internal-linkage
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
namespace shm {
|
namespace shm {
|
||||||
|
|
||||||
id_t acquire(char const * name, std::size_t size, unsigned mode) {
|
id_t acquire(char const * name, std::size_t size, unsigned mode) {
|
||||||
if (!is_valid_string(name)) {
|
if (!is_valid_string(name)) {
|
||||||
ipc::error("fail acquire: name is empty\n");
|
ipc::error("fail acquire: name is empty\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
auto fmt_name = ipc::detail::to_tchar(name);
|
auto fmt_name = ipc::detail::to_tchar(name);
|
||||||
// Opens a named file mapping object.
|
// Opens a named file mapping object.
|
||||||
if (mode == open) {
|
if (mode == open) {
|
||||||
h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fmt_name.c_str());
|
h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fmt_name.c_str());
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
ipc::error("fail OpenFileMapping[%d]: %s\n", static_cast<int>(::GetLastError()), name);
|
ipc::error("fail OpenFileMapping[%d]: %s\n", static_cast<int>(::GetLastError()), name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Creates or opens a named file mapping object for a specified file.
|
// Creates or opens a named file mapping object for a specified file.
|
||||||
else {
|
else {
|
||||||
std::size_t alloc_size = calc_size(size);
|
std::size_t alloc_size = calc_size(size);
|
||||||
h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT,
|
h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT,
|
||||||
0, static_cast<DWORD>(alloc_size), fmt_name.c_str());
|
0, static_cast<DWORD>(alloc_size), fmt_name.c_str());
|
||||||
DWORD err = ::GetLastError();
|
DWORD err = ::GetLastError();
|
||||||
// If the object exists before the function call, the function returns a handle to the existing object
|
// If the object exists before the function call, the function returns a handle to the existing object
|
||||||
// (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
|
// (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
|
||||||
if ((mode == create) && (err == ERROR_ALREADY_EXISTS)) {
|
if ((mode == create) && (err == ERROR_ALREADY_EXISTS)) {
|
||||||
if (h != NULL) ::CloseHandle(h);
|
if (h != NULL) ::CloseHandle(h);
|
||||||
h = NULL;
|
h = NULL;
|
||||||
}
|
}
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
ipc::error("fail CreateFileMapping[%d]: %s\n", static_cast<int>(err), name);
|
ipc::error("fail CreateFileMapping[%d]: %s\n", static_cast<int>(err), name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto ii = mem::alloc<id_info_t>();
|
auto ii = mem::alloc<id_info_t>();
|
||||||
ii->h_ = h;
|
ii->h_ = h;
|
||||||
ii->size_ = size;
|
ii->size_ = size;
|
||||||
return ii;
|
return ii;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int32_t get_ref(id_t id) {
|
std::int32_t get_ref(id_t id) {
|
||||||
if (id == nullptr) {
|
if (id == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto ii = static_cast<id_info_t*>(id);
|
auto ii = static_cast<id_info_t*>(id);
|
||||||
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return acc_of(ii->mem_, calc_size(ii->size_)).load(std::memory_order_acquire);
|
return acc_of(ii->mem_, calc_size(ii->size_)).load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sub_ref(id_t id) {
|
void sub_ref(id_t id) {
|
||||||
if (id == nullptr) {
|
if (id == nullptr) {
|
||||||
ipc::error("fail sub_ref: invalid id (null)\n");
|
ipc::error("fail sub_ref: invalid id (null)\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto ii = static_cast<id_info_t*>(id);
|
auto ii = static_cast<id_info_t*>(id);
|
||||||
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
||||||
ipc::error("fail sub_ref: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_);
|
ipc::error("fail sub_ref: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel);
|
acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * get_mem(id_t id, std::size_t * size) {
|
void * get_mem(id_t id, std::size_t * size) {
|
||||||
if (id == nullptr) {
|
if (id == nullptr) {
|
||||||
ipc::error("fail get_mem: invalid id (null)\n");
|
ipc::error("fail get_mem: invalid id (null)\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto ii = static_cast<id_info_t*>(id);
|
auto ii = static_cast<id_info_t*>(id);
|
||||||
if (ii->mem_ != nullptr) {
|
if (ii->mem_ != nullptr) {
|
||||||
if (size != nullptr) *size = ii->size_;
|
if (size != nullptr) *size = ii->size_;
|
||||||
return ii->mem_;
|
return ii->mem_;
|
||||||
}
|
}
|
||||||
if (ii->h_ == NULL) {
|
if (ii->h_ == NULL) {
|
||||||
ipc::error("fail to_mem: invalid id (h = null)\n");
|
ipc::error("fail to_mem: invalid id (h = null)\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
LPVOID mem = ::MapViewOfFile(ii->h_, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
LPVOID mem = ::MapViewOfFile(ii->h_, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
ipc::error("fail MapViewOfFile[%d]\n", static_cast<int>(::GetLastError()));
|
ipc::error("fail MapViewOfFile[%d]\n", static_cast<int>(::GetLastError()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
MEMORY_BASIC_INFORMATION mem_info;
|
MEMORY_BASIC_INFORMATION mem_info;
|
||||||
if (::VirtualQuery(mem, &mem_info, sizeof(mem_info)) == 0) {
|
if (::VirtualQuery(mem, &mem_info, sizeof(mem_info)) == 0) {
|
||||||
ipc::error("fail VirtualQuery[%d]\n", static_cast<int>(::GetLastError()));
|
ipc::error("fail VirtualQuery[%d]\n", static_cast<int>(::GetLastError()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::size_t actual_size = static_cast<std::size_t>(mem_info.RegionSize);
|
std::size_t actual_size = static_cast<std::size_t>(mem_info.RegionSize);
|
||||||
if (ii->size_ == 0) {
|
if (ii->size_ == 0) {
|
||||||
// Opening existing shared memory
|
// Opening existing shared memory
|
||||||
ii->size_ = actual_size - sizeof(info_t);
|
ii->size_ = actual_size - sizeof(info_t);
|
||||||
}
|
}
|
||||||
// else: Keep user-requested size (already set in acquire)
|
// else: Keep user-requested size (already set in acquire)
|
||||||
ii->mem_ = mem;
|
ii->mem_ = mem;
|
||||||
if (size != nullptr) *size = ii->size_;
|
if (size != nullptr) *size = ii->size_;
|
||||||
// Initialize or increment reference counter
|
// Initialize or increment reference counter
|
||||||
acc_of(mem, calc_size(ii->size_)).fetch_add(1, std::memory_order_release);
|
acc_of(mem, calc_size(ii->size_)).fetch_add(1, std::memory_order_release);
|
||||||
return static_cast<void *>(mem);
|
return static_cast<void *>(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int32_t release(id_t id) noexcept {
|
std::int32_t release(id_t id) noexcept {
|
||||||
if (id == nullptr) {
|
if (id == nullptr) {
|
||||||
ipc::error("fail release: invalid id (null)\n");
|
ipc::error("fail release: invalid id (null)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::int32_t ret = -1;
|
std::int32_t ret = -1;
|
||||||
auto ii = static_cast<id_info_t*>(id);
|
auto ii = static_cast<id_info_t*>(id);
|
||||||
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
if (ii->mem_ == nullptr || ii->size_ == 0) {
|
||||||
ipc::error("fail release: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_);
|
ipc::error("fail release: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel);
|
ret = acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel);
|
||||||
::UnmapViewOfFile(static_cast<LPCVOID>(ii->mem_));
|
::UnmapViewOfFile(static_cast<LPCVOID>(ii->mem_));
|
||||||
}
|
}
|
||||||
if (ii->h_ == NULL) {
|
if (ii->h_ == NULL) {
|
||||||
ipc::error("fail release: invalid id (h = null)\n");
|
ipc::error("fail release: invalid id (h = null)\n");
|
||||||
}
|
}
|
||||||
else ::CloseHandle(ii->h_);
|
else ::CloseHandle(ii->h_);
|
||||||
mem::free(ii);
|
mem::free(ii);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(id_t id) noexcept {
|
void remove(id_t id) noexcept {
|
||||||
if (id == nullptr) {
|
if (id == nullptr) {
|
||||||
ipc::error("fail release: invalid id (null)\n");
|
ipc::error("fail release: invalid id (null)\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
release(id);
|
release(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(char const * name) noexcept {
|
void remove(char const * name) noexcept {
|
||||||
if (!is_valid_string(name)) {
|
if (!is_valid_string(name)) {
|
||||||
ipc::error("fail remove: name is empty\n");
|
ipc::error("fail remove: name is empty\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do Nothing.
|
// Do Nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace shm
|
} // namespace shm
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "libipc/utility/concept.h"
|
#include "libipc/utility/concept.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "libipc/pool_alloc.h"
|
#include "libipc/pool_alloc.h"
|
||||||
|
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#include "libipc/circ/elem_def.h"
|
#include "libipc/circ/elem_def.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "libipc/utility/pimpl.h"
|
#include "libipc/utility/pimpl.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
namespace shm {
|
namespace shm {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "libipc/utility/pimpl.h"
|
#include "libipc/utility/pimpl.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#if defined(LIBIPC_OS_WIN)
|
#if defined(LIBIPC_OS_WIN)
|
||||||
#include "libipc/platform/win/condition.h"
|
#include "libipc/platform/win/condition.h"
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "libipc/utility/pimpl.h"
|
#include "libipc/utility/pimpl.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#if defined(LIBIPC_OS_WIN)
|
#if defined(LIBIPC_OS_WIN)
|
||||||
#include "libipc/platform/win/mutex.h"
|
#include "libipc/platform/win/mutex.h"
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "libipc/utility/pimpl.h"
|
#include "libipc/utility/pimpl.h"
|
||||||
#include "libipc/utility/log.h"
|
#include "libipc/utility/log.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
#include "libipc/platform/detail.h"
|
#include "libipc/platform/detail.h"
|
||||||
#if defined(LIBIPC_OS_WIN)
|
#if defined(LIBIPC_OS_WIN)
|
||||||
#include "libipc/platform/win/semaphore.h"
|
#include "libipc/platform/win/semaphore.h"
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "libipc/ipc.h"
|
#include "libipc/ipc.h"
|
||||||
#include "libipc/buffer.h"
|
#include "libipc/buffer.h"
|
||||||
#include "libipc/memory/resource.h"
|
#include "libipc/mem/resource.h"
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "thread_pool.h"
|
#include "thread_pool.h"
|
||||||
|
|||||||
@ -1,218 +0,0 @@
|
|||||||
#include <vector>
|
|
||||||
#include <array>
|
|
||||||
#include <thread>
|
|
||||||
#include <atomic>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include "capo/random.hpp"
|
|
||||||
|
|
||||||
#include "libipc/memory/resource.h"
|
|
||||||
#include "libipc/pool_alloc.h"
|
|
||||||
|
|
||||||
// #include "gperftools/tcmalloc.h"
|
|
||||||
|
|
||||||
#include "test.h"
|
|
||||||
#include "thread_pool.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr int DataMin = 4;
|
|
||||||
constexpr int DataMax = 256;
|
|
||||||
constexpr int LoopCount = 8388608;
|
|
||||||
constexpr int ThreadMax = 8;
|
|
||||||
|
|
||||||
// constexpr int DataMin = 256;
|
|
||||||
// constexpr int DataMax = 512;
|
|
||||||
// constexpr int LoopCount = 2097152;
|
|
||||||
|
|
||||||
std::vector<std::size_t> sizes__;
|
|
||||||
std::vector<void*> ptr_cache__[ThreadMax];
|
|
||||||
|
|
||||||
template <typename M>
|
|
||||||
struct alloc_ix_t {
|
|
||||||
static std::vector<int> ix_;
|
|
||||||
static bool inited_;
|
|
||||||
|
|
||||||
alloc_ix_t() {
|
|
||||||
if (inited_) return;
|
|
||||||
inited_ = true;
|
|
||||||
M::init();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int ThreadsN>
|
|
||||||
static int index(std::size_t /*pid*/, std::size_t /*k*/, std::size_t n) {
|
|
||||||
return ix_[n];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename M>
|
|
||||||
std::vector<int> alloc_ix_t<M>::ix_(LoopCount);
|
|
||||||
template <typename M>
|
|
||||||
bool alloc_ix_t<M>::inited_ = false;
|
|
||||||
|
|
||||||
struct alloc_FIFO : alloc_ix_t<alloc_FIFO> {
|
|
||||||
static void init() {
|
|
||||||
for (int i = 0; i < LoopCount; ++i) {
|
|
||||||
ix_[static_cast<std::size_t>(i)] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct alloc_LIFO : alloc_ix_t<alloc_LIFO> {
|
|
||||||
static void init() {
|
|
||||||
for (int i = 0; i < LoopCount; ++i) {
|
|
||||||
ix_[static_cast<std::size_t>(i)] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int ThreadsN>
|
|
||||||
static int index(std::size_t pid, std::size_t k, std::size_t n) {
|
|
||||||
constexpr static int CacheSize = LoopCount / ThreadsN;
|
|
||||||
if (k) {
|
|
||||||
return ix_[(CacheSize * (2 * pid + 1)) - 1 - n];
|
|
||||||
}
|
|
||||||
else return ix_[n];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct alloc_Random : alloc_ix_t<alloc_Random> {
|
|
||||||
static void init() {
|
|
||||||
capo::random<> rdm_index(0, LoopCount - 1);
|
|
||||||
for (int i = 0; i < LoopCount; ++i) {
|
|
||||||
ix_[static_cast<std::size_t>(i)] = rdm_index();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Init {
|
|
||||||
Init() {
|
|
||||||
capo::random<> rdm{ DataMin, DataMax };
|
|
||||||
for (int i = 0; i < LoopCount; ++i) {
|
|
||||||
sizes__.emplace_back(static_cast<std::size_t>(rdm()));
|
|
||||||
}
|
|
||||||
for (auto& vec : ptr_cache__) {
|
|
||||||
vec.resize(LoopCount, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} init__;
|
|
||||||
|
|
||||||
template <typename AllocT, int ThreadsN>
|
|
||||||
void benchmark_alloc(char const * message) {
|
|
||||||
std::string msg = std::to_string(ThreadsN) + "\t" + message;
|
|
||||||
|
|
||||||
constexpr static int CacheSize = LoopCount / ThreadsN;
|
|
||||||
ipc_ut::sender().start(static_cast<std::size_t>(ThreadsN));
|
|
||||||
ipc_ut::test_stopwatch sw;
|
|
||||||
|
|
||||||
for (int pid = 0; pid < ThreadsN; ++pid) {
|
|
||||||
ipc_ut::sender() << [&, pid] {
|
|
||||||
sw.start();
|
|
||||||
for (int n = (CacheSize * pid); n < (CacheSize * (pid + 1)); ++n) {
|
|
||||||
std::size_t s = sizes__[n];
|
|
||||||
AllocT::free(AllocT::alloc(s), s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc_ut::sender().wait_for_done();
|
|
||||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount, msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename AllocT, typename ModeT, int ThreadsN>
|
|
||||||
void benchmark_alloc(char const * message) {
|
|
||||||
std::string msg = std::to_string(ThreadsN) + "\t" + message;
|
|
||||||
|
|
||||||
constexpr static int CacheSize = LoopCount / ThreadsN;
|
|
||||||
ModeT mode;
|
|
||||||
ipc_ut::sender().start(static_cast<std::size_t>(ThreadsN));
|
|
||||||
ipc_ut::test_stopwatch sw;
|
|
||||||
|
|
||||||
for (int pid = 0; pid < ThreadsN; ++pid) {
|
|
||||||
ipc_ut::sender() << [&, pid] {
|
|
||||||
auto& vec = ptr_cache__[pid];
|
|
||||||
sw.start();
|
|
||||||
for (std::size_t k = 0; k < 2; ++k)
|
|
||||||
for (int n = (CacheSize * pid); n < (CacheSize * (pid + 1)); ++n) {
|
|
||||||
int m = mode.template index<ThreadsN>(pid, k, n);
|
|
||||||
void*& p = vec[static_cast<std::size_t>(m)];
|
|
||||||
std::size_t s = sizes__[static_cast<std::size_t>(m)];
|
|
||||||
if (p == nullptr) {
|
|
||||||
p = AllocT::alloc(s);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AllocT::free(p, s);
|
|
||||||
p = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc_ut::sender().wait_for_done();
|
|
||||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount, msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename AllocT, typename ModeT, int ThreadsN>
|
|
||||||
struct test_performance {
|
|
||||||
static void start(char const * message) {
|
|
||||||
test_performance<AllocT, ModeT, ThreadsN / 2>::start(message);
|
|
||||||
benchmark_alloc<AllocT, ModeT, ThreadsN>(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename AllocT, typename ModeT>
|
|
||||||
struct test_performance<AllocT, ModeT, 1> {
|
|
||||||
static void start(char const * message) {
|
|
||||||
benchmark_alloc<AllocT, ModeT, 1>(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename AllocT, int ThreadsN>
|
|
||||||
struct test_performance<AllocT, void, ThreadsN> {
|
|
||||||
static void start(char const * message) {
|
|
||||||
test_performance<AllocT, void, ThreadsN / 2>::start(message);
|
|
||||||
benchmark_alloc<AllocT, ThreadsN>(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename AllocT>
|
|
||||||
struct test_performance<AllocT, void, 1> {
|
|
||||||
static void start(char const * message) {
|
|
||||||
benchmark_alloc<AllocT, 1>(message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// class tc_alloc {
|
|
||||||
// public:
|
|
||||||
// static void clear() {}
|
|
||||||
|
|
||||||
// static void* alloc(std::size_t size) {
|
|
||||||
// return size ? tc_malloc(size) : nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static void free(void* p, std::size_t size) {
|
|
||||||
// tc_free_sized(p, size);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
/*
|
|
||||||
TEST(Memory, static_alloc) {
|
|
||||||
test_performance<ipc::mem::static_alloc, void , ThreadMax>::start("alloc-free");
|
|
||||||
test_performance<ipc::mem::static_alloc, alloc_FIFO , ThreadMax>::start("alloc-FIFO");
|
|
||||||
test_performance<ipc::mem::static_alloc, alloc_LIFO , ThreadMax>::start("alloc-LIFO");
|
|
||||||
test_performance<ipc::mem::static_alloc, alloc_Random, ThreadMax>::start("alloc-Rand");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Memory, pool_alloc) {
|
|
||||||
test_performance<ipc::mem::async_pool_alloc, void , ThreadMax>::start("alloc-free");
|
|
||||||
test_performance<ipc::mem::async_pool_alloc, alloc_FIFO , ThreadMax>::start("alloc-FIFO");
|
|
||||||
test_performance<ipc::mem::async_pool_alloc, alloc_LIFO , ThreadMax>::start("alloc-LIFO");
|
|
||||||
test_performance<ipc::mem::async_pool_alloc, alloc_Random, ThreadMax>::start("alloc-Rand");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// TEST(Memory, tc_alloc) {
|
|
||||||
// test_performance<tc_alloc, void , ThreadMax>::start();
|
|
||||||
// test_performance<tc_alloc, alloc_FIFO , ThreadMax>::start();
|
|
||||||
// test_performance<tc_alloc, alloc_LIFO , ThreadMax>::start();
|
|
||||||
// test_performance<tc_alloc, alloc_Random, ThreadMax>::start();
|
|
||||||
// }
|
|
||||||
|
|
||||||
} // internal-linkage
|
|
||||||
Loading…
x
Reference in New Issue
Block a user