mirror of
https://github.com/yse/easy_profiler.git
synced 2025-01-14 00:27:55 +08:00
#31 intermediate commit: added basic API for arbitrary values profiling. Still not working.
This commit is contained in:
parent
91482f2e1f
commit
86f7a48995
279
easy_profiler_core/include/easy/arbitrary_value.h
Normal file
279
easy_profiler_core/include/easy/arbitrary_value.h
Normal file
@ -0,0 +1,279 @@
|
||||
/**
|
||||
Lightweight profiler library for c++
|
||||
Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin
|
||||
|
||||
Licensed under either of
|
||||
* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
* Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
at your option.
|
||||
|
||||
The MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
The Apache License, Version 2.0 (the "License");
|
||||
You may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef EASY_PROFILER_ARBITRARY_VALUE_H
|
||||
#define EASY_PROFILER_ARBITRARY_VALUE_H
|
||||
|
||||
#include <easy/profiler.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USING_EASY_PROFILER
|
||||
|
||||
# define EASY_VIN(member) ::profiler::ValueId(member)
|
||||
|
||||
# define EASY_VALUE(name, value, ...)\
|
||||
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);
|
||||
|
||||
# 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);
|
||||
|
||||
#else
|
||||
|
||||
# define EASY_VIN(member)
|
||||
# define EASY_VALUE(...)
|
||||
# define EASY_TEXT(...)
|
||||
|
||||
#endif
|
||||
|
||||
namespace profiler
|
||||
{
|
||||
|
||||
class ValueId EASY_FINAL {
|
||||
size_t m_id;
|
||||
ValueId() = delete;
|
||||
public:
|
||||
inline ValueId(const ValueId& _another) : m_id(_another.m_id) {}
|
||||
explicit inline template <class T> ValueId(const T& _member) : m_id(static_cast<size_t>(&_member)) {}
|
||||
inline size_t id() const { return m_id; }
|
||||
};
|
||||
|
||||
inline ValueId extract_value_id() {
|
||||
return ValueId(0);
|
||||
}
|
||||
|
||||
template <class T, class ... TArgs>
|
||||
inline ValueId extract_value_id(T, ::profiler::ValueId _vin, TArgs...) {
|
||||
return _vin;
|
||||
}
|
||||
|
||||
template <class ... TArgs>
|
||||
inline ValueId extract_value_id(::profiler::ValueId _vin, TArgs...) {
|
||||
return _vin;
|
||||
}
|
||||
|
||||
template <class ... TArgs>
|
||||
inline ValueId extract_value_id(TArgs...) {
|
||||
static_assert(sizeof...(TArgs) < 2, "No EasyBlockStatus in arguments list for EASY_BLOCK(name, ...)!");
|
||||
return ValueId(0);
|
||||
}
|
||||
|
||||
enum DataType : uint8_t
|
||||
{
|
||||
DATA_BOOL = 0,
|
||||
DATA_CHAR,
|
||||
DATA_INT8,
|
||||
DATA_UINT8,
|
||||
DATA_INT16,
|
||||
DATA_UINT16,
|
||||
DATA_INT32,
|
||||
DATA_UINT32,
|
||||
DATA_INT64,
|
||||
DATA_UINT64,
|
||||
DATA_FLOAT,
|
||||
DATA_DOUBLE,
|
||||
DATA_STR,
|
||||
|
||||
DATA_TYPES_NUMBER
|
||||
};
|
||||
|
||||
template <DataType dataType> struct StdType;
|
||||
template <> struct StdType<DATA_BOOL > { using value_type = bool ; };
|
||||
template <> struct StdType<DATA_CHAR > { using value_type = char ; };
|
||||
template <> struct StdType<DATA_INT8 > { using value_type = int8_t ; };
|
||||
template <> struct StdType<DATA_UINT8 > { using value_type = uint8_t ; };
|
||||
template <> struct StdType<DATA_INT16 > { using value_type = int16_t ; };
|
||||
template <> struct StdType<DATA_UINT16> { using value_type = uint16_t; };
|
||||
template <> struct StdType<DATA_INT32 > { using value_type = int32_t ; };
|
||||
template <> struct StdType<DATA_UINT32> { using value_type = uint32_t; };
|
||||
template <> struct StdType<DATA_INT64 > { using value_type = int64_t ; };
|
||||
template <> struct StdType<DATA_UINT64> { using value_type = uint64_t; };
|
||||
template <> struct StdType<DATA_FLOAT > { using value_type = float ; };
|
||||
template <> struct StdType<DATA_DOUBLE> { using value_type = double ; };
|
||||
template <> struct StdType<DATA_STR > { using value_type = char ; };
|
||||
|
||||
template <class T> struct StdToDataType;
|
||||
template <> struct StdToDataType<bool > { static const DataType data_type = DATA_BOOL ; };
|
||||
template <> struct StdToDataType<char > { static const DataType data_type = DATA_CHAR ; };
|
||||
template <> struct StdToDataType<int8_t > { static const DataType data_type = DATA_INT8 ; };
|
||||
template <> struct StdToDataType<uint8_t > { static const DataType data_type = DATA_UINT8 ; };
|
||||
template <> struct StdToDataType<int16_t > { static const DataType data_type = DATA_INT16 ; };
|
||||
template <> struct StdToDataType<uint16_t > { static const DataType data_type = DATA_UINT16; };
|
||||
template <> struct StdToDataType<int32_t > { static const DataType data_type = DATA_INT32 ; };
|
||||
template <> struct StdToDataType<uint32_t > { static const DataType data_type = DATA_UINT32; };
|
||||
template <> struct StdToDataType<int64_t > { static const DataType data_type = DATA_INT64 ; };
|
||||
template <> struct StdToDataType<uint64_t > { static const DataType data_type = DATA_UINT64; };
|
||||
template <> struct StdToDataType<float > { static const DataType data_type = DATA_FLOAT ; };
|
||||
template <> struct StdToDataType<double > { static const DataType data_type = DATA_DOUBLE; };
|
||||
template <> struct StdToDataType<const char*> { static const DataType data_type = DATA_STR ; };
|
||||
|
||||
template <DataType dataType, bool isArray> struct Value;
|
||||
template <bool isArray> struct Value<DATA_TYPES_NUMBER, isArray>;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
class PROFILER_API ArbitraryValue : protected BaseBlockData
|
||||
{
|
||||
friend ::ThreadStorage;
|
||||
|
||||
protected:
|
||||
|
||||
void setSize(uint16_t _size) { m_end16[3] = _size; }
|
||||
void setType(DataType _type) { m_end8[2] = static_cast<uint8_t>(_type); }
|
||||
void setArray(bool _isArray) { m_end8[3] = static_cast<uint8_t>(_isArray); }
|
||||
|
||||
uint16_t size() const { return m_end16[0]; }
|
||||
DataType type() const { return static_cast<DataType>(m_end8[2]); }
|
||||
bool isArray() const { return static_cast<bool>(m_end8[3]); }
|
||||
|
||||
ArbitraryValue(block_id_t _id, uint16_t _size, DataType _type, bool _isArray) : BaseBlockData(0, 0, _id)
|
||||
{
|
||||
setSize(_size);
|
||||
setType(_type);
|
||||
setArray(_isArray);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
const char* data() const {
|
||||
return reinterpret_cast<const char*>(this) + sizeof(ArbitraryValue);
|
||||
}
|
||||
|
||||
template <DataType dataType>
|
||||
const Value<dataType, false>* convertToValue() const {
|
||||
return type() == dataType ? static_cast<const Value<dataType, false>*>(this) : nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const Value<StdToDataType<T>::data_type, false>* convertToValue() const {
|
||||
return convertToValue<StdToDataType<T>::data_type>();
|
||||
}
|
||||
|
||||
template <DataType dataType>
|
||||
const Value<dataType, true>* convertToArray() const {
|
||||
return isArray() && type() == dataType ? static_cast<const Value<dataType, true>*>(this) : nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const Value<StdToDataType<T>::data_type, true>* convertToArray() const {
|
||||
return convertToArray<StdToDataType<T>::data_type>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char* data() {
|
||||
return reinterpret_cast<char*>(this) + sizeof(ArbitraryValue);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
template <DataType dataType> struct Value<dataType, false> : public ArbitraryValue {
|
||||
using value_type = typename StdType<dataType>::value_type;
|
||||
value_type value() const { return *reinterpret_cast<const value_type*>(data()); }
|
||||
};
|
||||
|
||||
template <DataType dataType> struct Value<dataType, true> : public ArbitraryValue {
|
||||
using value_type = typename StdType<dataType>::value_type;
|
||||
const value_type* value() const { return reinterpret_cast<const value_type*>(data()); }
|
||||
uint16_t size() const { return ArbitraryValue::size() / sizeof(value_type); }
|
||||
value_type operator [] (int i) const { return value()[i]; }
|
||||
};
|
||||
|
||||
template <> struct Value<DATA_STR, true> : public ArbitraryValue {
|
||||
using value_type = char;
|
||||
const char* value() const { return data(); }
|
||||
uint16_t size() const { return ArbitraryValue::size(); }
|
||||
char operator [] (int i) const { return data()[i]; }
|
||||
const char* c_str() const { return data(); }
|
||||
};
|
||||
|
||||
template <DataType dataType>
|
||||
using SingleValue = Value<dataType, false>;
|
||||
|
||||
template <DataType dataType>
|
||||
using ArrayValue = Value<dataType, true>;
|
||||
|
||||
using StringValue = Value<DATA_STR, true>;
|
||||
|
||||
#ifdef USING_EASY_PROFILER
|
||||
extern "C" {
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray);
|
||||
}
|
||||
#else
|
||||
inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool) {}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline void setValue(const BaseBlockDescriptor* _desc, T _value)
|
||||
{
|
||||
storeValue(_desc, StdToDataType<T>::data_type, &_value, sizeof(T), false);
|
||||
}
|
||||
|
||||
template <class T, size_t N>
|
||||
inline void setValue(const BaseBlockDescriptor* _desc, const T (&_value)[N])
|
||||
{
|
||||
storeValue(_desc, StdToDataType<T>::data_type, &_value[0], sizeof(_value), true);
|
||||
}
|
||||
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char* _text)
|
||||
{
|
||||
storeValue(_desc, DATA_STR, _text, strlen(_text) + 1, true);
|
||||
}
|
||||
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const std::string& _text)
|
||||
{
|
||||
storeValue(_desc, DATA_STR, _text.c_str(), _text.size() + 1, true);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N])
|
||||
{
|
||||
storeValue(_desc, DATA_STR, &_text[0], N, true);
|
||||
}
|
||||
|
||||
} // END of namespace profiler.
|
||||
|
||||
#endif // EASY_PROFILER_ARBITRARY_VALUE_H
|
@ -462,7 +462,7 @@ namespace profiler {
|
||||
// Note: It is better to use macros defined above than a direct calls to API.
|
||||
// But some API functions does not have macro wrappers...
|
||||
|
||||
#ifdef BUILD_WITH_EASY_PROFILER
|
||||
#ifdef USING_EASY_PROFILER
|
||||
extern "C" {
|
||||
|
||||
/** Returns current time in ticks.
|
||||
|
@ -59,6 +59,7 @@ namespace profiler {
|
||||
{
|
||||
BLOCK_TYPE_EVENT = 0,
|
||||
BLOCK_TYPE_BLOCK,
|
||||
BLOCK_TYPE_VALUE,
|
||||
|
||||
BLOCK_TYPES_NUMBER
|
||||
};
|
||||
@ -106,8 +107,17 @@ namespace profiler {
|
||||
|
||||
protected:
|
||||
|
||||
timestamp_t m_begin;
|
||||
timestamp_t m_end;
|
||||
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];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
|
@ -322,6 +322,11 @@ extern "C" {
|
||||
return MANAGER.isEnabled();
|
||||
}
|
||||
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray)
|
||||
{
|
||||
MANAGER.storeValue(_desc, _type, _data, _size, _isArray);
|
||||
}
|
||||
|
||||
PROFILER_API void storeEvent(const BaseBlockDescriptor* _desc, const char* _runtimeName)
|
||||
{
|
||||
MANAGER.storeBlock(_desc, _runtimeName);
|
||||
@ -483,6 +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 storeEvent(const BaseBlockDescriptor*, const char*) { }
|
||||
PROFILER_API void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { }
|
||||
PROFILER_API void beginBlock(Block&) { }
|
||||
@ -772,6 +778,35 @@ const BaseBlockDescriptor* ProfileManager::addBlockDescriptor(EasyBlockStatus _d
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray)
|
||||
{
|
||||
const auto state = m_profilerStatus.load(std::memory_order_acquire);
|
||||
if (state == EASY_PROF_DISABLED || !(_desc->m_status & profiler::ON))
|
||||
return;
|
||||
|
||||
if (state == EASY_PROF_DUMP)
|
||||
{
|
||||
if (THIS_THREAD == nullptr || THIS_THREAD->blocks.openedList.empty())
|
||||
return;
|
||||
}
|
||||
else if (THIS_THREAD == nullptr)
|
||||
{
|
||||
registerThread();
|
||||
}
|
||||
|
||||
#if EASY_ENABLE_BLOCK_STATUS != 0
|
||||
if (!THIS_THREAD->allowChildren && !(_desc->m_status & FORCE_ON_FLAG))
|
||||
return;
|
||||
#endif
|
||||
|
||||
(void)_type;
|
||||
(void)_data;
|
||||
(void)_size;
|
||||
(void)_isArray;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName)
|
||||
{
|
||||
const auto state = m_profilerStatus.load(std::memory_order_acquire);
|
||||
|
@ -44,6 +44,7 @@ The Apache License, Version 2.0 (the "License");
|
||||
#define EASY_PROFILER_MANAGER_H
|
||||
|
||||
#include <easy/profiler.h>
|
||||
#include <easy/arbitrary_value.h>
|
||||
#include <easy/easy_socket.h>
|
||||
|
||||
#include "spin_lock.h"
|
||||
@ -129,6 +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);
|
||||
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);
|
||||
|
@ -60,6 +60,14 @@ 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)
|
||||
{
|
||||
uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::ArbitraryValue) + _size);
|
||||
void* data = blocks.closedList.allocate(serializedDataSize);
|
||||
::new (data) profiler::ArbitraryValue(_id, static_cast<uint16_t>(_size), _type, _isArray);
|
||||
blocks.usedMemorySize += serializedDataSize;
|
||||
}
|
||||
|
||||
void ThreadStorage::storeBlock(const profiler::Block& block)
|
||||
{
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0
|
||||
@ -71,22 +79,22 @@ void ThreadStorage::storeBlock(const profiler::Block& block)
|
||||
EASY_THREAD_LOCAL static profiler::timestamp_t endTime = 0ULL;
|
||||
#endif
|
||||
|
||||
uint16_t name_length = static_cast<uint16_t>(strlen(block.name()));
|
||||
uint16_t size = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + name_length + 1);
|
||||
uint16_t nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + nameLength + 1);
|
||||
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0
|
||||
const bool expanded = (desc->m_status & profiler::ON) && blocks.closedList.need_expand(size);
|
||||
const bool expanded = (desc->m_status & profiler::ON) && blocks.closedList.need_expand(serializedDataSize);
|
||||
if (expanded) beginTime = getCurrentTime();
|
||||
#endif
|
||||
|
||||
void* data = blocks.closedList.allocate(size);
|
||||
void* data = blocks.closedList.allocate(serializedDataSize);
|
||||
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0
|
||||
if (expanded) endTime = getCurrentTime();
|
||||
#endif
|
||||
|
||||
::new (data) profiler::SerializedBlock(block, name_length);
|
||||
blocks.usedMemorySize += size;
|
||||
::new (data) profiler::SerializedBlock(block, nameLength);
|
||||
blocks.usedMemorySize += serializedDataSize;
|
||||
|
||||
#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0
|
||||
if (expanded)
|
||||
@ -94,21 +102,21 @@ void ThreadStorage::storeBlock(const profiler::Block& block)
|
||||
profiler::Block b(beginTime, desc->id(), "");
|
||||
b.finish(endTime);
|
||||
|
||||
size = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + 1);
|
||||
data = blocks.closedList.allocate(size);
|
||||
serializedDataSize = static_cast<uint16_t>(sizeof(profiler::BaseBlockData) + 1);
|
||||
data = blocks.closedList.allocate(serializedDataSize);
|
||||
::new (data) profiler::SerializedBlock(b, 0);
|
||||
blocks.usedMemorySize += size;
|
||||
blocks.usedMemorySize += serializedDataSize;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThreadStorage::storeCSwitch(const CSwitchBlock& block)
|
||||
{
|
||||
uint16_t name_length = static_cast<uint16_t>(strlen(block.name()));
|
||||
uint16_t size = static_cast<uint16_t>(sizeof(profiler::CSwitchEvent) + name_length + 1);
|
||||
void* data = sync.closedList.allocate(size);
|
||||
::new (data) profiler::SerializedCSwitch(block, name_length);
|
||||
sync.usedMemorySize += size;
|
||||
uint16_t nameLength = static_cast<uint16_t>(strlen(block.name()));
|
||||
uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::CSwitchEvent) + nameLength + 1);
|
||||
void* data = sync.closedList.allocate(serializedDataSize);
|
||||
::new (data) profiler::SerializedCSwitch(block, nameLength);
|
||||
sync.usedMemorySize += serializedDataSize;
|
||||
}
|
||||
|
||||
void ThreadStorage::clearClosed()
|
||||
|
@ -44,6 +44,7 @@ The Apache License, Version 2.0 (the "License");
|
||||
#define EASY_PROFILER_THREAD_STORAGE_H
|
||||
|
||||
#include <easy/profiler.h>
|
||||
#include <easy/arbitrary_value.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
@ -91,7 +92,7 @@ public:
|
||||
const uint16_t SIZEOF_BLOCK = sizeof(profiler::BaseBlockData) + 1 + sizeof(uint16_t); // SerializedBlock stores BaseBlockData + at least 1 character for name ('\0') + 2 bytes for size of serialized data
|
||||
const uint16_t SIZEOF_CSWITCH = sizeof(profiler::CSwitchEvent) + 1 + sizeof(uint16_t); // SerializedCSwitch also stores additional 4 bytes to be able to save 64-bit thread_id
|
||||
|
||||
struct ThreadStorage
|
||||
struct ThreadStorage EASY_FINAL
|
||||
{
|
||||
StackBuffer<NonscopedBlock> nonscopedBlocks;
|
||||
BlocksList<std::reference_wrapper<profiler::Block>, SIZEOF_BLOCK * (uint16_t)128U> blocks;
|
||||
@ -109,6 +110,7 @@ struct ThreadStorage
|
||||
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 storeBlock(const profiler::Block& _block);
|
||||
void storeCSwitch(const CSwitchBlock& _block);
|
||||
void clearClosed();
|
||||
|
Loading…
x
Reference in New Issue
Block a user