mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
#91 [Core][UI] functions profiler::writeTreesToFile(), profiler::writeTreesToStream() are now working. Snapshot feature is now working: select an area on Diagram (with right mouse button or double-click) and press Snapshot button to save it to separate file.
This commit is contained in:
parent
21bcefcb75
commit
f665478830
@ -283,86 +283,41 @@ namespace profiler {
|
|||||||
|
|
||||||
class PROFILER_API SerializedData EASY_FINAL
|
class PROFILER_API SerializedData EASY_FINAL
|
||||||
{
|
{
|
||||||
char* m_data;
|
uint64_t m_size;
|
||||||
size_t m_size;
|
char* m_data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SerializedData(const SerializedData&) = delete;
|
SerializedData(const SerializedData&) = delete;
|
||||||
SerializedData& operator = (const SerializedData&) = delete;
|
SerializedData& operator = (const SerializedData&) = delete;
|
||||||
|
|
||||||
SerializedData() : m_data(nullptr), m_size(0)
|
SerializedData();
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializedData(SerializedData&& that) : m_data(that.m_data), m_size(that.m_size)
|
SerializedData(SerializedData&& that);
|
||||||
{
|
|
||||||
that.m_data = nullptr;
|
|
||||||
that.m_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~SerializedData()
|
~SerializedData();
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(uint64_t _size);
|
void set(uint64_t _size);
|
||||||
|
|
||||||
void extend(uint64_t _size);
|
void extend(uint64_t _size);
|
||||||
|
|
||||||
SerializedData& operator = (SerializedData&& that)
|
SerializedData& operator = (SerializedData&& that);
|
||||||
{
|
|
||||||
set(that.m_data, that.m_size);
|
|
||||||
that.m_data = nullptr;
|
|
||||||
that.m_size = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* operator [] (uint64_t i)
|
char* operator [] (uint64_t i);
|
||||||
{
|
|
||||||
return m_data + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* operator [] (uint64_t i) const
|
const char* operator [] (uint64_t i) const;
|
||||||
{
|
|
||||||
return m_data + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const
|
bool empty() const;
|
||||||
{
|
|
||||||
return m_size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t size() const
|
uint64_t size() const;
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* data()
|
char* data();
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* data() const
|
const char* data() const;
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
void clear();
|
||||||
{
|
|
||||||
set(nullptr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(SerializedData& other)
|
void swap(SerializedData& other);
|
||||||
{
|
|
||||||
char* d = other.m_data;
|
|
||||||
uint64_t sz = other.m_size;
|
|
||||||
|
|
||||||
other.m_data = m_data;
|
|
||||||
other.m_size = m_size;
|
|
||||||
|
|
||||||
m_data = d;
|
|
||||||
m_size = (size_t)sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -409,6 +364,7 @@ extern "C" {
|
|||||||
|
|
||||||
PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -419,6 +375,7 @@ extern "C" {
|
|||||||
|
|
||||||
PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<int>& progress, std::ostream& str,
|
PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<int>& progress, std::ostream& str,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -445,6 +402,7 @@ inline profiler::block_index_t fillTreesFromFile(const char* filename, profiler:
|
|||||||
|
|
||||||
inline profiler::block_index_t writeTreesToFile(const char* filename,
|
inline profiler::block_index_t writeTreesToFile(const char* filename,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -454,12 +412,13 @@ inline profiler::block_index_t writeTreesToFile(const char* filename,
|
|||||||
std::ostream& log)
|
std::ostream& log)
|
||||||
{
|
{
|
||||||
std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
||||||
return writeTreesToFile(progress, filename, serialized_descriptors, descriptors_count, trees, std::move(block_getter),
|
return writeTreesToFile(progress, filename, serialized_descriptors, descriptors, descriptors_count, trees,
|
||||||
begin_time, end_time, pid, log);
|
std::move(block_getter), begin_time, end_time, pid, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline profiler::block_index_t writeTreesToStream(std::ostream& str,
|
inline profiler::block_index_t writeTreesToStream(std::ostream& str,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -469,8 +428,8 @@ inline profiler::block_index_t writeTreesToStream(std::ostream& str,
|
|||||||
std::ostream& log)
|
std::ostream& log)
|
||||||
{
|
{
|
||||||
std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
||||||
return writeTreesToStream(progress, str, serialized_descriptors, descriptors_count, trees, std::move(block_getter),
|
return writeTreesToStream(progress, str, serialized_descriptors, descriptors, descriptors_count, trees,
|
||||||
begin_time, end_time, pid, log);
|
std::move(block_getter), begin_time, end_time, pid, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool readDescriptionsFromStream(std::istream& str,
|
inline bool readDescriptionsFromStream(std::istream& str,
|
||||||
|
@ -129,11 +129,26 @@ inline bool isCompatibleVersion(uint32_t _version)
|
|||||||
|
|
||||||
namespace profiler {
|
namespace profiler {
|
||||||
|
|
||||||
|
SerializedData::SerializedData() : m_size(0), m_data(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializedData::SerializedData(SerializedData&& that) : m_size(that.m_size), m_data(that.m_data)
|
||||||
|
{
|
||||||
|
that.m_size = 0;
|
||||||
|
that.m_data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializedData::~SerializedData()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
void SerializedData::set(char* _data, uint64_t _size)
|
void SerializedData::set(char* _data, uint64_t _size)
|
||||||
{
|
{
|
||||||
delete [] m_data;
|
delete [] m_data;
|
||||||
m_data = _data;
|
|
||||||
m_size = _size;
|
m_size = _size;
|
||||||
|
m_data = _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializedData::set(uint64_t _size)
|
void SerializedData::set(uint64_t _size)
|
||||||
@ -146,8 +161,8 @@ namespace profiler {
|
|||||||
|
|
||||||
void SerializedData::extend(uint64_t _size)
|
void SerializedData::extend(uint64_t _size)
|
||||||
{
|
{
|
||||||
auto olddata = m_data;
|
|
||||||
auto oldsize = m_size;
|
auto oldsize = m_size;
|
||||||
|
auto olddata = m_data;
|
||||||
|
|
||||||
m_size = oldsize + _size;
|
m_size = oldsize + _size;
|
||||||
m_data = new char[m_size];
|
m_data = new char[m_size];
|
||||||
@ -158,6 +173,61 @@ namespace profiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SerializedData& SerializedData::operator = (SerializedData&& that)
|
||||||
|
{
|
||||||
|
set(that.m_data, that.m_size);
|
||||||
|
that.m_size = 0;
|
||||||
|
that.m_data = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SerializedData::operator [] (uint64_t i)
|
||||||
|
{
|
||||||
|
return m_data + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* SerializedData::operator [] (uint64_t i) const
|
||||||
|
{
|
||||||
|
return m_data + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerializedData::empty() const
|
||||||
|
{
|
||||||
|
return m_size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t SerializedData::size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SerializedData::data()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* SerializedData::data() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerializedData::clear()
|
||||||
|
{
|
||||||
|
set(nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerializedData::swap(SerializedData& other)
|
||||||
|
{
|
||||||
|
char* d = other.m_data;
|
||||||
|
const auto sz = other.m_size;
|
||||||
|
|
||||||
|
other.m_data = m_data;
|
||||||
|
other.m_size = m_size;
|
||||||
|
|
||||||
|
m_data = d;
|
||||||
|
m_size = sz;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats)
|
extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats)
|
||||||
{
|
{
|
||||||
if (_stats == nullptr)
|
if (_stats == nullptr)
|
||||||
@ -653,6 +723,12 @@ extern "C" PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i + sz > memory_size)
|
||||||
|
{
|
||||||
|
_log << "File corrupted.\nActual context switches data size > size pointed in file.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char* data = serialized_blocks[i];
|
char* data = serialized_blocks[i];
|
||||||
inFile.read(data, sz);
|
inFile.read(data, sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
@ -714,6 +790,12 @@ extern "C" PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i + sz > memory_size)
|
||||||
|
{
|
||||||
|
_log << "File corrupted.\nActual blocks data size > size pointed in file.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char* data = serialized_blocks[i];
|
char* data = serialized_blocks[i];
|
||||||
inFile.read(data, sz);
|
inFile.read(data, sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
@ -1146,7 +1228,9 @@ BlocksRange findRange(const profiler::BlocksTree::children_t& children, profiler
|
|||||||
|
|
||||||
BlocksMemoryAndCount calculateUsedMemoryAndBlocksCount(const profiler::BlocksTree::children_t& children,
|
BlocksMemoryAndCount calculateUsedMemoryAndBlocksCount(const profiler::BlocksTree::children_t& children,
|
||||||
const BlocksRange& range,
|
const BlocksRange& range,
|
||||||
const profiler::block_getter_fn& getter, bool contextSwitches)
|
const profiler::block_getter_fn& getter,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
|
bool contextSwitches)
|
||||||
{
|
{
|
||||||
BlocksMemoryAndCount memoryAndCount;
|
BlocksMemoryAndCount memoryAndCount;
|
||||||
|
|
||||||
@ -1157,12 +1241,18 @@ BlocksMemoryAndCount calculateUsedMemoryAndBlocksCount(const profiler::BlocksTre
|
|||||||
const auto& child = getter(children[i]);
|
const auto& child = getter(children[i]);
|
||||||
|
|
||||||
// Calculate self memory consumption
|
// Calculate self memory consumption
|
||||||
const uint64_t usedMemorySize = sizeof(profiler::SerializedBlock) + strlen(child.node->name()) + 1;
|
const auto& desc = *descriptors[child.node->id()];
|
||||||
|
uint64_t usedMemorySize = 0;
|
||||||
|
|
||||||
|
if (desc.type() == profiler::BlockType::Value)
|
||||||
|
usedMemorySize = sizeof(profiler::ArbitraryValue) + child.value->data_size();
|
||||||
|
else
|
||||||
|
usedMemorySize = sizeof(profiler::SerializedBlock) + strlen(child.node->name()) + 1;
|
||||||
|
|
||||||
// Calculate children memory consumption
|
// Calculate children memory consumption
|
||||||
const BlocksRange childRange(0, static_cast<profiler::block_index_t>(child.children.size()));
|
const BlocksRange childRange(0, static_cast<profiler::block_index_t>(child.children.size()));
|
||||||
const auto childrenMemoryAndCount = calculateUsedMemoryAndBlocksCount(child.children, childRange,
|
const auto childrenMemoryAndCount = calculateUsedMemoryAndBlocksCount(child.children, childRange,
|
||||||
getter,
|
getter, descriptors,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// Accumulate memory and count
|
// Accumulate memory and count
|
||||||
@ -1185,37 +1275,53 @@ BlocksMemoryAndCount calculateUsedMemoryAndBlocksCount(const profiler::BlocksTre
|
|||||||
return memoryAndCount;
|
return memoryAndCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(profiler::SerializedData& output, uint64_t& position, const profiler::BlocksTree::children_t& children,
|
void serializeBlocks(std::ostream& output, std::vector<char>& buffer, const profiler::BlocksTree::children_t& children,
|
||||||
const BlocksRange& range, const profiler::block_getter_fn& getter, bool contextSwitches)
|
const BlocksRange& range, const profiler::block_getter_fn& getter,
|
||||||
|
const profiler::descriptors_list_t& descriptors)
|
||||||
{
|
{
|
||||||
if (!contextSwitches)
|
for (auto i = range.begin; i < range.end; ++i)
|
||||||
{
|
{
|
||||||
// Serialize blocks
|
const auto& child = getter(children[i]);
|
||||||
|
|
||||||
for (auto i = range.begin; i < range.end; ++i)
|
// Serialize children
|
||||||
|
const BlocksRange childRange(0, static_cast<profiler::block_index_t>(child.children.size()));
|
||||||
|
serializeBlocks(output, buffer, child.children, childRange, getter, descriptors);
|
||||||
|
|
||||||
|
// Serialize self
|
||||||
|
const auto& desc = *descriptors[child.node->id()];
|
||||||
|
uint16_t usedMemorySize = 0;
|
||||||
|
|
||||||
|
if (desc.type() == profiler::BlockType::Value)
|
||||||
{
|
{
|
||||||
const auto& child = getter(children[i]);
|
usedMemorySize = static_cast<uint16_t>(sizeof(profiler::ArbitraryValue)) + child.value->data_size();
|
||||||
|
buffer.resize(usedMemorySize + sizeof(uint16_t));
|
||||||
|
unaligned_store16(buffer.data(), usedMemorySize);
|
||||||
|
memcpy(buffer.data() + sizeof(uint16_t), child.value, static_cast<size_t>(usedMemorySize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usedMemorySize = static_cast<uint16_t>(sizeof(profiler::SerializedBlock)
|
||||||
|
+ strlen(child.node->name()) + 1);
|
||||||
|
|
||||||
// Serialize children
|
buffer.resize(usedMemorySize + sizeof(uint16_t));
|
||||||
const BlocksRange childRange(0, static_cast<profiler::block_index_t>(child.children.size()));
|
unaligned_store16(buffer.data(), usedMemorySize);
|
||||||
serialize(output, position, child.children, childRange, getter, false);
|
memcpy(buffer.data() + sizeof(uint16_t), child.node, static_cast<size_t>(usedMemorySize));
|
||||||
|
|
||||||
// Serialize self
|
if (child.node->id() != desc.id())
|
||||||
const auto usedMemorySize = static_cast<uint16_t>(
|
{
|
||||||
sizeof(profiler::SerializedBlock) + strlen(child.node->name()) + 1);
|
// This block id is dynamic. Restore it's value like it was before in the input .prof file
|
||||||
|
auto block = reinterpret_cast<profiler::SerializedBlock*>(buffer.data() + sizeof(uint16_t));
|
||||||
unaligned_store16(output.data() + position, usedMemorySize);
|
block->setId(desc.id());
|
||||||
memcpy(output.data() + position + sizeof(uint16_t), child.node, static_cast<size_t>(usedMemorySize));
|
}
|
||||||
|
|
||||||
// TODO: write valid block id (it can be dynamic)
|
|
||||||
|
|
||||||
position += usedMemorySize + sizeof(uint16_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
write(output, buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize context switches
|
void serializeContextSwitches(std::ostream& output, std::vector<char>& buffer, const profiler::BlocksTree::children_t& children,
|
||||||
|
const BlocksRange& range, const profiler::block_getter_fn& getter)
|
||||||
|
{
|
||||||
for (auto i = range.begin; i < range.end; ++i)
|
for (auto i = range.begin; i < range.end; ++i)
|
||||||
{
|
{
|
||||||
const auto& child = getter(children[i]);
|
const auto& child = getter(children[i]);
|
||||||
@ -1223,15 +1329,39 @@ void serialize(profiler::SerializedData& output, uint64_t& position, const profi
|
|||||||
const auto usedMemorySize = static_cast<uint16_t>(
|
const auto usedMemorySize = static_cast<uint16_t>(
|
||||||
sizeof(profiler::SerializedCSwitch) + strlen(child.cs->name()) + 1);
|
sizeof(profiler::SerializedCSwitch) + strlen(child.cs->name()) + 1);
|
||||||
|
|
||||||
unaligned_store16(output.data() + position, usedMemorySize);
|
buffer.resize(usedMemorySize + sizeof(uint16_t));
|
||||||
memcpy(output.data() + position + sizeof(uint16_t), child.cs, static_cast<size_t>(usedMemorySize));
|
unaligned_store16(buffer.data(), usedMemorySize);
|
||||||
|
memcpy(buffer.data() + sizeof(uint16_t), child.cs, static_cast<size_t>(usedMemorySize));
|
||||||
|
|
||||||
position += usedMemorySize + sizeof(uint16_t);
|
write(output, buffer.data(), buffer.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializeDescriptors(std::ostream& output, std::vector<char>& buffer,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
|
profiler::block_id_t descriptors_count)
|
||||||
|
{
|
||||||
|
const size_t size = std::min(descriptors.size(), static_cast<size_t>(descriptors_count));
|
||||||
|
for (size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
const auto& desc = *descriptors[i];
|
||||||
|
if (desc.id() != i)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const auto usedMemorySize = static_cast<uint16_t>(sizeof(profiler::SerializedBlockDescriptor)
|
||||||
|
+ strlen(desc.name()) + strlen(desc.file()) + 2);
|
||||||
|
|
||||||
|
buffer.resize(usedMemorySize + sizeof(uint16_t));
|
||||||
|
unaligned_store16(buffer.data(), usedMemorySize);
|
||||||
|
memcpy(buffer.data() + sizeof(uint16_t), &desc, static_cast<size_t>(usedMemorySize));
|
||||||
|
|
||||||
|
write(output, buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
extern "C" PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -1251,8 +1381,8 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write data to file
|
// Write data to file
|
||||||
auto result = writeTreesToStream(progress, outFile, serialized_descriptors, descriptors_count, trees, std::move(block_getter),
|
auto result = writeTreesToStream(progress, outFile, serialized_descriptors, descriptors, descriptors_count, trees,
|
||||||
begin_time, end_time, pid, log);
|
std::move(block_getter), begin_time, end_time, pid, log);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1261,6 +1391,7 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int
|
|||||||
|
|
||||||
extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<int>& progress, std::ostream& str,
|
extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<int>& progress, std::ostream& str,
|
||||||
const profiler::SerializedData& serialized_descriptors,
|
const profiler::SerializedData& serialized_descriptors,
|
||||||
|
const profiler::descriptors_list_t& descriptors,
|
||||||
profiler::block_id_t descriptors_count,
|
profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& trees,
|
const profiler::thread_blocks_tree_t& trees,
|
||||||
profiler::block_getter_fn block_getter,
|
profiler::block_getter_fn block_getter,
|
||||||
@ -1281,6 +1412,7 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<i
|
|||||||
ranges_t block_ranges;
|
ranges_t block_ranges;
|
||||||
|
|
||||||
// Calculate block ranges and used memory (for serialization)
|
// Calculate block ranges and used memory (for serialization)
|
||||||
|
profiler::timestamp_t beginTime = begin_time, endTime = end_time;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const auto& kv : trees)
|
for (const auto& kv : trees)
|
||||||
{
|
{
|
||||||
@ -1292,12 +1424,26 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<i
|
|||||||
range.blocks = findRange(tree.children, begin_time, end_time, block_getter);
|
range.blocks = findRange(tree.children, begin_time, end_time, block_getter);
|
||||||
range.cswitches = findRange(tree.sync, begin_time, end_time, block_getter);
|
range.cswitches = findRange(tree.sync, begin_time, end_time, block_getter);
|
||||||
|
|
||||||
range.blocksMemoryAndCount = calculateUsedMemoryAndBlocksCount(tree.children, range.blocks, block_getter, false);
|
range.blocksMemoryAndCount = calculateUsedMemoryAndBlocksCount(tree.children, range.blocks, block_getter,
|
||||||
|
descriptors, false);
|
||||||
total += range.blocksMemoryAndCount;
|
total += range.blocksMemoryAndCount;
|
||||||
|
|
||||||
range.cswitchesMemoryAndCount = calculateUsedMemoryAndBlocksCount(tree.sync, range.cswitches, block_getter, true);
|
if (range.blocksMemoryAndCount.blocksCount != 0)
|
||||||
|
{
|
||||||
|
beginTime = std::min(beginTime, block_getter(tree.children[range.blocks.begin]).node->begin());
|
||||||
|
endTime = std::max(endTime, block_getter(tree.children[range.blocks.end - 1]).node->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
range.cswitchesMemoryAndCount = calculateUsedMemoryAndBlocksCount(tree.sync, range.cswitches, block_getter,
|
||||||
|
descriptors, true);
|
||||||
total += range.cswitchesMemoryAndCount;
|
total += range.cswitchesMemoryAndCount;
|
||||||
|
|
||||||
|
if (range.cswitchesMemoryAndCount.blocksCount != 0)
|
||||||
|
{
|
||||||
|
beginTime = std::min(beginTime, block_getter(tree.children[range.cswitches.begin]).cs->begin());
|
||||||
|
endTime = std::max(endTime, block_getter(tree.children[range.cswitches.end - 1]).cs->end());
|
||||||
|
}
|
||||||
|
|
||||||
block_ranges[id] = range;
|
block_ranges[id] = range;
|
||||||
|
|
||||||
if (!update_progress_write(progress, 15 / static_cast<int>(trees.size() - i), log))
|
if (!update_progress_write(progress, 15 / static_cast<int>(trees.size() - i), log))
|
||||||
@ -1322,22 +1468,20 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<i
|
|||||||
// write 0 because we do not need to convert time from ticks to nanoseconds (it's already converted)
|
// write 0 because we do not need to convert time from ticks to nanoseconds (it's already converted)
|
||||||
write<int64_t>(str, 0LL); // CPU frequency
|
write<int64_t>(str, 0LL); // CPU frequency
|
||||||
|
|
||||||
write(str, begin_time);
|
write(str, beginTime);
|
||||||
write(str, end_time);
|
write(str, endTime);
|
||||||
|
|
||||||
write(str, total.usedMemorySize);
|
write(str, total.usedMemorySize);
|
||||||
write(str, usedMemorySizeDescriptors);
|
write(str, usedMemorySizeDescriptors);
|
||||||
write(str, total.blocksCount);
|
write(str, total.blocksCount);
|
||||||
write(str, descriptors_count);
|
write(str, descriptors_count);
|
||||||
|
|
||||||
|
std::vector<char> buffer;
|
||||||
|
|
||||||
// Serialize all descriptors
|
// Serialize all descriptors
|
||||||
// TODO
|
serializeDescriptors(str, buffer, descriptors, descriptors_count);
|
||||||
|
|
||||||
// Serialize all blocks
|
// Serialize all blocks
|
||||||
profiler::SerializedData serializedBlocks;
|
|
||||||
serializedBlocks.set(total.usedMemorySize + sizeof(uint16_t) * total.blocksCount);
|
|
||||||
uint64_t position = 0;
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto& kv : trees)
|
for (const auto& kv : trees)
|
||||||
{
|
{
|
||||||
@ -1349,25 +1493,16 @@ extern "C" PROFILER_API profiler::block_index_t writeTreesToStream(std::atomic<i
|
|||||||
write(str, id);
|
write(str, id);
|
||||||
write(str, nameSize);
|
write(str, nameSize);
|
||||||
write(str, tree.name(), nameSize);
|
write(str, tree.name(), nameSize);
|
||||||
write(str, range.cswitchesMemoryAndCount.blocksCount);
|
|
||||||
|
|
||||||
// Serialize context switches
|
// Serialize context switches
|
||||||
write(str, range.cswitchesMemoryAndCount.blocksCount);
|
write(str, range.cswitchesMemoryAndCount.blocksCount);
|
||||||
if (range.cswitchesMemoryAndCount.blocksCount != 0)
|
if (range.cswitchesMemoryAndCount.blocksCount != 0)
|
||||||
{
|
serializeContextSwitches(str, buffer, tree.sync, range.cswitches, block_getter);
|
||||||
const auto previousPosition = position;
|
|
||||||
serialize(serializedBlocks, position, tree.sync, range.cswitches, block_getter, true);
|
|
||||||
write(str, serializedBlocks.data() + previousPosition, position - previousPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize blocks
|
// Serialize blocks
|
||||||
write(str, range.blocksMemoryAndCount.blocksCount);
|
write(str, range.blocksMemoryAndCount.blocksCount);
|
||||||
if (range.blocksMemoryAndCount.blocksCount != 0)
|
if (range.blocksMemoryAndCount.blocksCount != 0)
|
||||||
{
|
serializeBlocks(str, buffer, tree.children, range.blocks, block_getter, descriptors);
|
||||||
const auto previousPosition = position;
|
|
||||||
serialize(serializedBlocks, position, tree.children, range.blocks, block_getter, false);
|
|
||||||
write(str, serializedBlocks.data() + previousPosition, position - previousPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!update_progress_write(progress, 40 + 60 / static_cast<int>(trees.size() - i), log))
|
if (!update_progress_write(progress, 40 + 60 / static_cast<int>(trees.size() - i), log))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -407,6 +407,8 @@ void BlocksGraphicsView::clear()
|
|||||||
|
|
||||||
EASY_GLOBALS.selected_thread = 0;
|
EASY_GLOBALS.selected_thread = 0;
|
||||||
emit EASY_GLOBALS.events.selectedThreadChanged(0);
|
emit EASY_GLOBALS.events.selectedThreadChanged(0);
|
||||||
|
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlocksGraphicsView::notifySceneSizeChange()
|
void BlocksGraphicsView::notifySceneSizeChange()
|
||||||
@ -438,7 +440,10 @@ void BlocksGraphicsView::notifyVisibleRegionPosChange()
|
|||||||
|
|
||||||
void BlocksGraphicsView::notifyVisibleRegionPosChange(qreal _pos)
|
void BlocksGraphicsView::notifyVisibleRegionPosChange(qreal _pos)
|
||||||
{
|
{
|
||||||
m_offset = estd::clamp(0., _pos, m_sceneWidth - m_visibleRegionWidth);
|
if (m_sceneWidth < m_visibleRegionWidth)
|
||||||
|
m_offset = 0;
|
||||||
|
else
|
||||||
|
m_offset = estd::clamp(0., _pos, m_sceneWidth - m_visibleRegionWidth);
|
||||||
notifyVisibleRegionPosChange();
|
notifyVisibleRegionPosChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,25 +621,15 @@ const BlocksGraphicsView::Items &BlocksGraphicsView::getItems() const
|
|||||||
|
|
||||||
bool BlocksGraphicsView::getSelectionRegionForSaving(profiler::timestamp_t& _beginTime, profiler::timestamp_t& _endTime) const
|
bool BlocksGraphicsView::getSelectionRegionForSaving(profiler::timestamp_t& _beginTime, profiler::timestamp_t& _endTime) const
|
||||||
{
|
{
|
||||||
if (m_selectedBlocks.empty())
|
if (m_bEmpty)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_beginTime = ~0ULL;
|
if (!m_selectionItem->isVisible() && !m_rulerItem->isVisible())
|
||||||
_endTime = 0;
|
return false;
|
||||||
|
|
||||||
for (const auto& selection : m_selectedBlocks)
|
decltype(m_selectionItem) ruler = m_selectionItem->isVisible() ? m_selectionItem : m_rulerItem;
|
||||||
{
|
_beginTime = m_beginTime + position2time(ruler->left());
|
||||||
const auto& tree = easyBlocksTree(selection.tree);
|
_endTime = m_beginTime + position2time(ruler->right());
|
||||||
_beginTime = std::min(_beginTime, tree.node->begin());
|
|
||||||
_endTime = std::max(_endTime, tree.node->end());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_beginTime > 10)
|
|
||||||
_beginTime -= 10;
|
|
||||||
else
|
|
||||||
_beginTime = 0;
|
|
||||||
|
|
||||||
_endTime += 10;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -923,7 +918,10 @@ void BlocksGraphicsView::onWheel(qreal _scenePos, int _wheelDelta)
|
|||||||
notifyVisibleRegionSizeChange();
|
notifyVisibleRegionSizeChange();
|
||||||
|
|
||||||
// Calculate new offset to simulate QGraphicsView::AnchorUnderMouse scaling behavior
|
// Calculate new offset to simulate QGraphicsView::AnchorUnderMouse scaling behavior
|
||||||
m_offset = clamp(0., initialPosition - _scenePos / m_scale, m_sceneWidth - m_visibleRegionWidth);
|
if (m_sceneWidth < m_visibleRegionWidth)
|
||||||
|
m_offset = 0;
|
||||||
|
else
|
||||||
|
m_offset = clamp(0., initialPosition - _scenePos / m_scale, m_sceneWidth - m_visibleRegionWidth);
|
||||||
|
|
||||||
// Update slider position
|
// Update slider position
|
||||||
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true); // To be sure that updateVisibleSceneRect will not be called by scrollbar change
|
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true); // To be sure that updateVisibleSceneRect will not be called by scrollbar change
|
||||||
@ -980,6 +978,7 @@ void BlocksGraphicsView::mousePressEvent(QMouseEvent* _event)
|
|||||||
m_selectionItem->setLeftRight(mouseX, mouseX);
|
m_selectionItem->setLeftRight(mouseX, mouseX);
|
||||||
m_selectionItem->hide();
|
m_selectionItem->hide();
|
||||||
m_pScrollbar->hideSelectionIndicator();
|
m_pScrollbar->hideSelectionIndicator();
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(m_rulerItem->isVisible());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,6 +1008,7 @@ void BlocksGraphicsView::mouseDoubleClickEvent(QMouseEvent* _event)
|
|||||||
m_rulerItem->setLeftRight(mouseX, mouseX);
|
m_rulerItem->setLeftRight(mouseX, mouseX);
|
||||||
m_rulerItem->hide();
|
m_rulerItem->hide();
|
||||||
emit sceneUpdated();
|
emit sceneUpdated();
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(m_selectionItem->isVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
_event->accept();
|
_event->accept();
|
||||||
@ -1035,6 +1035,7 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
|||||||
{
|
{
|
||||||
m_selectionItem->hide();
|
m_selectionItem->hide();
|
||||||
m_pScrollbar->hideSelectionIndicator();
|
m_pScrollbar->hideSelectionIndicator();
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(m_rulerItem->isVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_selectedBlocks.empty())
|
if (!m_selectedBlocks.empty())
|
||||||
@ -1071,6 +1072,7 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
|||||||
{
|
{
|
||||||
chronoHidden = true;
|
chronoHidden = true;
|
||||||
m_rulerItem->hide();
|
m_rulerItem->hide();
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(m_selectionItem->isVisible());
|
||||||
}
|
}
|
||||||
else if (m_selectionItem->isVisible() && m_selectionItem->hoverIndicator())
|
else if (m_selectionItem->isVisible() && m_selectionItem->hoverIndicator())
|
||||||
{
|
{
|
||||||
@ -1216,6 +1218,9 @@ void BlocksGraphicsView::addSelectionToHierarchy()
|
|||||||
|
|
||||||
void BlocksGraphicsView::onZoomSelection()
|
void BlocksGraphicsView::onZoomSelection()
|
||||||
{
|
{
|
||||||
|
if (m_selectionItem->width() < 1e-6)
|
||||||
|
return;
|
||||||
|
|
||||||
auto deltaScale = m_visibleRegionWidth / m_selectionItem->width();
|
auto deltaScale = m_visibleRegionWidth / m_selectionItem->width();
|
||||||
|
|
||||||
if (fabs(deltaScale - 1) < 1e-6)
|
if (fabs(deltaScale - 1) < 1e-6)
|
||||||
@ -1254,6 +1259,9 @@ void BlocksGraphicsView::onInspectCurrentView(bool _strict)
|
|||||||
m_selectionItem->show();
|
m_selectionItem->show();
|
||||||
m_pScrollbar->setSelectionPos(m_selectionItem->left(), m_selectionItem->right());
|
m_pScrollbar->setSelectionPos(m_selectionItem->left(), m_selectionItem->right());
|
||||||
m_pScrollbar->showSelectionIndicator();
|
m_pScrollbar->showSelectionIndicator();
|
||||||
|
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(true);
|
||||||
|
|
||||||
addSelectionToHierarchy();
|
addSelectionToHierarchy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1306,6 +1314,7 @@ bool BlocksGraphicsView::moveChrono(GraphicsRulerItem* _chronometerItem, qreal _
|
|||||||
if (!_chronometerItem->isVisible() && _chronometerItem->width() > 1e-6)
|
if (!_chronometerItem->isVisible() && _chronometerItem->width() > 1e-6)
|
||||||
{
|
{
|
||||||
_chronometerItem->show();
|
_chronometerItem->show();
|
||||||
|
emit EASY_GLOBALS.events.rulerVisible(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ namespace profiler_gui {
|
|||||||
void hexThreadIdChanged();
|
void hexThreadIdChanged();
|
||||||
void refreshRequired();
|
void refreshRequired();
|
||||||
void blocksTreeModeChanged();
|
void blocksTreeModeChanged();
|
||||||
|
void rulerVisible(bool);
|
||||||
|
|
||||||
void sceneCleared();
|
void sceneCleared();
|
||||||
void sceneSizeChanged(qreal left, qreal right);
|
void sceneSizeChanged(qreal left, qreal right);
|
||||||
|
@ -379,8 +379,10 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos
|
|||||||
});
|
});
|
||||||
|
|
||||||
action = toolbar->addAction(QIcon(imagePath("crop")), "Snapshot");
|
action = toolbar->addAction(QIcon(imagePath("crop")), "Snapshot");
|
||||||
action->setToolTip("Save selected area\nas separate .prof file.");
|
action->setToolTip("Take a snapshot.\nSave selected area to\nseparate .prof file.");
|
||||||
|
action->setEnabled(false);
|
||||||
connect(action, &QAction::triggered, this, &This::onSnapshotClicked);
|
connect(action, &QAction::triggered, this, &This::onSnapshotClicked);
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::rulerVisible, action, &QAction::setEnabled);
|
||||||
|
|
||||||
toolbar->addSeparator();
|
toolbar->addSeparator();
|
||||||
auto menu = new QMenu("Settings", this);
|
auto menu = new QMenu("Settings", this);
|
||||||
@ -1944,7 +1946,8 @@ void MainWindow::onLoadingFinish(profiler::block_index_t& _nblocks)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, "Warning", QString("Cannot read profiled blocks.\n\nReason:\n%1").arg(m_reader.getError()), QMessageBox::Close);
|
QMessageBox::warning(this, "Warning", QString("Cannot read profiled blocks.\n\nReason:\n%1")
|
||||||
|
.arg(m_reader.getError()), QMessageBox::Close);
|
||||||
|
|
||||||
if (m_reader.isFile())
|
if (m_reader.isFile())
|
||||||
{
|
{
|
||||||
@ -1964,7 +1967,12 @@ void MainWindow::onLoadingFinish(profiler::block_index_t& _nblocks)
|
|||||||
|
|
||||||
void MainWindow::onSavingFinish()
|
void MainWindow::onSavingFinish()
|
||||||
{
|
{
|
||||||
|
const auto errorMessage = m_reader.getError();
|
||||||
|
if (!errorMessage.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "Warning", QString("Cannot save profiled blocks.\n\nReason:\n%1")
|
||||||
|
.arg(errorMessage), QMessageBox::Close);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onFileReaderTimeout()
|
void MainWindow::onFileReaderTimeout()
|
||||||
@ -2114,7 +2122,8 @@ void FileReader::load(std::stringstream& _stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileReader::save(const QString& _filename, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime,
|
void FileReader::save(const QString& _filename, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime,
|
||||||
const profiler::SerializedData& _serializedDescriptors, profiler::block_id_t descriptors_count,
|
const profiler::SerializedData& _serializedDescriptors,
|
||||||
|
const profiler::descriptors_list_t& _descriptors, profiler::block_id_t descriptors_count,
|
||||||
const profiler::thread_blocks_tree_t& _trees, profiler::block_getter_fn block_getter,
|
const profiler::thread_blocks_tree_t& _trees, profiler::block_getter_fn block_getter,
|
||||||
profiler::processid_t _pid)
|
profiler::processid_t _pid)
|
||||||
{
|
{
|
||||||
@ -2125,13 +2134,37 @@ void FileReader::save(const QString& _filename, profiler::timestamp_t _beginTime
|
|||||||
m_filename = _filename;
|
m_filename = _filename;
|
||||||
|
|
||||||
auto serializedDescriptors = std::ref(_serializedDescriptors);
|
auto serializedDescriptors = std::ref(_serializedDescriptors);
|
||||||
|
auto descriptors = std::ref(_descriptors);
|
||||||
auto trees = std::ref(_trees);
|
auto trees = std::ref(_trees);
|
||||||
|
|
||||||
m_thread = std::thread([=] (profiler::block_getter_fn getter) {
|
m_thread = std::thread([=] (profiler::block_getter_fn getter)
|
||||||
writeTreesToFile(m_progress, m_filename.toStdString().c_str(), serializedDescriptors, descriptors_count, trees,
|
{
|
||||||
getter, _beginTime, _endTime, _pid, m_errorMessage);
|
const QString tmpFile = m_filename + ".tmp";
|
||||||
|
|
||||||
|
const auto result = writeTreesToFile(m_progress, tmpFile.toStdString().c_str(), serializedDescriptors,
|
||||||
|
descriptors, descriptors_count, trees, getter, _beginTime, _endTime,
|
||||||
|
_pid, m_errorMessage);
|
||||||
|
|
||||||
|
if (result == 0 || !m_errorMessage.str().empty())
|
||||||
|
{
|
||||||
|
// Remove temporary file in case of error
|
||||||
|
QFile::remove(tmpFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Remove old file if exists
|
||||||
|
{
|
||||||
|
QFile out(m_filename);
|
||||||
|
if (out.exists())
|
||||||
|
out.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile::rename(tmpFile, m_filename);
|
||||||
|
}
|
||||||
|
|
||||||
m_progress.store(100, std::memory_order_release);
|
m_progress.store(100, std::memory_order_release);
|
||||||
m_bDone.store(true, std::memory_order_release);
|
m_bDone.store(true, std::memory_order_release);
|
||||||
|
|
||||||
}, std::move(block_getter));
|
}, std::move(block_getter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2254,8 +2287,9 @@ void MainWindow::onSnapshotClicked(bool)
|
|||||||
|
|
||||||
createProgressDialog(tr("Saving selected region..."));
|
createProgressDialog(tr("Saving selected region..."));
|
||||||
m_readerTimer.start();
|
m_readerTimer.start();
|
||||||
m_reader.save(filename, beginTime, endTime, m_serializedDescriptors, m_descriptorsNumberInFile,
|
|
||||||
EASY_GLOBALS.profiler_blocks, easyBlocksTree, EASY_GLOBALS.pid);
|
m_reader.save(filename, beginTime, endTime, m_serializedDescriptors, EASY_GLOBALS.descriptors,
|
||||||
|
m_descriptorsNumberInFile, EASY_GLOBALS.profiler_blocks, easyBlocksTree, EASY_GLOBALS.pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -130,8 +130,9 @@ public:
|
|||||||
/** \brief Save data to file.
|
/** \brief Save data to file.
|
||||||
*/
|
*/
|
||||||
void save(const QString& _filename, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime,
|
void save(const QString& _filename, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime,
|
||||||
const profiler::SerializedData& _serializedDescriptors, profiler::block_id_t descriptors_count,
|
const profiler::SerializedData& _serializedDescriptors, const profiler::descriptors_list_t& _descriptors,
|
||||||
const profiler::thread_blocks_tree_t& _trees, profiler::block_getter_fn block_getter, profiler::processid_t _pid);
|
profiler::block_id_t descriptors_count, const profiler::thread_blocks_tree_t& _trees,
|
||||||
|
profiler::block_getter_fn block_getter, profiler::processid_t _pid);
|
||||||
|
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void get(profiler::SerializedData& _serializedBlocks, profiler::SerializedData& _serializedDescriptors,
|
void get(profiler::SerializedData& _serializedBlocks, profiler::SerializedData& _serializedDescriptors,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user