0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-26 16:11:02 +08:00

#91 [UI] Snapshot feature further progress (intermediate commit)

This commit is contained in:
Victor Zarubkin 2018-04-22 16:15:10 +03:00
parent ef7b41fd0d
commit ae5c46477d
3 changed files with 666 additions and 635 deletions

View File

@ -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,
@ -501,7 +473,7 @@ extern "C" {
profiler::processid_t& pid,
bool gather_statistics,
std::ostream& _log)
{
{
if (!update_progress(progress, 0, _log))
{
return 0;
@ -519,11 +491,11 @@ extern "C" {
threaded_trees, total_descriptors_number, version, pid, gather_statistics, _log);
return result;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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,
@ -534,7 +506,7 @@ extern "C" {
profiler::processid_t& pid,
bool gather_statistics,
std::ostream& _log)
{
{
EASY_FUNCTION(profiler::colors::Cyan);
if (!update_progress(progress, 0, _log))
@ -994,15 +966,15 @@ extern "C" {
progress.store(100, std::memory_order_release);
return blocks_counter;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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)
{
{
EASY_FUNCTION(profiler::colors::Cyan);
progress.store(0);
@ -1073,13 +1045,84 @@ extern "C" {
}
return !descriptors.empty();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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;
});
PROFILER_API profiler::block_index_t writeTreesToFile(std::atomic<int>& progress, const char* filename,
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,
@ -1088,11 +1131,9 @@ extern "C" {
profiler::timestamp_t end_time,
profiler::processid_t pid,
std::ostream& log)
{
{
if (!update_progress_write(progress, 0, log))
{
return 0;
}
std::ofstream outFile(filename, std::fstream::binary);
if (!outFile.is_open())
@ -1106,11 +1147,11 @@ extern "C" {
begin_time, end_time, pid, log);
return result;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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,
@ -1119,47 +1160,42 @@ extern "C" {
profiler::timestamp_t end_time,
profiler::processid_t pid,
std::ostream& log)
{
{
if (trees.empty() || serialized_descriptors.empty() || descriptors_count == 0)
{
log << "Nothing to save";
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

View File

@ -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);

View File

@ -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);