diff --git a/easy_profiler_core/include/easy/arbitrary_value.h b/easy_profiler_core/include/easy/arbitrary_value.h index 927d4a5..93a18cb 100644 --- a/easy_profiler_core/include/easy/arbitrary_value.h +++ b/easy_profiler_core/include/easy/arbitrary_value.h @@ -54,13 +54,13 @@ The Apache License, Version 2.0 (the "License"); EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ __FILE__, __LINE__, ::profiler::BLOCK_TYPE_VALUE, ::profiler::extract_color(__VA_ARGS__), false));\ - ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), value); + ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), value, ::profiler::extract_value_id(__VA_ARGS__)); # define EASY_TEXT(name, text, ...)\ EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ __FILE__, __LINE__, ::profiler::BLOCK_TYPE_VALUE, ::profiler::extract_color(__VA_ARGS__), false));\ - ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), text); + ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), text, ::profiler::extract_value_id(__VA_ARGS__)); #else @@ -73,13 +73,16 @@ The Apache License, Version 2.0 (the "License"); namespace profiler { - class ValueId EASY_FINAL { + class ValueId EASY_FINAL + { + friend ::ThreadStorage; size_t m_id; + public: - inline explicit ValueId() : m_id(0) {} + + explicit inline ValueId() : m_id(0) {} + template explicit inline ValueId(const T& _member) : m_id(reinterpret_cast(&_member)) {} inline ValueId(const ValueId&) = default; - template ValueId(const T& _member) : m_id(reinterpret_cast(&_member)) {} - inline size_t id() const { return m_id; } }; inline ValueId extract_value_id() { @@ -91,6 +94,11 @@ namespace profiler return _vin; } + template + inline ValueId extract_value_id(T, U, ::profiler::ValueId _vin, TArgs...) { + return _vin; + } + template inline ValueId extract_value_id(::profiler::ValueId _vin, TArgs...) { return _vin; @@ -98,7 +106,7 @@ namespace profiler template inline ValueId extract_value_id(TArgs...) { - static_assert(sizeof...(TArgs) < 2, "No EasyBlockStatus in arguments list for EASY_BLOCK(name, ...)!"); + static_assert(sizeof...(TArgs) < 2, "No ValueId in arguments list for EASY_VALUE(name, value, ...)!"); return ValueId(); } @@ -161,19 +169,15 @@ namespace profiler protected: - void setSize(uint16_t _size) { m_end16[3] = _size; } - void setType(DataType _type) { m_end8[2] = static_cast(_type); } - void setArray(bool _isArray) { m_end8[3] = static_cast(_isArray); } + uint16_t m_size; + DataType m_type; + bool m_isArray; - uint16_t size() const { return m_end16[0]; } - DataType type() const { return static_cast(m_end8[2]); } - bool isArray() const { return m_end8[3] != 0; } - - ArbitraryValue(block_id_t _id, uint16_t _size, DataType _type, bool _isArray) : BaseBlockData(0, 0, _id) + ArbitraryValue(size_t _vin, block_id_t _id, uint16_t _size, DataType _type, bool _isArray) : BaseBlockData(0, static_cast(_vin), _id) + , m_size(_size) + , m_type(_type) + , m_isArray(_isArray) { - setSize(_size); - setType(_type); - setArray(_isArray); } public: @@ -182,9 +186,13 @@ namespace profiler return reinterpret_cast(this) + sizeof(ArbitraryValue); } + size_t value_id() const { + return static_cast(m_end); + } + template const Value* convertToValue() const { - return type() == dataType ? static_cast*>(this) : nullptr; + return m_type == dataType ? static_cast*>(this) : nullptr; } template @@ -194,19 +202,13 @@ namespace profiler template const Value* convertToArray() const { - return isArray() && type() == dataType ? static_cast*>(this) : nullptr; + return m_isArray && m_type == dataType ? static_cast*>(this) : nullptr; } template const Value::data_type, true>* convertToArray() const { return convertToArray::data_type>(); } - - private: - - char* data() { - return reinterpret_cast(this) + sizeof(ArbitraryValue); - } }; #pragma pack(pop) @@ -218,14 +220,14 @@ namespace profiler template struct Value : public ArbitraryValue { using value_type = typename StdType::value_type; const value_type* value() const { return reinterpret_cast(data()); } - uint16_t size() const { return ArbitraryValue::size() / sizeof(value_type); } + uint16_t size() const { return m_size / sizeof(value_type); } value_type operator [] (int i) const { return value()[i]; } }; template <> struct Value : public ArbitraryValue { using value_type = char; const char* value() const { return data(); } - uint16_t size() const { return ArbitraryValue::size(); } + uint16_t size() const { return m_size; } char operator [] (int i) const { return data()[i]; } const char* c_str() const { return data(); } }; @@ -240,38 +242,38 @@ namespace profiler #ifdef USING_EASY_PROFILER extern "C" { - PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray); + PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin); } #else - inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool) {} + inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {} #endif template - inline void setValue(const BaseBlockDescriptor* _desc, T _value) + inline void setValue(const BaseBlockDescriptor* _desc, T _value, ValueId _vin) { - storeValue(_desc, StdToDataType::data_type, &_value, sizeof(T), false); + storeValue(_desc, StdToDataType::data_type, &_value, sizeof(T), false, _vin); } template - inline void setValue(const BaseBlockDescriptor* _desc, const T (&_value)[N]) + inline void setValue(const BaseBlockDescriptor* _desc, const T (&_value)[N], ValueId _vin) { - storeValue(_desc, StdToDataType::data_type, &_value[0], sizeof(_value), true); + storeValue(_desc, StdToDataType::data_type, &_value[0], sizeof(_value), true, _vin); } - inline void setText(const BaseBlockDescriptor* _desc, const char* _text) + inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin) { - storeValue(_desc, DATA_STR, _text, strlen(_text) + 1, true); + storeValue(_desc, DATA_STR, _text, strlen(_text) + 1, true, _vin); } - inline void setText(const BaseBlockDescriptor* _desc, const std::string& _text) + inline void setText(const BaseBlockDescriptor* _desc, const std::string& _text, ValueId _vin) { - storeValue(_desc, DATA_STR, _text.c_str(), _text.size() + 1, true); + storeValue(_desc, DATA_STR, _text.c_str(), _text.size() + 1, true, _vin); } template - inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N]) + inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N], ValueId _vin) { - storeValue(_desc, DATA_STR, &_text[0], N, true); + storeValue(_desc, DATA_STR, &_text[0], N, true, _vin); } } // END of namespace profiler. diff --git a/easy_profiler_core/include/easy/profiler_aux.h b/easy_profiler_core/include/easy/profiler_aux.h index 9236094..6807844 100644 --- a/easy_profiler_core/include/easy/profiler_aux.h +++ b/easy_profiler_core/include/easy/profiler_aux.h @@ -155,6 +155,11 @@ namespace profiler { return _color; } + template + inline color_t extract_color(T, U, color_t _color, TArgs...) { + return _color; + } + template inline color_t extract_color(TArgs...) { static_assert(sizeof...(TArgs) < 2, "No profiler::color_t in arguments list for EASY_BLOCK(name, ...)!"); @@ -172,6 +177,11 @@ namespace profiler { return _flag; } + template + inline EasyBlockStatus extract_enable_flag(T, U, ::profiler::EasyBlockStatus _flag, TArgs...) { + return _flag; + } + template inline EasyBlockStatus extract_enable_flag(::profiler::EasyBlockStatus _flag, TArgs...) { return _flag; diff --git a/easy_profiler_core/include/easy/profiler_public_types.h b/easy_profiler_core/include/easy/profiler_public_types.h index 58f189c..f176540 100644 --- a/easy_profiler_core/include/easy/profiler_public_types.h +++ b/easy_profiler_core/include/easy/profiler_public_types.h @@ -107,17 +107,8 @@ namespace profiler { protected: - union { - timestamp_t m_begin; - uint16_t m_begin16[4]; - uint8_t m_begin8[8]; - }; - - union { - timestamp_t m_end; - uint16_t m_end16[4]; - uint8_t m_end8[8]; - }; + timestamp_t m_begin; + timestamp_t m_end; public: diff --git a/easy_profiler_core/profile_manager.cpp b/easy_profiler_core/profile_manager.cpp index f4acf8b..862dd4b 100644 --- a/easy_profiler_core/profile_manager.cpp +++ b/easy_profiler_core/profile_manager.cpp @@ -322,9 +322,9 @@ extern "C" { return MANAGER.isEnabled(); } - PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray) + PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin) { - MANAGER.storeValue(_desc, _type, _data, _size, _isArray); + MANAGER.storeValue(_desc, _type, _data, _size, _isArray, _vin); } PROFILER_API void storeEvent(const BaseBlockDescriptor* _desc, const char* _runtimeName) @@ -488,7 +488,7 @@ extern "C" { PROFILER_API void endBlock() { } PROFILER_API void setEnabled(bool) { } PROFILER_API bool isEnabled() { return false; } - PROFILER_API void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool) {} + PROFILER_API void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {} PROFILER_API void storeEvent(const BaseBlockDescriptor*, const char*) { } PROFILER_API void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { } PROFILER_API void beginBlock(Block&) { } @@ -778,7 +778,7 @@ const BaseBlockDescriptor* ProfileManager::addBlockDescriptor(EasyBlockStatus _d ////////////////////////////////////////////////////////////////////////// -void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray) +void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin) { const auto state = m_profilerStatus.load(std::memory_order_acquire); if (state == EASY_PROF_DISABLED || !(_desc->m_status & profiler::ON)) @@ -803,6 +803,7 @@ void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type (void)_data; (void)_size; (void)_isArray; + (void)_vin; } ////////////////////////////////////////////////////////////////////////// diff --git a/easy_profiler_core/profile_manager.h b/easy_profiler_core/profile_manager.h index 642b5ce..a1973e7 100644 --- a/easy_profiler_core/profile_manager.h +++ b/easy_profiler_core/profile_manager.h @@ -130,7 +130,7 @@ public: profiler::color_t _color, bool _copyName = false); - void storeValue(const profiler::BaseBlockDescriptor* _desc, profiler::DataType _type, const void* _data, size_t _size, bool _isArray); + void storeValue(const profiler::BaseBlockDescriptor* _desc, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin); bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName); bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime); void beginBlock(profiler::Block& _block); diff --git a/easy_profiler_core/thread_storage.cpp b/easy_profiler_core/thread_storage.cpp index 40dab8d..2825b81 100644 --- a/easy_profiler_core/thread_storage.cpp +++ b/easy_profiler_core/thread_storage.cpp @@ -60,11 +60,16 @@ ThreadStorage::ThreadStorage() profiledFrameOpened = ATOMIC_VAR_INIT(false); } -void ThreadStorage::storeValue(profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray) +void ThreadStorage::storeValue(profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin) { - uint16_t serializedDataSize = static_cast(sizeof(profiler::ArbitraryValue) + _size); + const uint16_t serializedDataSize = static_cast(sizeof(profiler::ArbitraryValue) + _size); void* data = blocks.closedList.allocate(serializedDataSize); - ::new (data) profiler::ArbitraryValue(_id, static_cast(_size), _type, _isArray); + + ::new (data) profiler::ArbitraryValue(_vin.m_id, _id, static_cast(_size), _type, _isArray); + + char* cdata = reinterpret_cast(data); + memcpy(cdata + sizeof(profiler::ArbitraryValue), _data, _size); + blocks.usedMemorySize += serializedDataSize; } diff --git a/easy_profiler_core/thread_storage.h b/easy_profiler_core/thread_storage.h index db894ff..62c8c33 100644 --- a/easy_profiler_core/thread_storage.h +++ b/easy_profiler_core/thread_storage.h @@ -110,7 +110,7 @@ struct ThreadStorage EASY_FINAL bool frameOpened; ///< Is new frame opened (this does not depend on profiling status) \sa profiledFrameOpened bool halt; ///< This is set to true when new frame started while dumping blocks. Used to restrict collecting blocks during dumping process. - void storeValue(profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray); + void storeValue(profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin); void storeBlock(const profiler::Block& _block); void storeCSwitch(const CSwitchBlock& _block); void clearClosed();