mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 00:21:11 +08:00
#91 [UI] Snapshot feature further progress (intermediate commit)
This commit is contained in:
parent
ef7b41fd0d
commit
ae5c46477d
@ -119,37 +119,11 @@ const uint64_t TIME_FACTOR = 1000000000ULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct BlocksRange
|
||||
{
|
||||
profiler::block_index_t begin;
|
||||
profiler::block_index_t end;
|
||||
};
|
||||
|
||||
struct BlocksAndCSwitchesRange
|
||||
{
|
||||
BlocksRange blocks;
|
||||
BlocksRange cswitches;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool isCompatibleVersion(uint32_t _version)
|
||||
{
|
||||
return _version >= MIN_COMPATIBLE_VERSION;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void write(std::ostream& _stream, const char* _data, T _size)
|
||||
{
|
||||
_stream.write(_data, _size);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void write(std::ostream& _stream, const T& _data)
|
||||
{
|
||||
_stream.write((const char*)&_data, sizeof(T));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace profiler {
|
||||
@ -194,7 +168,7 @@ namespace profiler {
|
||||
_stats = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
} // end of namespace profiler.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -488,9 +462,7 @@ bool readHeader_v2(EasyFileHeader& _header, std::istream& inFile, std::ostream&
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" {
|
||||
|
||||
PROFILER_API profiler::block_index_t fillTreesFromFile(std::atomic<int>& progress, const char* filename,
|
||||
extern "C" PROFILER_API profiler::block_index_t fillTreesFromFile(std::atomic<int>& progress, const char* filename,
|
||||
profiler::SerializedData& serialized_blocks,
|
||||
profiler::SerializedData& serialized_descriptors,
|
||||
profiler::descriptors_list_t& descriptors,
|
||||
@ -523,7 +495,7 @@ extern "C" {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<int>& progress, std::istream& inFile,
|
||||
extern "C" PROFILER_API profiler::block_index_t fillTreesFromStream(std::atomic<int>& progress, std::istream& inFile,
|
||||
profiler::SerializedData& serialized_blocks,
|
||||
profiler::SerializedData& serialized_descriptors,
|
||||
profiler::descriptors_list_t& descriptors,
|
||||
@ -998,7 +970,7 @@ extern "C" {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PROFILER_API bool readDescriptionsFromStream(std::atomic<int>& progress, std::istream& inFile,
|
||||
extern "C" PROFILER_API bool readDescriptionsFromStream(std::atomic<int>& progress, std::istream& inFile,
|
||||
profiler::SerializedData& serialized_descriptors,
|
||||
profiler::descriptors_list_t& descriptors,
|
||||
std::ostream& _log)
|
||||
@ -1079,7 +1051,78 @@ extern "C" {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
||||
struct BlocksRange
|
||||
{
|
||||
profiler::block_index_t begin;
|
||||
profiler::block_index_t end;
|
||||
};
|
||||
|
||||
struct BlocksAndCSwitchesRange
|
||||
{
|
||||
BlocksRange blocks;
|
||||
BlocksRange cswitches;
|
||||
};
|
||||
|
||||
struct BlocksMemoryAndCount
|
||||
{
|
||||
uint64_t usedMemorySize = 0; // memory size used by profiler blocks
|
||||
profiler::block_index_t blocksCount = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline void write(std::ostream& _stream, const char* _data, T _size)
|
||||
{
|
||||
_stream.write(_data, _size);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void write(std::ostream& _stream, const T& _data)
|
||||
{
|
||||
_stream.write((const char*)&_data, sizeof(T));
|
||||
}
|
||||
|
||||
BlocksRange findRange(const profiler::BlocksTree::children_t& children, profiler::timestamp_t beginTime, profiler::timestamp_t endTime,
|
||||
const profiler::block_getter_fn& getter)
|
||||
{
|
||||
const auto size = static_cast<profiler::block_index_t>(children.size());
|
||||
BlocksRange range {size, size};
|
||||
|
||||
auto first_it = std::lower_bound(children.begin(), children.end(), beginTime, [&](profiler::block_index_t element, profiler::timestamp_t value)
|
||||
{
|
||||
return getter(element).node->end() < value;
|
||||
});
|
||||
|
||||
for (auto it = first_it; it != children.end(); ++it)
|
||||
{
|
||||
const auto& child = getter(*it);
|
||||
if (child.node->begin() >= beginTime || child.node->end() > beginTime)
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_it != children.end() && getter(*first_it).node->begin() <= endTime)
|
||||
{
|
||||
auto last_it = std::lower_bound(children.begin(), children.end(), endTime, [&](profiler::block_index_t element, profiler::timestamp_t value)
|
||||
{
|
||||
return getter(element).node->begin() <= value;
|
||||
});
|
||||
|
||||
if (last_it != children.end() && getter(*last_it).node->end() >= beginTime)
|
||||
{
|
||||
const auto begin = static_cast<profiler::block_index_t>(std::distance(children.begin(), first_it));
|
||||
const auto end = static_cast<profiler::block_index_t>(std::distance(children.begin(), last_it));
|
||||
|
||||
if (begin <= end)
|
||||
{
|
||||
range.begin = begin;
|
||||
range.end = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
extern "C" PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
|
||||
const profiler::SerializedData& serialized_descriptors,
|
||||
profiler::block_id_t descriptors_count,
|
||||
const profiler::thread_blocks_tree_t& trees,
|
||||
@ -1090,9 +1133,7 @@ extern "C" {
|
||||
std::ostream& log)
|
||||
{
|
||||
if (!update_progress_write(progress, 0, log))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ofstream outFile(filename, std::fstream::binary);
|
||||
if (!outFile.is_open())
|
||||
@ -1110,7 +1151,7 @@ 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,
|
||||
profiler::block_id_t descriptors_count,
|
||||
const profiler::thread_blocks_tree_t& trees,
|
||||
@ -1126,40 +1167,35 @@ extern "C" {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BlocksMemoryAndCount total;
|
||||
|
||||
using ranges_t = std::unordered_map<profiler::thread_id_t, BlocksAndCSwitchesRange, estd::hash<profiler::thread_id_t> >;
|
||||
ranges_t block_ranges;
|
||||
|
||||
size_t counter = 0, i = 0;
|
||||
for (const auto& kv : trees)
|
||||
{
|
||||
const auto id = kv.first;
|
||||
const auto& tree = kv.second;
|
||||
const auto childrenRange = findRange(tree.children, begin_time, end_time, block_getter);
|
||||
const auto cswitcesRange = findRange(tree.sync, begin_time, end_time, block_getter);
|
||||
|
||||
const auto children_size = tree.children.size();
|
||||
const auto csitches_size = tree.sync.size();
|
||||
BlocksAndCSwitchesRange ranges {{children_size, children_size}, {csitches_size, csitches_size}};
|
||||
counter += childrenRange.end - childrenRange.begin;
|
||||
counter += cswitcesRange.end - cswitcesRange.begin;
|
||||
block_ranges[id] = BlocksAndCSwitchesRange {childrenRange, cswitcesRange};
|
||||
|
||||
auto first_it = std::lower_bound(tree.children.begin(), tree.children.end(), begin_time, [&](profiler::block_index_t element, profiler::timestamp_t value)
|
||||
{
|
||||
block_getter(element).node->begin() < value;
|
||||
});
|
||||
if (!update_progress_write(progress, 15 / static_cast<int>(trees.size() - i), log))
|
||||
return 0;
|
||||
|
||||
if (first_it != tree.children.end())
|
||||
{
|
||||
auto last_it = std::lower_bound(tree.children.begin(), tree.children.end(), end_time, [&](profiler::block_index_t element, profiler::timestamp_t value)
|
||||
{
|
||||
block_getter(element).node->end() < value;
|
||||
});
|
||||
|
||||
if (last_it != tree.children.end())
|
||||
{
|
||||
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
block_ranges[id] = ranges;
|
||||
if (counter == 0)
|
||||
{
|
||||
log << "Nothing to save";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
write(str, PROFILER_SIGNATURE);
|
||||
write(str, EASY_CURRENT_VERSION);
|
||||
write(str, pid);
|
||||
@ -1170,23 +1206,18 @@ extern "C" {
|
||||
write(str, begin_time);
|
||||
write(str, end_time);
|
||||
|
||||
uint64_t usedMemorySize = 0; // memory size used by profiler blocks
|
||||
profiler::block_index_t blocksCount = 0;
|
||||
|
||||
write(str, usedMemorySize);
|
||||
write(str, total.usedMemorySize);
|
||||
write(str, serialized_descriptors.size());
|
||||
write(str, blocksCount);
|
||||
write(str, total.blocksCount);
|
||||
write(str, descriptors_count);
|
||||
|
||||
log << "Not implemented";
|
||||
progress.store(100, std::memory_order_release);
|
||||
return blocksCount;
|
||||
return total.blocksCount;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#undef EASY_CONVERT_TO_NANO
|
||||
|
||||
#ifdef EASY_USE_FLOATING_POINT_CONVERSION
|
||||
|
@ -378,9 +378,9 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos
|
||||
static_cast<DiagramWidget*>(m_graphicsView->widget())->view()->inspectCurrentView(true);
|
||||
});
|
||||
|
||||
action = toolbar->addAction(QIcon(imagePath("crop")), "Crop and save");
|
||||
action->setToolTip("Crop and save selected area\nas separate .prof file.");
|
||||
connect(action, &QAction::triggered, this, &This::onCropAndSaveClicked);
|
||||
action = toolbar->addAction(QIcon(imagePath("crop")), "Snapshot");
|
||||
action->setToolTip("Save selected area\nas separate .prof file.");
|
||||
connect(action, &QAction::triggered, this, &This::onSnapshotClicked);
|
||||
|
||||
toolbar->addSeparator();
|
||||
auto menu = new QMenu("Settings", this);
|
||||
@ -2230,7 +2230,7 @@ void MainWindow::onFrameTimeChanged()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MainWindow::onCropAndSaveClicked(bool)
|
||||
void MainWindow::onSnapshotClicked(bool)
|
||||
{
|
||||
profiler::timestamp_t beginTime = 0, endTime = 0;
|
||||
const bool hasSelection = static_cast<DiagramWidget*>(m_graphicsView->widget())->view()->getSelectionRegionForSaving(beginTime, endTime);
|
||||
|
@ -346,7 +346,7 @@ protected slots:
|
||||
void onEventTracingEnableChange(bool _checked);
|
||||
void onFrameTimeEditFinish();
|
||||
void onFrameTimeChanged();
|
||||
void onCropAndSaveClicked(bool);
|
||||
void onSnapshotClicked(bool);
|
||||
|
||||
void onBlockStatusChange(profiler::block_id_t _id, profiler::EasyBlockStatus _status);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user