diff --git a/src/libipc/ipc.cpp b/src/libipc/ipc.cpp index fe699e6..7b13c75 100755 --- a/src/libipc/ipc.cpp +++ b/src/libipc/ipc.cpp @@ -25,7 +25,7 @@ #include "libipc/utility/scope_guard.h" #include "libipc/utility/utility.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/platform/detail.h" #include "libipc/circ/elem_array.h" diff --git a/src/libipc/memory/resource.h b/src/libipc/mem/resource.h similarity index 100% rename from src/libipc/memory/resource.h rename to src/libipc/mem/resource.h diff --git a/src/libipc/platform/linux/mutex.h b/src/libipc/platform/linux/mutex.h index e962864..021e006 100644 --- a/src/libipc/platform/linux/mutex.h +++ b/src/libipc/platform/linux/mutex.h @@ -7,7 +7,7 @@ #include "libipc/platform/detail.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/shm.h" #include "get_wait_time.h" diff --git a/src/libipc/platform/posix/mutex.h b/src/libipc/platform/posix/mutex.h index 51c89e4..4d438b7 100644 --- a/src/libipc/platform/posix/mutex.h +++ b/src/libipc/platform/posix/mutex.h @@ -12,7 +12,7 @@ #include "libipc/platform/detail.h" #include "libipc/utility/log.h" #include "libipc/utility/scope_guard.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/shm.h" #include "get_wait_time.h" diff --git a/src/libipc/platform/posix/shm_posix.cpp b/src/libipc/platform/posix/shm_posix.cpp index a5ac7b5..7221d05 100644 --- a/src/libipc/platform/posix/shm_posix.cpp +++ b/src/libipc/platform/posix/shm_posix.cpp @@ -16,7 +16,7 @@ #include "libipc/pool_alloc.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" namespace { diff --git a/src/libipc/platform/win/shm_win.cpp b/src/libipc/platform/win/shm_win.cpp index 0b7bcc0..cad73a6 100755 --- a/src/libipc/platform/win/shm_win.cpp +++ b/src/libipc/platform/win/shm_win.cpp @@ -1,185 +1,185 @@ - -#if defined(__MINGW32__) -#include -#else -#include -#endif - -#include -#include -#include - -#include "libipc/shm.h" -#include "libipc/def.h" -#include "libipc/pool_alloc.h" - -#include "libipc/utility/log.h" -#include "libipc/memory/resource.h" - -#include "to_tchar.h" -#include "get_sa.h" - -namespace { - -struct info_t { - std::atomic acc_; -}; - -struct id_info_t { - HANDLE h_ = NULL; - void* mem_ = nullptr; - std::size_t size_ = 0; -}; - -constexpr std::size_t calc_size(std::size_t size) { - return ((((size - 1) / alignof(info_t)) + 1) * alignof(info_t)) + sizeof(info_t); -} - -inline auto& acc_of(void* mem, std::size_t size) { - return reinterpret_cast(static_cast(mem) + size - sizeof(info_t))->acc_; -} - -} // internal-linkage - -namespace ipc { -namespace shm { - -id_t acquire(char const * name, std::size_t size, unsigned mode) { - if (!is_valid_string(name)) { - ipc::error("fail acquire: name is empty\n"); - return nullptr; - } - HANDLE h; - auto fmt_name = ipc::detail::to_tchar(name); - // Opens a named file mapping object. - if (mode == open) { - h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fmt_name.c_str()); - if (h == NULL) { - ipc::error("fail OpenFileMapping[%d]: %s\n", static_cast(::GetLastError()), name); - return nullptr; - } - } - // Creates or opens a named file mapping object for a specified file. - else { - std::size_t alloc_size = calc_size(size); - h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT, - 0, static_cast(alloc_size), fmt_name.c_str()); - DWORD err = ::GetLastError(); - // 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. - if ((mode == create) && (err == ERROR_ALREADY_EXISTS)) { - if (h != NULL) ::CloseHandle(h); - h = NULL; - } - if (h == NULL) { - ipc::error("fail CreateFileMapping[%d]: %s\n", static_cast(err), name); - return nullptr; - } - } - auto ii = mem::alloc(); - ii->h_ = h; - ii->size_ = size; - return ii; -} - -std::int32_t get_ref(id_t id) { - if (id == nullptr) { - return 0; - } - auto ii = static_cast(id); - if (ii->mem_ == nullptr || ii->size_ == 0) { - return 0; - } - return acc_of(ii->mem_, calc_size(ii->size_)).load(std::memory_order_acquire); -} - -void sub_ref(id_t id) { - if (id == nullptr) { - ipc::error("fail sub_ref: invalid id (null)\n"); - return; - } - auto ii = static_cast(id); - if (ii->mem_ == nullptr || ii->size_ == 0) { - ipc::error("fail sub_ref: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_); - return; - } - 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) { - if (id == nullptr) { - ipc::error("fail get_mem: invalid id (null)\n"); - return nullptr; - } - auto ii = static_cast(id); - if (ii->mem_ != nullptr) { - if (size != nullptr) *size = ii->size_; - return ii->mem_; - } - if (ii->h_ == NULL) { - ipc::error("fail to_mem: invalid id (h = null)\n"); - return nullptr; - } - LPVOID mem = ::MapViewOfFile(ii->h_, FILE_MAP_ALL_ACCESS, 0, 0, 0); - if (mem == NULL) { - ipc::error("fail MapViewOfFile[%d]\n", static_cast(::GetLastError())); - return nullptr; - } - MEMORY_BASIC_INFORMATION mem_info; - if (::VirtualQuery(mem, &mem_info, sizeof(mem_info)) == 0) { - ipc::error("fail VirtualQuery[%d]\n", static_cast(::GetLastError())); - return nullptr; - } - std::size_t actual_size = static_cast(mem_info.RegionSize); - if (ii->size_ == 0) { - // Opening existing shared memory - ii->size_ = actual_size - sizeof(info_t); - } - // else: Keep user-requested size (already set in acquire) - ii->mem_ = mem; - if (size != nullptr) *size = ii->size_; - // Initialize or increment reference counter - acc_of(mem, calc_size(ii->size_)).fetch_add(1, std::memory_order_release); - return static_cast(mem); -} - -std::int32_t release(id_t id) noexcept { - if (id == nullptr) { - ipc::error("fail release: invalid id (null)\n"); - return -1; - } - std::int32_t ret = -1; - auto ii = static_cast(id); - if (ii->mem_ == nullptr || ii->size_ == 0) { - ipc::error("fail release: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_); - } - else { - ret = acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel); - ::UnmapViewOfFile(static_cast(ii->mem_)); - } - if (ii->h_ == NULL) { - ipc::error("fail release: invalid id (h = null)\n"); - } - else ::CloseHandle(ii->h_); - mem::free(ii); - return ret; -} - -void remove(id_t id) noexcept { - if (id == nullptr) { - ipc::error("fail release: invalid id (null)\n"); - return; - } - release(id); -} - -void remove(char const * name) noexcept { - if (!is_valid_string(name)) { - ipc::error("fail remove: name is empty\n"); - return; - } - // Do Nothing. -} - -} // namespace shm -} // namespace ipc + +#if defined(__MINGW32__) +#include +#else +#include +#endif + +#include +#include +#include + +#include "libipc/shm.h" +#include "libipc/def.h" +#include "libipc/pool_alloc.h" + +#include "libipc/utility/log.h" +#include "libipc/mem/resource.h" + +#include "to_tchar.h" +#include "get_sa.h" + +namespace { + +struct info_t { + std::atomic acc_; +}; + +struct id_info_t { + HANDLE h_ = NULL; + void* mem_ = nullptr; + std::size_t size_ = 0; +}; + +constexpr std::size_t calc_size(std::size_t size) { + return ((((size - 1) / alignof(info_t)) + 1) * alignof(info_t)) + sizeof(info_t); +} + +inline auto& acc_of(void* mem, std::size_t size) { + return reinterpret_cast(static_cast(mem) + size - sizeof(info_t))->acc_; +} + +} // internal-linkage + +namespace ipc { +namespace shm { + +id_t acquire(char const * name, std::size_t size, unsigned mode) { + if (!is_valid_string(name)) { + ipc::error("fail acquire: name is empty\n"); + return nullptr; + } + HANDLE h; + auto fmt_name = ipc::detail::to_tchar(name); + // Opens a named file mapping object. + if (mode == open) { + h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fmt_name.c_str()); + if (h == NULL) { + ipc::error("fail OpenFileMapping[%d]: %s\n", static_cast(::GetLastError()), name); + return nullptr; + } + } + // Creates or opens a named file mapping object for a specified file. + else { + std::size_t alloc_size = calc_size(size); + h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT, + 0, static_cast(alloc_size), fmt_name.c_str()); + DWORD err = ::GetLastError(); + // 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. + if ((mode == create) && (err == ERROR_ALREADY_EXISTS)) { + if (h != NULL) ::CloseHandle(h); + h = NULL; + } + if (h == NULL) { + ipc::error("fail CreateFileMapping[%d]: %s\n", static_cast(err), name); + return nullptr; + } + } + auto ii = mem::alloc(); + ii->h_ = h; + ii->size_ = size; + return ii; +} + +std::int32_t get_ref(id_t id) { + if (id == nullptr) { + return 0; + } + auto ii = static_cast(id); + if (ii->mem_ == nullptr || ii->size_ == 0) { + return 0; + } + return acc_of(ii->mem_, calc_size(ii->size_)).load(std::memory_order_acquire); +} + +void sub_ref(id_t id) { + if (id == nullptr) { + ipc::error("fail sub_ref: invalid id (null)\n"); + return; + } + auto ii = static_cast(id); + if (ii->mem_ == nullptr || ii->size_ == 0) { + ipc::error("fail sub_ref: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_); + return; + } + 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) { + if (id == nullptr) { + ipc::error("fail get_mem: invalid id (null)\n"); + return nullptr; + } + auto ii = static_cast(id); + if (ii->mem_ != nullptr) { + if (size != nullptr) *size = ii->size_; + return ii->mem_; + } + if (ii->h_ == NULL) { + ipc::error("fail to_mem: invalid id (h = null)\n"); + return nullptr; + } + LPVOID mem = ::MapViewOfFile(ii->h_, FILE_MAP_ALL_ACCESS, 0, 0, 0); + if (mem == NULL) { + ipc::error("fail MapViewOfFile[%d]\n", static_cast(::GetLastError())); + return nullptr; + } + MEMORY_BASIC_INFORMATION mem_info; + if (::VirtualQuery(mem, &mem_info, sizeof(mem_info)) == 0) { + ipc::error("fail VirtualQuery[%d]\n", static_cast(::GetLastError())); + return nullptr; + } + std::size_t actual_size = static_cast(mem_info.RegionSize); + if (ii->size_ == 0) { + // Opening existing shared memory + ii->size_ = actual_size - sizeof(info_t); + } + // else: Keep user-requested size (already set in acquire) + ii->mem_ = mem; + if (size != nullptr) *size = ii->size_; + // Initialize or increment reference counter + acc_of(mem, calc_size(ii->size_)).fetch_add(1, std::memory_order_release); + return static_cast(mem); +} + +std::int32_t release(id_t id) noexcept { + if (id == nullptr) { + ipc::error("fail release: invalid id (null)\n"); + return -1; + } + std::int32_t ret = -1; + auto ii = static_cast(id); + if (ii->mem_ == nullptr || ii->size_ == 0) { + ipc::error("fail release: invalid id (mem = %p, size = %zd)\n", ii->mem_, ii->size_); + } + else { + ret = acc_of(ii->mem_, calc_size(ii->size_)).fetch_sub(1, std::memory_order_acq_rel); + ::UnmapViewOfFile(static_cast(ii->mem_)); + } + if (ii->h_ == NULL) { + ipc::error("fail release: invalid id (h = null)\n"); + } + else ::CloseHandle(ii->h_); + mem::free(ii); + return ret; +} + +void remove(id_t id) noexcept { + if (id == nullptr) { + ipc::error("fail release: invalid id (null)\n"); + return; + } + release(id); +} + +void remove(char const * name) noexcept { + if (!is_valid_string(name)) { + ipc::error("fail remove: name is empty\n"); + return; + } + // Do Nothing. +} + +} // namespace shm +} // namespace ipc diff --git a/src/libipc/platform/win/to_tchar.h b/src/libipc/platform/win/to_tchar.h index 79310c4..7584820 100755 --- a/src/libipc/platform/win/to_tchar.h +++ b/src/libipc/platform/win/to_tchar.h @@ -15,7 +15,7 @@ #include #include "libipc/utility/concept.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/platform/detail.h" namespace ipc { diff --git a/src/libipc/pool_alloc.cpp b/src/libipc/pool_alloc.cpp index 9824df9..b84e73b 100755 --- a/src/libipc/pool_alloc.cpp +++ b/src/libipc/pool_alloc.cpp @@ -1,6 +1,6 @@ #include "libipc/pool_alloc.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" namespace ipc { namespace mem { diff --git a/src/libipc/queue.h b/src/libipc/queue.h index 86b4dfa..5000bad 100755 --- a/src/libipc/queue.h +++ b/src/libipc/queue.h @@ -18,7 +18,7 @@ #include "libipc/utility/log.h" #include "libipc/platform/detail.h" #include "libipc/circ/elem_def.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" namespace ipc { namespace detail { diff --git a/src/libipc/shm.cpp b/src/libipc/shm.cpp index ecf4ac0..40a374e 100755 --- a/src/libipc/shm.cpp +++ b/src/libipc/shm.cpp @@ -6,7 +6,7 @@ #include "libipc/utility/pimpl.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" namespace ipc { namespace shm { diff --git a/src/libipc/sync/condition.cpp b/src/libipc/sync/condition.cpp index dbb5745..c6afccb 100644 --- a/src/libipc/sync/condition.cpp +++ b/src/libipc/sync/condition.cpp @@ -3,7 +3,7 @@ #include "libipc/utility/pimpl.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/platform/detail.h" #if defined(LIBIPC_OS_WIN) #include "libipc/platform/win/condition.h" diff --git a/src/libipc/sync/mutex.cpp b/src/libipc/sync/mutex.cpp index 3e1c3fe..aa7fc08 100644 --- a/src/libipc/sync/mutex.cpp +++ b/src/libipc/sync/mutex.cpp @@ -3,7 +3,7 @@ #include "libipc/utility/pimpl.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/platform/detail.h" #if defined(LIBIPC_OS_WIN) #include "libipc/platform/win/mutex.h" diff --git a/src/libipc/sync/semaphore.cpp b/src/libipc/sync/semaphore.cpp index 42f78ae..29665c8 100644 --- a/src/libipc/sync/semaphore.cpp +++ b/src/libipc/sync/semaphore.cpp @@ -3,7 +3,7 @@ #include "libipc/utility/pimpl.h" #include "libipc/utility/log.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "libipc/platform/detail.h" #if defined(LIBIPC_OS_WIN) #include "libipc/platform/win/semaphore.h" diff --git a/test/archive/test_ipc.cpp b/test/archive/test_ipc.cpp index 5bd828b..a482fcb 100755 --- a/test/archive/test_ipc.cpp +++ b/test/archive/test_ipc.cpp @@ -7,7 +7,7 @@ #include "libipc/ipc.h" #include "libipc/buffer.h" -#include "libipc/memory/resource.h" +#include "libipc/mem/resource.h" #include "test.h" #include "thread_pool.h" diff --git a/test/archive/test_mem.cpp b/test/archive/test_mem.cpp deleted file mode 100755 index 16a5ad1..0000000 --- a/test/archive/test_mem.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include -#include -#include -#include -#include - -#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 sizes__; -std::vector ptr_cache__[ThreadMax]; - -template -struct alloc_ix_t { - static std::vector ix_; - static bool inited_; - - alloc_ix_t() { - if (inited_) return; - inited_ = true; - M::init(); - } - - template - static int index(std::size_t /*pid*/, std::size_t /*k*/, std::size_t n) { - return ix_[n]; - } -}; - -template -std::vector alloc_ix_t::ix_(LoopCount); -template -bool alloc_ix_t::inited_ = false; - -struct alloc_FIFO : alloc_ix_t { - static void init() { - for (int i = 0; i < LoopCount; ++i) { - ix_[static_cast(i)] = i; - } - } -}; - -struct alloc_LIFO : alloc_ix_t { - static void init() { - for (int i = 0; i < LoopCount; ++i) { - ix_[static_cast(i)] = i; - } - } - - template - 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 { - static void init() { - capo::random<> rdm_index(0, LoopCount - 1); - for (int i = 0; i < LoopCount; ++i) { - ix_[static_cast(i)] = rdm_index(); - } - } -}; - -struct Init { - Init() { - capo::random<> rdm{ DataMin, DataMax }; - for (int i = 0; i < LoopCount; ++i) { - sizes__.emplace_back(static_cast(rdm())); - } - for (auto& vec : ptr_cache__) { - vec.resize(LoopCount, nullptr); - } - } -} init__; - -template -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(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 -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(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(pid, k, n); - void*& p = vec[static_cast(m)]; - std::size_t s = sizes__[static_cast(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 -struct test_performance { - static void start(char const * message) { - test_performance::start(message); - benchmark_alloc(message); - } -}; - -template -struct test_performance { - static void start(char const * message) { - benchmark_alloc(message); - } -}; - -template -struct test_performance { - static void start(char const * message) { - test_performance::start(message); - benchmark_alloc(message); - } -}; - -template -struct test_performance { - static void start(char const * message) { - benchmark_alloc(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::start("alloc-free"); - test_performance::start("alloc-FIFO"); - test_performance::start("alloc-LIFO"); - test_performance::start("alloc-Rand"); -} - -TEST(Memory, pool_alloc) { - test_performance::start("alloc-free"); - test_performance::start("alloc-FIFO"); - test_performance::start("alloc-LIFO"); - test_performance::start("alloc-Rand"); -} -*/ -// TEST(Memory, tc_alloc) { -// test_performance::start(); -// test_performance::start(); -// test_performance::start(); -// test_performance::start(); -// } - -} // internal-linkage