mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 08:46:45 +08:00
ISSUE: MSVC compiler reports warning C4138: '*/' found outside of comment for patterns like 'void */*p*/' where the pointer asterisk is immediately followed by a comment start. AFFECTED FILES: - include/libipc/mem/new.h (line 30) - src/libipc/platform/win/mutex.h (line 54) - src/libipc/platform/win/semaphore.h (line 53) CHANGES: Changed 'type */*param*/' to 'type * /*param*/' (added space before comment) Examples: - void */*p*/ → void * /*p*/ - char const */*name*/ → char const * /*name*/ This resolves the MSVC warning while maintaining code functionality and keeping the commented-out parameter names for documentation.
118 lines
3.7 KiB
C++
118 lines
3.7 KiB
C++
/**
|
|
* \file libipc/mem.h
|
|
* \author mutouyun (orz@orzz.org)
|
|
* \brief Global memory management.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <algorithm>
|
|
#include <type_traits>
|
|
#include <limits>
|
|
#include <tuple>
|
|
|
|
#include "libipc/imp/aligned.h"
|
|
#include "libipc/imp/uninitialized.h"
|
|
#include "libipc/imp/byte.h"
|
|
#include "libipc/imp/detect_plat.h"
|
|
#include "libipc/imp/export.h"
|
|
#include "libipc/mem/memory_resource.h"
|
|
#include "libipc/mem/block_pool.h"
|
|
|
|
namespace ipc {
|
|
namespace mem {
|
|
|
|
/// \brief Defines the memory block collector interface.
|
|
class LIBIPC_EXPORT block_collector {
|
|
public:
|
|
virtual ~block_collector() noexcept = default;
|
|
virtual void *allocate(std::size_t /*bytes*/) noexcept = 0;
|
|
virtual void deallocate(void * /*p*/, std::size_t /*bytes*/) noexcept = 0;
|
|
};
|
|
|
|
/// \brief Matches the appropriate memory block resource based on a specified size.
|
|
LIBIPC_EXPORT block_collector &get_regular_resource(std::size_t s) noexcept;
|
|
|
|
/// \brief Allocates storage with a size of at least bytes bytes.
|
|
LIBIPC_EXPORT void *alloc(std::size_t bytes) noexcept;
|
|
LIBIPC_EXPORT void free (void *p, std::size_t bytes) noexcept;
|
|
|
|
namespace detail_new {
|
|
|
|
#if defined(LIBIPC_CPP_17)
|
|
using recycle_t = void (*)(void *p) noexcept;
|
|
#else
|
|
using recycle_t = void (*)(void *p);
|
|
#endif
|
|
|
|
static constexpr std::size_t recycler_size = round_up(sizeof(recycle_t), alignof(std::size_t));
|
|
static constexpr std::size_t allocated_size = sizeof(std::size_t);
|
|
static constexpr std::size_t regular_head_size = round_up(recycler_size + allocated_size, alignof(std::max_align_t));
|
|
|
|
template <typename T>
|
|
struct do_allocate {
|
|
template <typename... A>
|
|
static T *apply(A &&... args) noexcept {
|
|
void *b = mem::alloc(regular_head_size + sizeof(T));
|
|
auto *p = static_cast<byte *>(b) + regular_head_size;
|
|
LIBIPC_TRY {
|
|
T *t = construct<T>(p, std::forward<A>(args)...);
|
|
*reinterpret_cast<recycle_t *>(b)
|
|
= [](void *p) noexcept {
|
|
mem::free(static_cast<byte *>(destroy(static_cast<T *>(p))) - regular_head_size
|
|
, regular_head_size + sizeof(T));
|
|
};
|
|
return t;
|
|
} LIBIPC_CATCH(...) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct do_allocate<void> {
|
|
static void *apply(std::size_t bytes) noexcept {
|
|
if (bytes == 0) return nullptr;
|
|
std::size_t rbz = regular_head_size + bytes;
|
|
void *b = mem::alloc(rbz);
|
|
*reinterpret_cast<recycle_t *>(b)
|
|
= [](void *p) noexcept {
|
|
auto *b = static_cast<byte *>(p) - regular_head_size;
|
|
mem::free(b, *reinterpret_cast<std::size_t *>(b + recycler_size));
|
|
};
|
|
auto *z = static_cast<byte *>(b) + recycler_size;
|
|
*reinterpret_cast<std::size_t *>(z) = rbz;
|
|
return static_cast<byte *>(b) + regular_head_size;
|
|
}
|
|
};
|
|
|
|
} // namespace detail_new
|
|
|
|
/// \brief Creates an object based on the specified type and parameters with block pool resource.
|
|
/// \note This function is thread-safe.
|
|
template <typename T, typename... A>
|
|
T *$new(A &&... args) noexcept {
|
|
return detail_new::do_allocate<T>::apply(std::forward<A>(args)...);
|
|
}
|
|
|
|
/// \brief Destroys object previously allocated by the `$new` and releases obtained memory area.
|
|
/// \note This function is thread-safe. If the pointer type passed in is different from `$new`,
|
|
/// additional performance penalties may be incurred.
|
|
inline void $delete(void *p) noexcept {
|
|
if (p == nullptr) return;
|
|
auto *r = reinterpret_cast<detail_new::recycle_t *>(static_cast<byte *>(p) - detail_new::regular_head_size);
|
|
(*r)(p);
|
|
}
|
|
|
|
/// \brief The destruction policy used by std::unique_ptr.
|
|
/// \see https://en.cppreference.com/w/cpp/memory/default_delete
|
|
struct deleter {
|
|
template <typename T>
|
|
void operator()(T *p) const noexcept {
|
|
$delete(p);
|
|
}
|
|
};
|
|
|
|
} // namespace mem
|
|
} // namespace ipc
|