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

(profiler_gui) Added tool-button "Clear all";

(profiler_gui) Prepare for append blocks
This commit is contained in:
Victor Zarubkin 2016-09-21 22:09:04 +03:00
parent d6269f17fe
commit 7f5b7c00a8
13 changed files with 276 additions and 73 deletions

View File

@ -57,6 +57,8 @@ namespace profiler {
{
}
//BlockStatistics() = default;
inline ::profiler::timestamp_t average_duration() const
{
return total_duration / calls_number;
@ -65,7 +67,7 @@ namespace profiler {
}; // END of struct BlockStatistics.
#pragma pack(pop)
extern "C" void PROFILER_API release_stats(BlockStatistics*& _stats);
extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats);
//////////////////////////////////////////////////////////////////////////
@ -208,13 +210,11 @@ namespace profiler {
inline bool got_name() const
{
//return thread_name && *thread_name != 0;
return thread_name.front() != 0;
}
inline const char* name() const
{
//return thread_name;
return thread_name.c_str();
}
@ -238,16 +238,18 @@ namespace profiler {
class PROFILER_API SerializedData final
{
char* m_data;
size_t m_size;
public:
SerializedData() : m_data(nullptr)
SerializedData() : m_data(nullptr), m_size(0)
{
}
SerializedData(SerializedData&& that) : m_data(that.m_data)
SerializedData(SerializedData&& that) : m_data(that.m_data), m_size(that.m_size)
{
that.m_data = nullptr;
that.m_size = 0;
}
~SerializedData()
@ -255,12 +257,14 @@ namespace profiler {
clear();
}
void set(char* _data);
void set(size_t _size);
void extend(size_t _size);
SerializedData& operator = (SerializedData&& that)
{
set(that.m_data);
set(that.m_data, that.m_size);
that.m_data = nullptr;
that.m_size = 0;
return *this;
}
@ -269,20 +273,42 @@ namespace profiler {
return m_data + i;
}
size_t size() const
{
return m_size;
}
char* data()
{
return m_data;
}
const char* data() const
{
return m_data;
}
void clear()
{
set(nullptr);
set(nullptr, 0);
}
void swap(SerializedData& other)
{
auto temp = other.m_data;
char* d = other.m_data;
size_t sz = other.m_size;
other.m_data = m_data;
m_data = temp;
other.m_size = m_size;
m_data = d;
m_size = sz;
}
private:
void set(char* _data, size_t _size);
SerializedData(const SerializedData&) = delete;
SerializedData& operator = (const SerializedData&) = delete;
@ -294,18 +320,18 @@ namespace profiler {
} // END of namespace profiler.
extern "C" ::profiler::block_index_t PROFILER_API 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,
::profiler::blocks_t& _blocks,
::profiler::thread_blocks_tree_t& threaded_trees,
bool gather_statistics = false);
bool gather_statistics);
inline ::profiler::block_index_t fillTreesFromFile(const char* filename, ::profiler::SerializedData& serialized_blocks,
::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors,
::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& threaded_trees,
bool gather_statistics = false)
bool gather_statistics)
{
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
return fillTreesFromFile(progress, filename, serialized_blocks, serialized_descriptors, descriptors, _blocks, threaded_trees, gather_statistics);

View File

@ -307,7 +307,7 @@ EasyChronometerItem* EasyGraphicsView::createChronometer(bool _main)
//////////////////////////////////////////////////////////////////////////
void EasyGraphicsView::clearSilent()
void EasyGraphicsView::clear()
{
const QSignalBlocker blocker(this), sceneBlocker(scene()); // block all scene signals (otherwise clear() would be extremely slow!)
@ -341,7 +341,6 @@ void EasyGraphicsView::clearSilent()
m_idleTime = 0;
// Reset necessary flags
//m_bTest = false;
m_bEmpty = true;
// notify ProfTreeWidget that selection was reset
@ -351,7 +350,7 @@ void EasyGraphicsView::clearSilent()
void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTree)
{
// clear scene
clearSilent();
clear();
if (_blocksTree.empty())
{
@ -450,7 +449,7 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
// Calculating scene rect
const qreal endX = time2position(finish) + 1500.0;
scene()->setSceneRect(0, 0, endX, y + TIMELINE_ROW_SIZE);
setSceneRect(0, 0, endX, y + TIMELINE_ROW_SIZE);
// Center view on the beginning of the scene
updateVisibleSceneRect();
@ -602,11 +601,9 @@ void EasyGraphicsView::setScrollbar(EasyGraphicsScrollbar* _scrollbar)
}
m_pScrollbar = _scrollbar;
m_pScrollbar->setMinimapFrom(0, nullptr);
m_pScrollbar->hideChrono();
m_pScrollbar->clear();
m_pScrollbar->setRange(0, scene()->width());
m_pScrollbar->setSliderWidth(m_visibleSceneRect.width());
m_pScrollbar->setValue(0);
if (makeConnect)
{
@ -1444,6 +1441,14 @@ EasyGraphicsView* EasyGraphicsViewWidget::view()
return m_view;
}
void EasyGraphicsViewWidget::clear()
{
m_scrollbar->clear();
m_threadNamesWidget->clear();
m_view->clear();
m_view->setSceneRect(0, 0, 10, 10);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@ -1506,6 +1511,17 @@ void EasyThreadNameItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte
_painter->drawText(rect, Qt::AlignRight | Qt::AlignVCenter, item->threadName());
}
const auto rect_bottom = rect.bottom();
if (rect_bottom < h)
{
++i;
rect.translate(5, rect.height());
rect.setHeight(h - rect_bottom);
_painter->setBrush(brushes[i & 1]);
_painter->setPen(Qt::NoPen);
_painter->drawRect(rect);
}
// Draw separator between thread names area and information area
_painter->setPen(Qt::darkGray);
_painter->drawLine(QLineF(0, h, w, h));
@ -1567,6 +1583,13 @@ EasyThreadNamesWidget::~EasyThreadNamesWidget()
}
void EasyThreadNamesWidget::clear()
{
const QSignalBlocker b(this);
scene()->clear();
setFixedWidth(100);
}
void EasyThreadNamesWidget::setVerticalScrollbarRange(int _minValue, int _maxValue)
{
verticalScrollBar()->setRange(_minValue, _maxValue + m_additionalHeight);

View File

@ -141,7 +141,7 @@ public:
qreal chronoTimeAux() const;
void setScrollbar(EasyGraphicsScrollbar* _scrollbar);
void clearSilent();
void clear();
void setTree(const ::profiler::thread_blocks_tree_t& _blocksTree);
@ -246,6 +246,8 @@ public:
void keyPressEvent(QKeyEvent* _event) override;
void keyReleaseEvent(QKeyEvent* _event) override;
void clear();
const EasyGraphicsView* view() const
{
return m_view;
@ -278,6 +280,7 @@ public:
virtual ~EasyGraphicsViewWidget();
EasyGraphicsView* view();
void clear();
private:

View File

@ -733,6 +733,11 @@ void EasyDescWidget::build()
m_tree->build();
}
void EasyDescWidget::clear()
{
m_tree->clearSilent(true);
}
void EasyDescWidget::onSeachBoxReturnPressed()
{
auto matches = m_tree->findNext(m_searchBox->text());

View File

@ -152,6 +152,7 @@ public:
// Public non-virtual methods
void build();
void clear();
private slots:

View File

@ -349,6 +349,17 @@ EasyGraphicsScrollbar::~EasyGraphicsScrollbar()
//////////////////////////////////////////////////////////////////////////
void EasyGraphicsScrollbar::clear()
{
setMinimapFrom(0, nullptr);
hideChrono();
setRange(0, 100);
setSliderWidth(2);
setValue(0);
}
//////////////////////////////////////////////////////////////////////////
qreal EasyGraphicsScrollbar::getWindowScale() const
{
return m_windowScale;

View File

@ -145,6 +145,8 @@ public:
// Public non-virtual methods
void clear();
qreal getWindowScale() const;
::profiler::thread_id_t minimapThread() const;

View File

@ -14,3 +14,4 @@ lan_on.svg - Icon made by Freepik from www.flaticon.com
wifi.svg - Icon made by Freepik from www.flaticon.com
wifi_on.svg - Icon made by Freepik from www.flaticon.com
play.svg - Icon made by Google from www.flaticon.com
delete.svg - Icon made by Freepik from www.flaticon.com

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 443 443" style="enable-background:new 0 0 443 443;" xml:space="preserve">
<g>
<rect x="61.785" y="128" width="60" height="290"/>
<path style="fill:#212121;" d="M211.785,250.65V128h-60v290h44.172c-14.861-21.067-23.602-46.746-23.602-74.43
C172.356,307.145,187.486,274.193,211.785,250.65z"/>
<path style="fill:#212121;" d="M301.785,214.141l0-86.141h-60v100.918C259.731,219.488,280.144,214.141,301.785,214.141z"/>
<path style="fill:#212121;" d="M321.785,38h-83.384V0H125.169v38H41.785v60h280V38z M155.169,30h53.232v8h-53.232V30z"/>
<path style="fill:#f44336;" d="M301.785,244.141c-54.826,0-99.429,44.604-99.429,99.429S246.959,443,301.785,443s99.43-44.604,99.43-99.43
S356.611,244.141,301.785,244.141z M355.961,376.533l-21.213,21.213l-32.963-32.963l-32.963,32.963l-21.213-21.213l32.963-32.963
l-32.963-32.963l21.213-21.213l32.963,32.963l32.963-32.963l21.213,21.213l-32.963,32.963L355.961,376.533z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -120,6 +120,7 @@ EasyMainWindow::EasyMainWindow() : Parent()
auto toolbar = addToolBar("MainToolBar");
toolbar->setObjectName("ProfilerGUI_MainToolBar");
toolbar->addAction(QIcon(":/Delete"), tr("Clear all"), this, SLOT(onDeleteClicked(bool)));
m_captureAction = toolbar->addAction(QIcon(":/Start"), tr("Capture"), this, SLOT(onCaptureClicked(bool)));
m_captureAction->setEnabled(false);
@ -259,6 +260,8 @@ EasyMainWindow::EasyMainWindow() : Parent()
menu = menuBar()->addMenu("&Edit");
m_editBlocksAction = menu->addAction(tr("Edit blocks"), this, SLOT(onEditBlocksClicked(bool)));
m_editBlocksAction->setEnabled(false);
action = menu->addAction(tr("Clear all"), this, SLOT(onDeleteClicked(bool)));
SET_ICON(action, ":/Delete");
@ -469,7 +472,7 @@ void EasyMainWindow::listen()
loaded += toWrite;
seek = toWrite;
m_downloadedBytes.store((loaded / (neededSize+1)) * 100);
m_downloadedBytes.store((100 * loaded / (neededSize + 1)), ::std::memory_order_release);
}
break;
@ -530,6 +533,30 @@ void EasyMainWindow::onReloadFileClicked(bool)
//////////////////////////////////////////////////////////////////////////
void EasyMainWindow::onDeleteClicked(bool)
{
static_cast<EasyTreeWidget*>(m_treeWidget->widget())->clearSilent(true);
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->clear();
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0
static_cast<EasyDescWidget*>(m_descTreeWidget->widget())->clear();
#endif
if (m_dialogDescTree != nullptr)
m_dialogDescTree->clear();
m_editBlocksAction->setEnabled(false);
EASY_GLOBALS.selected_thread = 0;
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
EASY_GLOBALS.profiler_blocks.clear();
EASY_GLOBALS.descriptors.clear();
EASY_GLOBALS.gui_blocks.clear();
m_serializedBlocks.clear();
m_serializedDescriptors.clear();
}
//////////////////////////////////////////////////////////////////////////
void EasyMainWindow::onExitClicked(bool)
{
close();
@ -768,7 +795,7 @@ void EasyMainWindow::onDownloadTimeout()
m_downloadedTimer.stop();
}
else{
m_downloadingProgress->setValue(m_downloadedBytes.load());
m_downloadingProgress->setValue(m_downloadedBytes.load(::std::memory_order_acquire));
}
}
@ -865,17 +892,17 @@ EasyFileReader::~EasyFileReader()
bool EasyFileReader::done() const
{
return m_bDone.load();
return m_bDone.load(::std::memory_order_acquire);
}
int EasyFileReader::progress() const
{
return m_progress.load();
return m_progress.load(::std::memory_order_acquire);
}
unsigned int EasyFileReader::size() const
{
return m_size.load();
return m_size.load(::std::memory_order_acquire);
}
const QString& EasyFileReader::filename() const
@ -889,21 +916,21 @@ void EasyFileReader::load(const QString& _filename)
m_filename = _filename;
m_thread = ::std::move(::std::thread([this](bool _enableStatistics) {
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors, m_descriptors, m_blocks, m_blocksTree, _enableStatistics));
m_progress.store(100);
m_bDone.store(true);
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors, m_descriptors, m_blocks, m_blocksTree, _enableStatistics), ::std::memory_order_release);
m_progress.store(100, ::std::memory_order_release);
m_bDone.store(true, ::std::memory_order_release);
}, EASY_GLOBALS.enable_statistics));
}
void EasyFileReader::interrupt()
{
m_progress.store(-100);
m_progress.store(-100, ::std::memory_order_release);
if (m_thread.joinable())
m_thread.join();
m_bDone.store(false);
m_progress.store(0);
m_size.store(0);
m_bDone.store(false, ::std::memory_order_release);
m_progress.store(0, ::std::memory_order_release);
m_size.store(0, ::std::memory_order_release);
m_serializedBlocks.clear();
m_serializedDescriptors.clear();
m_descriptors.clear();

View File

@ -153,6 +153,7 @@ protected slots:
void onOpenFileClicked(bool);
void onReloadFileClicked(bool);
void onDeleteClicked(bool);
void onExitClicked(bool);
void onEncodingChanged(bool);
void onChronoTextPosChanged(bool);

View File

@ -18,5 +18,6 @@
<file alias="Connection">icons/lan.svg</file>
<file alias="Connection-on">icons/lan_on.svg</file>
<file alias="Start">icons/play.svg</file>
<file alias="Delete">icons/delete.svg</file>
</qresource>
</RCC>

View File

@ -54,24 +54,42 @@
namespace profiler {
void SerializedData::set(char* _data)
void SerializedData::set(char* _data, size_t _size)
{
if (m_data != nullptr)
delete [] m_data;
m_data = _data;
m_size = _size;
}
extern "C" void release_stats(BlockStatistics*& _stats)
void SerializedData::set(size_t _size)
{
if (!_stats)
{
return;
if (_size != 0)
set(new char[_size], _size);
else
set(nullptr, 0);
}
void SerializedData::extend(size_t _size)
{
auto olddata = m_data;
auto oldsize = m_size;
m_size = oldsize + _size;
m_data = new char[m_size];
if (olddata != nullptr) {
memcpy(m_data, olddata, oldsize);
delete [] olddata;
}
}
extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats)
{
if (_stats == nullptr)
return;
if (--_stats->calls_number == 0)
{
delete _stats;
}
_stats = nullptr;
}
@ -159,14 +177,53 @@ void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _
{
_current.per_frame_stats = update_statistics(_stats_map, _current, _current_index, _parent_index);
for (auto i : _current.children)
{
update_statistics_recursive(_stats_map, _blocks[i], i, _parent_index, _blocks);
}
}
//////////////////////////////////////////////////////////////////////////
extern "C" ::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, ::profiler::blocks_t& blocks, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics)
/*void validate_pointers(::std::atomic<int>& _progress, const char* _oldbase, ::profiler::SerializedData& _serialized_blocks, ::profiler::blocks_t& _blocks, size_t _size)
{
if (_oldbase == nullptr)
{
_progress.store(25, ::std::memory_order_release);
return;
}
for (size_t i = 0; i < _size; ++i)
{
auto& tree = _blocks[i];
auto dist = ::std::distance(_oldbase, reinterpret_cast<const char*>(tree.node));
tree.node = reinterpret_cast<::profiler::SerializedBlock*>(_serialized_blocks.data() + dist);
_progress.store(20 + static_cast<int>(5 * i / _size), ::std::memory_order_release);
}
}
void validate_pointers(::std::atomic<int>& _progress, const char* _oldbase, ::profiler::SerializedData& _serialized_descriptors, ::profiler::descriptors_list_t& _descriptors, size_t _size)
{
if (_oldbase == nullptr)
{
_progress.store(5, ::std::memory_order_release);
return;
}
for (size_t i = 0; i < _size; ++i)
{
auto dist = ::std::distance(_oldbase, reinterpret_cast<const char*>(_descriptors[i]));
_descriptors[i] = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(_serialized_descriptors.data() + dist);
_progress.store(static_cast<int>(5 * i / _size));
}
}*/
//////////////////////////////////////////////////////////////////////////
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,
::profiler::blocks_t& blocks,
::profiler::thread_blocks_tree_t& threaded_trees,
bool gather_statistics)
{
EASY_FUNCTION(::profiler::colors::Cyan);
@ -189,10 +246,6 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
if (memory_size == 0)
return 0;
serialized_blocks.set(new char[memory_size]);
//memset(serialized_blocks[0], 0, memory_size);
uint32_t total_descriptors_number = 0;
inFile.read((char*)&total_descriptors_number, sizeof(decltype(total_descriptors_number)));
if (total_descriptors_number == 0)
@ -204,7 +257,9 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
return 0;
descriptors.reserve(total_descriptors_number);
serialized_descriptors.set(new char[descriptors_memory_size]);
//const char* olddata = append_regime ? serialized_descriptors.data() : nullptr;
serialized_descriptors.set(descriptors_memory_size);
//validate_pointers(progress, olddata, serialized_descriptors, descriptors, descriptors.size());
uint64_t i = 0;
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
@ -228,19 +283,25 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
descriptors.push_back(descriptor);
i += sz;
progress.store(static_cast<int>(10 * i / descriptors_memory_size));
progress.store(static_cast<int>(15 * i / descriptors_memory_size), ::std::memory_order_release);
}
if (progress.load(::std::memory_order_acquire) < 0)
return 0; // Loading interrupted
typedef ::std::unordered_map<::profiler::thread_id_t, StatsMap, ::profiler::passthrough_hash> PerThreadStats;
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
IdMap identification_table;
::std::vector<char> name;
blocks.reserve(total_blocks_number);
//olddata = append_regime ? serialized_blocks.data() : nullptr;
serialized_blocks.set(memory_size);
//validate_pointers(progress, olddata, serialized_blocks, blocks, blocks.size());
i = 0;
uint32_t read_number = 0;
::profiler::block_index_t blocks_counter = 0;
blocks.reserve(total_blocks_number);
::std::vector<char> name;
while (!inFile.eof() && read_number < total_blocks_number)
{
EASY_BLOCK("Read thread data", ::profiler::colors::DarkGreen);
@ -297,14 +358,14 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
root.sync.emplace_back(block_index);
if (progress.load() < 0)
break;
if (progress.load(::std::memory_order_acquire) < 0)
break; // Loading interrupted
progress.store(10 + static_cast<int>(80 * i / memory_size));
progress.store(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
}
if (progress.load() < 0 || inFile.eof())
break;
if (progress.load(::std::memory_order_acquire) < 0 || inFile.eof())
break; // Loading interrupted
blocks_number_in_thread = 0;
inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread)));
@ -434,19 +495,15 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
tree.per_thread_stats = update_statistics(per_thread_statistics, tree, block_index, thread_id);
}
if (progress.load() < 0)
break;
progress.store(10 + static_cast<int>(80 * i / memory_size));
if (progress.load(::std::memory_order_acquire) < 0)
break; // Loading interrupted
progress.store(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
}
}
if (progress.load() < 0)
{
serialized_blocks.clear();
threaded_trees.clear();
blocks.clear();
return 0;
}
if (progress.load(::std::memory_order_acquire) < 0)
return 0; // Loading interrupted
EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple);
if (gather_statistics)
@ -493,7 +550,7 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
for (auto& t : statistics_threads)
{
t.join();
progress.store(90 + (10 * ++j) / n);
progress.store(90 + (10 * ++j) / n, ::std::memory_order_release);
}
}
else
@ -520,7 +577,7 @@ extern "C" ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progr
++root.depth;
progress.store(90 + (10 * ++j) / n);
progress.store(90 + (10 * ++j) / n, ::std::memory_order_release);
}
}
// No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors