123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * Copyright 2020 ByteDance Games, Inc. All Rights Reserved.
- *
- * Author: Liuziming <liuziming.kelvin@bytedance.com>
- */
- #pragma once
- #include <stdint.h>
- #include <stddef.h>
- #include <string.h>
- #include <assert.h>
- #include <utility>
- #include <unordered_map>
- #ifndef _MSC_VER
- #define SHM_LIKELY(exp) __builtin_expect(!!(exp), 1)
- #define SHM_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
- #define SHM_FORCE_INLINE __attribute__((always_inline))
- #else
- #define SHM_LIKELY(exp) (exp)
- #define SHM_UNLIKELY(exp) !(exp)
- #define SHM_FORCE_INLINE
- #endif
- namespace bg {
- enum ShmLogLevel {
- SHM_LOG_TRACE = 0,
- SHM_LOG_DEBUG,
- SHM_LOG_INFO,
- SHM_LOG_WARN,
- SHM_LOG_ERROR,
- SHM_LOG_FATAL
- };
- using ShmLogger = void(ShmLogLevel level, const char* file, size_t line, const char* func, const char* msg);
- namespace detail {
- class ShmManager;
- class TypeName;
- void ShmLog(ShmLogLevel level, const char* file, size_t line, const char* func, const char* fmt, ...);/* __attribute__((format(printf, 5, 6)));*/
- void ShmStdoutLog(ShmLogLevel level, const char* file, size_t line, const char* func, const char* msg);
- void* ShmAllocate(size_t bytes, const void*);
- void ShmDeallocate(void* ptr, size_t);
- uint64_t ShmCurrentVersion();
- void* ShmAllocateRawMemory(size_t* bytes, size_t alignment);
- bool ShmHasSingleton(const TypeName& type);
- void* ShmGetSingleton(const TypeName& type, size_t bytes, bool* first_call);
- void ShmFreeSingleton(const TypeName& type);
- class TypeName {
- public:
- explicit TypeName(const char* type, size_t size = 0);
- const char* data() const { return m_type; }
- size_t length() const { return strnlen(m_type, MAX_TYPE_NAME_LENGTH); }
- const char* c_str() const { return m_type; }
- bool operator<(const TypeName& that) const {
- return strncmp(m_type, that.m_type, MAX_TYPE_NAME_LENGTH) < 0;
- }
- bool operator==(const TypeName& that) const {
- return strncmp(m_type, that.m_type, MAX_TYPE_NAME_LENGTH) == 0;
- }
- bool operator!=(const TypeName& that) const {
- return strncmp(m_type, that.m_type, MAX_TYPE_NAME_LENGTH) != 0;
- }
- private:
- static const size_t MAX_TYPE_NAME_LENGTH = 1024;
- char m_type[MAX_TYPE_NAME_LENGTH];
- };
- struct TypeNameHasher {
- size_t operator()(const TypeName& type) const {
- return std::_Fnv1a_append_value(type.length(), type.data());
- }
- };
- struct ShmContext {
- ShmLogger* logger = ShmStdoutLog;
- ShmManager* mgr = nullptr;
- size_t mmap_size = 0;
- char path[256];
- ShmContext() {
- memset(path, 0x00, sizeof(path));
- }
- };
- template<typename T>
- struct VptrHelper {
- struct D : public T {
- // NOTE: The destructor is not required, it's added to avoid compiler warning.
- virtual ~D() = default;
- virtual void IntroduceVptr() {}
- };
- static const bool value = std::is_polymorphic<T>::value || (sizeof(D) == sizeof(T));
- };
- template<typename T>
- struct HasVptr : public std::integral_constant<bool, VptrHelper<T>::value> {};
- template<typename T>
- class ShmAllocator {
- public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
- template<typename U>
- struct rebind {
- typedef ShmAllocator<U> other;
- };
- ShmAllocator() = default;
- template<typename U>
- explicit ShmAllocator(const ShmAllocator<U>&) {}
- pointer address(reference x) const { return &x; }
- const_pointer address(const_reference x) const { return &x; }
- size_type max_size() const { return size_t(-1) / sizeof(T); }
- void construct(pointer p, const T& val) { ::new(p) T(val); }
- void construct(pointer p) { ::new(p) T(); }
- void destroy(pointer p) { p->~T(); }
- // This is the C++11 version of construct.
- template<typename U, typename... Args>
- void construct(U* u, Args&&... args) { ::new(u) U(std::forward<Args>(args)...); }
- // This is the C++11 version of destroy.
- template<typename U>
- void destroy(U* u) { u->~U(); }
- bool operator==(const ShmAllocator&) const { return true; }
- bool operator!=(const ShmAllocator&) const { return false; }
- pointer allocate(size_type n, const void* ptr = nullptr) {
- return static_cast<value_type*>(ShmAllocate(n * sizeof(value_type), ptr));
- }
- void deallocate(pointer ptr, size_type size = 0) {
- ShmDeallocate(ptr, size);
- }
- };
- } // namespace detail
- } // namespace bg
- #define __SHM_LOG(level, fmt, ...) bg::detail::ShmLog(level, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
- #define SHM_TRACE(fmt, ...) __SHM_LOG(bg::SHM_LOG_TRACE, fmt, ##__VA_ARGS__)
- #define SHM_DEBUG(fmt, ...) __SHM_LOG(bg::SHM_LOG_DEBUG, fmt, ##__VA_ARGS__)
- #define SHM_INFO(fmt, ...) __SHM_LOG(bg::SHM_LOG_INFO, fmt, ##__VA_ARGS__)
- #define SHM_WARN(fmt, ...) __SHM_LOG(bg::SHM_LOG_WARN, fmt, ##__VA_ARGS__)
- #define SHM_ERROR(fmt, ...) __SHM_LOG(bg::SHM_LOG_ERROR, fmt, ##__VA_ARGS__)
- #define SHM_FATAL(fmt, ...) __SHM_LOG(bg::SHM_LOG_FATAL, fmt, ##__VA_ARGS__)
- // TODO: print stack trace here
- #define __SHM_DO_ASSERT(exp) \
- SHM_FATAL("assertion failure: %s", #exp); \
- assert(exp)
- #define SHM_ASSERT(exp) \
- do { \
- if (SHM_LIKELY(exp)) break; \
- __SHM_DO_ASSERT(exp); \
- } while (0)
- #define SHM_ASSERT_RETURN_VALUE(exp, val) \
- do { \
- if (SHM_LIKELY(exp)) break; \
- __SHM_DO_ASSERT(exp); \
- return (val); \
- } while (0)
- #define SHM_ASSERT_RETURN_VOID(exp) \
- do { \
- if (SHM_LIKELY(exp)) break; \
- __SHM_DO_ASSERT(exp); \
- return; \
- } while (0)
- #define SHM_ASSERT_RETURN_NULL(exp) SHM_ASSERT_RETURN_VALUE(exp, nullptr)
- #define SHM_ASSERT_RETURN_TRUE(exp) SHM_ASSERT_RETURN_VALUE(exp, true)
- #define SHM_ASSERT_RETURN_FALSE(exp) SHM_ASSERT_RETURN_VALUE(exp, false)
- #ifdef NDEBUG
- #define SHM_DEBUG_ASSERT(exp)
- #else
- #define SHM_DEBUG_ASSERT(exp) SHM_ASSERT(exp)
- #endif
|