mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
Saving network data using temporary cache file + Question box when clicked on "Clear all"
This commit is contained in:
parent
817083d3ff
commit
dc01c49020
@ -78,7 +78,6 @@ namespace profiler {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef ::std::vector<This> blocks_t;
|
typedef ::std::vector<This> blocks_t;
|
||||||
typedef ::std::vector<This*> pblocks_t;
|
|
||||||
typedef ::std::vector<::profiler::block_index_t> children_t;
|
typedef ::std::vector<::profiler::block_index_t> children_t;
|
||||||
|
|
||||||
children_t children; ///< List of children blocks. May be empty.
|
children_t children; ///< List of children blocks. May be empty.
|
||||||
@ -235,7 +234,6 @@ namespace profiler {
|
|||||||
}; // END of class BlocksTreeRoot.
|
}; // END of class BlocksTreeRoot.
|
||||||
|
|
||||||
typedef ::profiler::BlocksTree::blocks_t blocks_t;
|
typedef ::profiler::BlocksTree::blocks_t blocks_t;
|
||||||
typedef ::profiler::BlocksTree::pblocks_t pblocks_t;
|
|
||||||
typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::profiler::passthrough_hash> thread_blocks_tree_t;
|
typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::profiler::passthrough_hash> thread_blocks_tree_t;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -383,18 +381,22 @@ namespace profiler {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progress, const char* filename,
|
PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progress, const char* filename,
|
||||||
::profiler::FileData& filedata,
|
::profiler::SerializedData& serialized_blocks,
|
||||||
|
::profiler::SerializedData& serialized_descriptors,
|
||||||
::profiler::descriptors_list_t& descriptors,
|
::profiler::descriptors_list_t& descriptors,
|
||||||
::profiler::blocks_t& _blocks,
|
::profiler::blocks_t& _blocks,
|
||||||
::profiler::thread_blocks_tree_t& threaded_trees,
|
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||||
|
uint32_t& total_descriptors_number,
|
||||||
bool gather_statistics,
|
bool gather_statistics,
|
||||||
::std::stringstream& _log);
|
::std::stringstream& _log);
|
||||||
|
|
||||||
PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic<int>& progress, ::std::stringstream& str,
|
PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic<int>& progress, ::std::stringstream& str,
|
||||||
::profiler::FileData& filedata,
|
::profiler::SerializedData& serialized_blocks,
|
||||||
|
::profiler::SerializedData& serialized_descriptors,
|
||||||
::profiler::descriptors_list_t& descriptors,
|
::profiler::descriptors_list_t& descriptors,
|
||||||
::profiler::blocks_t& _blocks,
|
::profiler::blocks_t& _blocks,
|
||||||
::profiler::thread_blocks_tree_t& threaded_trees,
|
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||||
|
uint32_t& total_descriptors_number,
|
||||||
bool gather_statistics,
|
bool gather_statistics,
|
||||||
::std::stringstream& _log);
|
::std::stringstream& _log);
|
||||||
|
|
||||||
@ -402,31 +404,18 @@ extern "C" {
|
|||||||
::profiler::SerializedData& serialized_descriptors,
|
::profiler::SerializedData& serialized_descriptors,
|
||||||
::profiler::descriptors_list_t& descriptors,
|
::profiler::descriptors_list_t& descriptors,
|
||||||
::std::stringstream& _log);
|
::std::stringstream& _log);
|
||||||
|
|
||||||
PROFILER_API bool writeTreesToStream(::std::atomic<int>& progress,
|
|
||||||
::std::stringstream& str,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log);
|
|
||||||
|
|
||||||
PROFILER_API bool writeTreesToFile(::std::atomic<int>& progress,
|
|
||||||
const char* filename,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ::profiler::block_index_t fillTreesFromFile(const char* filename, ::profiler::FileData& filedata,
|
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::descriptors_list_t& descriptors, ::profiler::blocks_t& _blocks,
|
||||||
::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics,
|
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||||
|
uint32_t& total_descriptors_number,
|
||||||
|
bool gather_statistics,
|
||||||
::std::stringstream& _log)
|
::std::stringstream& _log)
|
||||||
{
|
{
|
||||||
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
||||||
return fillTreesFromFile(progress, filename, filedata, descriptors, _blocks, threaded_trees, gather_statistics, _log);
|
return fillTreesFromFile(progress, filename, serialized_blocks, serialized_descriptors, descriptors, _blocks, threaded_trees, total_descriptors_number, gather_statistics, _log);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool readDescriptionsFromStream(::std::stringstream& str,
|
inline bool readDescriptionsFromStream(::std::stringstream& str,
|
||||||
@ -438,28 +427,6 @@ inline bool readDescriptionsFromStream(::std::stringstream& str,
|
|||||||
return readDescriptionsFromStream(progress, str, serialized_descriptors, descriptors, _log);
|
return readDescriptionsFromStream(progress, str, serialized_descriptors, descriptors, _log);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool writeTreesToStream(::std::stringstream& str,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log)
|
|
||||||
{
|
|
||||||
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
|
||||||
return writeTreesToStream(progress, str, filedata, threaded_trees, _descriptors, _blocks, _log);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool writeTreesToFile(const char* filename,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log)
|
|
||||||
{
|
|
||||||
::std::atomic<int> progress = ATOMIC_VAR_INIT(0);
|
|
||||||
return writeTreesToFile(progress, filename, filedata, threaded_trees, _descriptors, _blocks, _log);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#endif // PROFILER_READER____H
|
#endif // PROFILER_READER____H
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
#include "blocks_tree_widget.h"
|
#include "blocks_tree_widget.h"
|
||||||
@ -79,6 +80,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const int LOADER_TIMER_INTERVAL = 40;
|
const int LOADER_TIMER_INTERVAL = 40;
|
||||||
|
const auto NETWORK_CACHE_FILE = "easy_profiler_stream.cache";
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -376,7 +378,7 @@ void EasyMainWindow::onReloadFileClicked(bool)
|
|||||||
|
|
||||||
void EasyMainWindow::onSaveFileClicked(bool)
|
void EasyMainWindow::onSaveFileClicked(bool)
|
||||||
{
|
{
|
||||||
if (m_filedata.serialized_blocks.empty())
|
if (m_serializedBlocks.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto i = m_lastFile.lastIndexOf(QChar('/'));
|
const auto i = m_lastFile.lastIndexOf(QChar('/'));
|
||||||
@ -390,26 +392,30 @@ void EasyMainWindow::onSaveFileClicked(bool)
|
|||||||
auto filename = QFileDialog::getSaveFileName(this, "Save profiler log", dir, "Profiler Log File (*.prof);;All Files (*.*)");
|
auto filename = QFileDialog::getSaveFileName(this, "Save profiler log", dir, "Profiler Log File (*.prof);;All Files (*.*)");
|
||||||
if (!filename.isEmpty())
|
if (!filename.isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, "Warning", "Saving is not working yet :)", QMessageBox::Close);
|
auto result = QFile::copy(m_bNetworkFileRegime ? QString(NETWORK_CACHE_FILE) : m_lastFile, filename);
|
||||||
|
if (result)
|
||||||
/*
|
{
|
||||||
::std::stringstream errorMessage;
|
|
||||||
|
|
||||||
::profiler::pblocks_t blocks(EASY_GLOBALS.gui_blocks.size());
|
|
||||||
for (size_t i = 0, size = EASY_GLOBALS.gui_blocks.size(); i < size; ++i)
|
|
||||||
blocks[i] = &EASY_GLOBALS.gui_blocks[i].tree;
|
|
||||||
|
|
||||||
if (writeTreesToFile(filename.toStdString().c_str(), m_filedata, EASY_GLOBALS.profiler_blocks, EASY_GLOBALS.descriptors, blocks, errorMessage))
|
|
||||||
m_lastFile = filename;
|
m_lastFile = filename;
|
||||||
|
if (m_bNetworkFileRegime)
|
||||||
|
{
|
||||||
|
m_bNetworkFileRegime = false;
|
||||||
|
QFile::remove(NETWORK_CACHE_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_bNetworkFileRegime)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "Warning", "Can not save network cahce to file.\nSaving incomplete.", QMessageBox::Close);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
QMessageBox::warning(this, "Warning", QString("Can not save blocks to file.\n\nReason:\n%1").arg(errorMessage.str().c_str()), QMessageBox::Close);
|
{
|
||||||
*/
|
QMessageBox::warning(this, "Warning", "Can not copy last file.\nSaving incomplete.", QMessageBox::Close);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void EasyMainWindow::onDeleteClicked(bool)
|
void EasyMainWindow::clear()
|
||||||
{
|
{
|
||||||
static_cast<EasyTreeWidget*>(m_treeWidget->widget())->clearSilent(true);
|
static_cast<EasyTreeWidget*>(m_treeWidget->widget())->clearSilent(true);
|
||||||
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->clear();
|
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->clear();
|
||||||
@ -426,11 +432,20 @@ void EasyMainWindow::onDeleteClicked(bool)
|
|||||||
EASY_GLOBALS.descriptors.clear();
|
EASY_GLOBALS.descriptors.clear();
|
||||||
EASY_GLOBALS.gui_blocks.clear();
|
EASY_GLOBALS.gui_blocks.clear();
|
||||||
|
|
||||||
m_filedata.serialized_blocks.clear();
|
m_serializedBlocks.clear();
|
||||||
m_filedata.serialized_descriptors.clear();
|
m_serializedDescriptors.clear();
|
||||||
|
|
||||||
m_saveAction->setEnabled(false);
|
m_saveAction->setEnabled(false);
|
||||||
m_deleteAction->setEnabled(false);
|
m_deleteAction->setEnabled(false);
|
||||||
|
|
||||||
|
m_bNetworkFileRegime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EasyMainWindow::onDeleteClicked(bool)
|
||||||
|
{
|
||||||
|
auto button = QMessageBox::question(this, "Clear all profiled data", "All profiled data is going to be deleted!\nContinue?", QMessageBox::Yes, QMessageBox::No);
|
||||||
|
if (button == QMessageBox::Yes)
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -758,12 +773,14 @@ void EasyMainWindow::onFileReaderTimeout()
|
|||||||
{
|
{
|
||||||
static_cast<EasyTreeWidget*>(m_treeWidget->widget())->clearSilent(true);
|
static_cast<EasyTreeWidget*>(m_treeWidget->widget())->clearSilent(true);
|
||||||
|
|
||||||
::profiler::FileData fd;
|
::profiler::SerializedData serialized_blocks;
|
||||||
|
::profiler::SerializedData serialized_descriptors;
|
||||||
::profiler::descriptors_list_t descriptors;
|
::profiler::descriptors_list_t descriptors;
|
||||||
::profiler::blocks_t blocks;
|
::profiler::blocks_t blocks;
|
||||||
::profiler::thread_blocks_tree_t threads_map;
|
::profiler::thread_blocks_tree_t threads_map;
|
||||||
QString filename;
|
QString filename;
|
||||||
m_reader.get(fd, descriptors, blocks, threads_map, filename);
|
uint32_t descriptorsNumberInFile = 0;
|
||||||
|
m_reader.get(serialized_blocks, serialized_descriptors, descriptors, blocks, threads_map, descriptorsNumberInFile, filename);
|
||||||
|
|
||||||
if (threads_map.size() > 0xff)
|
if (threads_map.size() > 0xff)
|
||||||
{
|
{
|
||||||
@ -774,9 +791,12 @@ void EasyMainWindow::onFileReaderTimeout()
|
|||||||
qWarning() << "Warning: Currently, maximum number of displayed threads is 255! Some threads will not be displayed.";
|
qWarning() << "Warning: Currently, maximum number of displayed threads is 255! Some threads will not be displayed.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_reader.isFile())
|
m_bNetworkFileRegime = !m_reader.isFile();
|
||||||
|
if (!m_bNetworkFileRegime)
|
||||||
m_lastFile = ::std::move(filename);
|
m_lastFile = ::std::move(filename);
|
||||||
m_filedata = ::std::move(fd);
|
m_serializedBlocks = ::std::move(serialized_blocks);
|
||||||
|
m_serializedDescriptors = ::std::move(serialized_descriptors);
|
||||||
|
m_descriptorsNumberInFile = descriptorsNumberInFile;
|
||||||
EASY_GLOBALS.selected_thread = 0;
|
EASY_GLOBALS.selected_thread = 0;
|
||||||
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||||
EASY_GLOBALS.profiler_blocks.swap(threads_map);
|
EASY_GLOBALS.profiler_blocks.swap(threads_map);
|
||||||
@ -876,7 +896,8 @@ void EasyFileReader::load(const QString& _filename)
|
|||||||
m_isFile = true;
|
m_isFile = true;
|
||||||
m_filename = _filename;
|
m_filename = _filename;
|
||||||
m_thread = ::std::move(::std::thread([this](bool _enableStatistics) {
|
m_thread = ::std::move(::std::thread([this](bool _enableStatistics) {
|
||||||
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_filedata, m_descriptors, m_blocks, m_blocksTree, _enableStatistics, m_errorMessage), ::std::memory_order_release);
|
m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors,
|
||||||
|
m_descriptors, m_blocks, m_blocksTree, m_descriptorsNumberInFile, _enableStatistics, m_errorMessage), ::std::memory_order_release);
|
||||||
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);
|
||||||
}, EASY_GLOBALS.enable_statistics));
|
}, EASY_GLOBALS.enable_statistics));
|
||||||
@ -890,7 +911,13 @@ void EasyFileReader::load(::std::stringstream& _stream)
|
|||||||
m_filename.clear();
|
m_filename.clear();
|
||||||
m_stream.swap(_stream);
|
m_stream.swap(_stream);
|
||||||
m_thread = ::std::move(::std::thread([this](bool _enableStatistics) {
|
m_thread = ::std::move(::std::thread([this](bool _enableStatistics) {
|
||||||
m_size.store(fillTreesFromStream(m_progress, m_stream, m_filedata, m_descriptors, m_blocks, m_blocksTree, _enableStatistics, m_errorMessage), ::std::memory_order_release);
|
::std::ofstream cache_file(NETWORK_CACHE_FILE, ::std::fstream::binary);
|
||||||
|
if (cache_file.is_open()) {
|
||||||
|
cache_file << m_stream.str();
|
||||||
|
cache_file.close();
|
||||||
|
}
|
||||||
|
m_size.store(fillTreesFromStream(m_progress, m_stream, m_serializedBlocks, m_serializedDescriptors, m_descriptors,
|
||||||
|
m_blocks, m_blocksTree, m_descriptorsNumberInFile, _enableStatistics, m_errorMessage), ::std::memory_order_release);
|
||||||
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);
|
||||||
}, EASY_GLOBALS.enable_statistics));
|
}, EASY_GLOBALS.enable_statistics));
|
||||||
@ -905,33 +932,30 @@ void EasyFileReader::interrupt()
|
|||||||
m_bDone.store(false, ::std::memory_order_release);
|
m_bDone.store(false, ::std::memory_order_release);
|
||||||
m_progress.store(0, ::std::memory_order_release);
|
m_progress.store(0, ::std::memory_order_release);
|
||||||
m_size.store(0, ::std::memory_order_release);
|
m_size.store(0, ::std::memory_order_release);
|
||||||
m_filedata.serialized_blocks.clear();
|
m_serializedBlocks.clear();
|
||||||
m_filedata.serialized_descriptors.clear();
|
m_serializedDescriptors.clear();
|
||||||
m_descriptors.clear();
|
m_descriptors.clear();
|
||||||
m_blocks.clear();
|
m_blocks.clear();
|
||||||
m_blocksTree.clear();
|
m_blocksTree.clear();
|
||||||
|
m_descriptorsNumberInFile = 0;
|
||||||
|
|
||||||
{ decltype(m_stream) dummy; dummy.swap(m_stream); }
|
{ decltype(m_stream) dummy; dummy.swap(m_stream); }
|
||||||
{ decltype(m_errorMessage) dummy; dummy.swap(m_errorMessage); }
|
{ decltype(m_errorMessage) dummy; dummy.swap(m_errorMessage); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void EasyFileReader::get(::profiler::FileData& _filedata, ::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks,
|
void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors,
|
||||||
::profiler::thread_blocks_tree_t& _tree, QString& _filename)
|
::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks,
|
||||||
|
::profiler::thread_blocks_tree_t& _tree, uint32_t& _descriptorsNumberInFile, QString& _filename)
|
||||||
{
|
{
|
||||||
if (done())
|
if (done())
|
||||||
{
|
{
|
||||||
m_filedata.serialized_blocks.swap(_filedata.serialized_blocks);
|
m_serializedBlocks.swap(_serializedBlocks);
|
||||||
m_filedata.serialized_descriptors.swap(_filedata.serialized_descriptors);
|
m_serializedDescriptors.swap(_serializedDescriptors);
|
||||||
m_filedata.threads_order.swap(_filedata.threads_order);
|
|
||||||
::profiler::descriptors_list_t(::std::move(m_descriptors)).swap(_descriptors);
|
::profiler::descriptors_list_t(::std::move(m_descriptors)).swap(_descriptors);
|
||||||
m_blocks.swap(_blocks);
|
m_blocks.swap(_blocks);
|
||||||
m_blocksTree.swap(_tree);
|
m_blocksTree.swap(_tree);
|
||||||
m_filename.swap(_filename);
|
m_filename.swap(_filename);
|
||||||
_filedata.cpu_frequency = m_filedata.cpu_frequency;
|
_descriptorsNumberInFile = m_descriptorsNumberInFile;
|
||||||
_filedata.begin_time = m_filedata.begin_time;
|
|
||||||
_filedata.end_time = m_filedata.end_time;
|
|
||||||
_filedata.total_blocks_number = m_filedata.total_blocks_number;
|
|
||||||
_filedata.total_descriptors_number = m_filedata.total_descriptors_number;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,34 +1095,34 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
|
|||||||
{
|
{
|
||||||
// Read descriptions from stream
|
// Read descriptions from stream
|
||||||
decltype(EASY_GLOBALS.descriptors) descriptors;
|
decltype(EASY_GLOBALS.descriptors) descriptors;
|
||||||
decltype(m_filedata.serialized_descriptors) serializedDescriptors;
|
decltype(m_serializedDescriptors) serializedDescriptors;
|
||||||
::std::stringstream errorMessage;
|
::std::stringstream errorMessage;
|
||||||
if (readDescriptionsFromStream(m_listener.data(), serializedDescriptors, descriptors, errorMessage))
|
if (readDescriptionsFromStream(m_listener.data(), serializedDescriptors, descriptors, errorMessage))
|
||||||
{
|
{
|
||||||
bool cancel = false;
|
bool cancel = false;
|
||||||
const bool doFlush = m_filedata.total_descriptors_number != descriptors.size();
|
const bool doFlush = m_descriptorsNumberInFile != descriptors.size();
|
||||||
if (doFlush && !m_filedata.serialized_blocks.empty())
|
if (doFlush && !m_serializedBlocks.empty())
|
||||||
{
|
{
|
||||||
auto button = QMessageBox::question(this, "Information",
|
auto button = QMessageBox::question(this, "Information",
|
||||||
QString("New blocks description number = %1\ndiffers from the old one = %2.\nTo avoid possible conflicts\nall profiled data will be deleted.\nPress \"Yes\" to continue or \"No\" to cancel.")
|
QString("New blocks description number = %1\ndiffers from the old one = %2.\nTo avoid possible conflicts\nall profiled data will be deleted.\nPress \"Yes\" to continue or \"No\" to cancel.")
|
||||||
.arg(descriptors.size())
|
.arg(descriptors.size())
|
||||||
.arg(m_filedata.total_descriptors_number),
|
.arg(m_descriptorsNumberInFile),
|
||||||
QMessageBox::Yes, QMessageBox::No);
|
QMessageBox::Yes, QMessageBox::No);
|
||||||
|
|
||||||
if (button == QMessageBox::Yes)
|
if (button == QMessageBox::Yes)
|
||||||
onDeleteClicked(true); // Clear all contents because new descriptors list conflicts with old one
|
clear(); // Clear all contents because new descriptors list conflicts with old one
|
||||||
else
|
else
|
||||||
cancel = true;
|
cancel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cancel)
|
if (!cancel)
|
||||||
{
|
{
|
||||||
auto oldnumber = m_filedata.total_descriptors_number;
|
auto oldnumber = m_descriptorsNumberInFile;
|
||||||
m_filedata.total_descriptors_number = static_cast<uint32_t>(descriptors.size());
|
m_descriptorsNumberInFile = static_cast<uint32_t>(descriptors.size());
|
||||||
EASY_GLOBALS.descriptors.swap(descriptors);
|
EASY_GLOBALS.descriptors.swap(descriptors);
|
||||||
m_filedata.serialized_descriptors.swap(serializedDescriptors);
|
m_serializedDescriptors.swap(serializedDescriptors);
|
||||||
|
|
||||||
if (!doFlush && !m_filedata.serialized_blocks.empty() && descriptors.size() > oldnumber)
|
if (!doFlush && !m_serializedBlocks.empty() && descriptors.size() > oldnumber)
|
||||||
{
|
{
|
||||||
// There are dynamically added descriptors, add them to the new list too
|
// There are dynamically added descriptors, add them to the new list too
|
||||||
|
|
||||||
@ -1120,7 +1144,7 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
|
|||||||
if (desc != nullptr)
|
if (desc != nullptr)
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, "Warning", "Conflict with dynamically added block descriptions.\nAll profiled data will be cleared.", QMessageBox::Close);
|
QMessageBox::warning(this, "Warning", "Conflict with dynamically added block descriptions.\nAll profiled data will be cleared.", QMessageBox::Close);
|
||||||
onDeleteClicked(true);
|
clear();
|
||||||
cancel = true;
|
cancel = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -61,13 +61,15 @@ namespace profiler { namespace net { struct EasyProfilerStatus; } }
|
|||||||
|
|
||||||
class EasyFileReader Q_DECL_FINAL
|
class EasyFileReader Q_DECL_FINAL
|
||||||
{
|
{
|
||||||
::profiler::FileData m_filedata; ///<
|
::profiler::SerializedData m_serializedBlocks; ///<
|
||||||
|
::profiler::SerializedData m_serializedDescriptors; ///<
|
||||||
::profiler::descriptors_list_t m_descriptors; ///<
|
::profiler::descriptors_list_t m_descriptors; ///<
|
||||||
::profiler::blocks_t m_blocks; ///<
|
::profiler::blocks_t m_blocks; ///<
|
||||||
::profiler::thread_blocks_tree_t m_blocksTree; ///<
|
::profiler::thread_blocks_tree_t m_blocksTree; ///<
|
||||||
::std::stringstream m_stream; ///<
|
::std::stringstream m_stream; ///<
|
||||||
::std::stringstream m_errorMessage; ///<
|
::std::stringstream m_errorMessage; ///<
|
||||||
QString m_filename; ///<
|
QString m_filename; ///<
|
||||||
|
uint32_t m_descriptorsNumberInFile = 0; ///<
|
||||||
::std::thread m_thread; ///<
|
::std::thread m_thread; ///<
|
||||||
::std::atomic_bool m_bDone; ///<
|
::std::atomic_bool m_bDone; ///<
|
||||||
::std::atomic<int> m_progress; ///<
|
::std::atomic<int> m_progress; ///<
|
||||||
@ -88,9 +90,9 @@ public:
|
|||||||
void load(const QString& _filename);
|
void load(const QString& _filename);
|
||||||
void load(::std::stringstream& _stream);
|
void load(::std::stringstream& _stream);
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void get(::profiler::FileData& _filedata, ::profiler::descriptors_list_t& _descriptors,
|
void get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors,
|
||||||
::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree,
|
::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree,
|
||||||
QString& _filename);
|
uint32_t& _descriptorsNumberInFile, QString& _filename);
|
||||||
|
|
||||||
QString getError();
|
QString getError();
|
||||||
|
|
||||||
@ -171,7 +173,8 @@ protected:
|
|||||||
class QMessageBox* m_listenerDialog = nullptr;
|
class QMessageBox* m_listenerDialog = nullptr;
|
||||||
QTimer m_readerTimer;
|
QTimer m_readerTimer;
|
||||||
QTimer m_listenerTimer;
|
QTimer m_listenerTimer;
|
||||||
::profiler::FileData m_filedata;
|
::profiler::SerializedData m_serializedBlocks;
|
||||||
|
::profiler::SerializedData m_serializedDescriptors;
|
||||||
EasyFileReader m_reader;
|
EasyFileReader m_reader;
|
||||||
EasySocketListener m_listener;
|
EasySocketListener m_listener;
|
||||||
|
|
||||||
@ -186,7 +189,9 @@ protected:
|
|||||||
class QAction* m_eventTracingEnableAction = nullptr;
|
class QAction* m_eventTracingEnableAction = nullptr;
|
||||||
class QAction* m_eventTracingPriorityAction = nullptr;
|
class QAction* m_eventTracingPriorityAction = nullptr;
|
||||||
|
|
||||||
|
uint32_t m_descriptorsNumberInFile = 0;
|
||||||
uint16_t m_lastPort = 0;
|
uint16_t m_lastPort = 0;
|
||||||
|
bool m_bNetworkFileRegime = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -233,6 +238,8 @@ private:
|
|||||||
|
|
||||||
// Private non-virtual methods
|
// Private non-virtual methods
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
void loadFile(const QString& filename);
|
void loadFile(const QString& filename);
|
||||||
void readStream(::std::stringstream& data);
|
void readStream(::std::stringstream& data);
|
||||||
|
|
||||||
|
@ -110,11 +110,13 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
auto start = std::chrono::system_clock::now();
|
auto start = std::chrono::system_clock::now();
|
||||||
|
|
||||||
::profiler::FileData fd;
|
::profiler::SerializedData serialized_blocks, serialized_descriptors;
|
||||||
::profiler::descriptors_list_t descriptors;
|
::profiler::descriptors_list_t descriptors;
|
||||||
::profiler::blocks_t blocks;
|
::profiler::blocks_t blocks;
|
||||||
::std::stringstream errorMessage;
|
::std::stringstream errorMessage;
|
||||||
auto blocks_counter = fillTreesFromFile(filename.c_str(), fd, descriptors, blocks, threaded_trees, true, errorMessage);
|
uint32_t descriptorsNumberInFile = 0;
|
||||||
|
auto blocks_counter = fillTreesFromFile(filename.c_str(), serialized_blocks, serialized_descriptors, descriptors, blocks,
|
||||||
|
threaded_trees, descriptorsNumberInFile, true, errorMessage);
|
||||||
if (blocks_counter == 0)
|
if (blocks_counter == 0)
|
||||||
std::cout << "Can not read blocks from file " << filename.c_str() << "\nReason: " << errorMessage.str();
|
std::cout << "Can not read blocks from file " << filename.c_str() << "\nReason: " << errorMessage.str();
|
||||||
|
|
||||||
|
331
src/reader.cpp
331
src/reader.cpp
@ -252,84 +252,15 @@ void validate_pointers(::std::atomic<int>& _progress, const char* _oldbase, ::pr
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint64_t write_block_recursive(float& _progress, float _prog_per_block, ::std::vector<char>& _buf, ::std::stringstream& _stream, const ::profiler::FileData& _filedata, const ::profiler::BlocksTree& _tree, const ::profiler::pblocks_t& _blocks, const ::profiler::descriptors_list_t& _descriptors)
|
|
||||||
{
|
|
||||||
uint64_t total_size = 0;
|
|
||||||
for (const auto chld : _tree.children)
|
|
||||||
total_size += write_block_recursive(_progress, _prog_per_block, _buf, _stream, _filedata, *_blocks[chld], _blocks, _descriptors);
|
|
||||||
|
|
||||||
auto sz = static_cast<uint16_t>(sizeof(::profiler::SerializedBlock) + strlen(_tree.node->name()) + 1);
|
|
||||||
|
|
||||||
_buf.resize(sz);
|
|
||||||
memcpy(_buf.data(), _tree.node->data(), sz);
|
|
||||||
|
|
||||||
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(_buf.data());
|
|
||||||
auto t_end = t_begin + 1;
|
|
||||||
|
|
||||||
*t_begin *= _filedata.cpu_frequency;
|
|
||||||
*t_begin /= TIME_FACTOR;
|
|
||||||
*t_end *= _filedata.cpu_frequency;
|
|
||||||
*t_end /= TIME_FACTOR;
|
|
||||||
|
|
||||||
if (_tree.node->id() >= _filedata.total_descriptors_number)
|
|
||||||
{
|
|
||||||
auto desc = _descriptors[_tree.node->id()];
|
|
||||||
for (uint32_t i = 0; i < _filedata.total_descriptors_number; ++i)
|
|
||||||
{
|
|
||||||
if (_descriptors[i] == desc)
|
|
||||||
{
|
|
||||||
reinterpret_cast<::profiler::SerializedBlock*>(_buf.data())->setId(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
write(_stream, sz);
|
|
||||||
write(_stream, _buf.data(), sz);
|
|
||||||
total_size += sz;
|
|
||||||
|
|
||||||
_progress += _prog_per_block;
|
|
||||||
|
|
||||||
return total_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t write_block_recursive(float& _progress, float _prog_per_block, ::std::vector<char>& _buf, ::std::stringstream& _stream, const ::profiler::FileData& _filedata, const ::profiler::BlocksTree& _tree, const ::profiler::pblocks_t& _blocks)
|
|
||||||
{
|
|
||||||
uint64_t total_size = 0;
|
|
||||||
for (const auto chld : _tree.children)
|
|
||||||
total_size += write_block_recursive(_progress, _prog_per_block, _buf, _stream, _filedata, *_blocks[chld], _blocks);
|
|
||||||
|
|
||||||
auto sz = static_cast<uint16_t>(sizeof(::profiler::SerializedBlock) + strlen(_tree.node->name()) + 1);
|
|
||||||
|
|
||||||
_buf.resize(sz);
|
|
||||||
memcpy(_buf.data(), _tree.node->data(), sz);
|
|
||||||
|
|
||||||
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(_buf.data());
|
|
||||||
auto t_end = t_begin + 1;
|
|
||||||
|
|
||||||
*t_begin *= _filedata.cpu_frequency;
|
|
||||||
*t_begin /= TIME_FACTOR;
|
|
||||||
*t_end *= _filedata.cpu_frequency;
|
|
||||||
*t_end /= TIME_FACTOR;
|
|
||||||
|
|
||||||
write(_stream, sz);
|
|
||||||
write(_stream, _buf.data(), sz);
|
|
||||||
total_size += sz;
|
|
||||||
|
|
||||||
_progress += _prog_per_block;
|
|
||||||
|
|
||||||
return total_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progress, const char* filename,
|
PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic<int>& progress, const char* filename,
|
||||||
::profiler::FileData& filedata,
|
::profiler::SerializedData& serialized_blocks,
|
||||||
|
::profiler::SerializedData& serialized_descriptors,
|
||||||
::profiler::descriptors_list_t& descriptors,
|
::profiler::descriptors_list_t& descriptors,
|
||||||
::profiler::blocks_t& blocks,
|
::profiler::blocks_t& blocks,
|
||||||
::profiler::thread_blocks_tree_t& threaded_trees,
|
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||||
|
uint32_t& total_descriptors_number,
|
||||||
bool gather_statistics,
|
bool gather_statistics,
|
||||||
::std::stringstream& _log)
|
::std::stringstream& _log)
|
||||||
{
|
{
|
||||||
@ -353,7 +284,8 @@ extern "C" {
|
|||||||
stringstream_parent& s = str;
|
stringstream_parent& s = str;
|
||||||
auto oldbuf = s.rdbuf(inFile.rdbuf());
|
auto oldbuf = s.rdbuf(inFile.rdbuf());
|
||||||
|
|
||||||
auto result = fillTreesFromStream(progress, str, filedata, descriptors, blocks, threaded_trees, gather_statistics, _log);
|
auto result = fillTreesFromStream(progress, str, serialized_blocks, serialized_descriptors, descriptors, blocks,
|
||||||
|
threaded_trees, total_descriptors_number, gather_statistics, _log);
|
||||||
s.rdbuf(oldbuf);
|
s.rdbuf(oldbuf);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -362,10 +294,12 @@ extern "C" {
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic<int>& progress, ::std::stringstream& inFile,
|
PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic<int>& progress, ::std::stringstream& inFile,
|
||||||
::profiler::FileData& filedata,
|
::profiler::SerializedData& serialized_blocks,
|
||||||
|
::profiler::SerializedData& serialized_descriptors,
|
||||||
::profiler::descriptors_list_t& descriptors,
|
::profiler::descriptors_list_t& descriptors,
|
||||||
::profiler::blocks_t& blocks,
|
::profiler::blocks_t& blocks,
|
||||||
::profiler::thread_blocks_tree_t& threaded_trees,
|
::profiler::thread_blocks_tree_t& threaded_trees,
|
||||||
|
uint32_t& total_descriptors_number,
|
||||||
bool gather_statistics,
|
bool gather_statistics,
|
||||||
::std::stringstream& _log)
|
::std::stringstream& _log)
|
||||||
{
|
{
|
||||||
@ -394,24 +328,24 @@ extern "C" {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
filedata.cpu_frequency = 0LL;
|
int64_t cpu_frequency = 0LL;
|
||||||
inFile.read((char*)&filedata.cpu_frequency, sizeof(int64_t));
|
inFile.read((char*)&cpu_frequency, sizeof(int64_t));
|
||||||
|
|
||||||
filedata.begin_time = 0;
|
::profiler::timestamp_t begin_time = 0ULL;
|
||||||
filedata.end_time = 0;
|
::profiler::timestamp_t end_time = 0ULL;
|
||||||
inFile.read((char*)&filedata.begin_time, sizeof(::profiler::timestamp_t));
|
inFile.read((char*)&begin_time, sizeof(::profiler::timestamp_t));
|
||||||
inFile.read((char*)&filedata.end_time, sizeof(::profiler::timestamp_t));
|
inFile.read((char*)&end_time, sizeof(::profiler::timestamp_t));
|
||||||
if (filedata.cpu_frequency != 0)
|
if (cpu_frequency != 0)
|
||||||
{
|
{
|
||||||
filedata.begin_time *= TIME_FACTOR;
|
begin_time *= TIME_FACTOR;
|
||||||
filedata.begin_time /= filedata.cpu_frequency;
|
begin_time /= cpu_frequency;
|
||||||
filedata.end_time *= TIME_FACTOR;
|
end_time *= TIME_FACTOR;
|
||||||
filedata.end_time /= filedata.cpu_frequency;
|
end_time /= cpu_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
filedata.total_blocks_number = 0;
|
uint32_t total_blocks_number = 0;
|
||||||
inFile.read((char*)&filedata.total_blocks_number, sizeof(decltype(filedata.total_blocks_number)));
|
inFile.read((char*)&total_blocks_number, sizeof(uint32_t));
|
||||||
if (filedata.total_blocks_number == 0)
|
if (total_blocks_number == 0)
|
||||||
{
|
{
|
||||||
_log << "Profiled blocks number == 0";
|
_log << "Profiled blocks number == 0";
|
||||||
return 0;
|
return 0;
|
||||||
@ -421,13 +355,13 @@ extern "C" {
|
|||||||
inFile.read((char*)&memory_size, sizeof(decltype(memory_size)));
|
inFile.read((char*)&memory_size, sizeof(decltype(memory_size)));
|
||||||
if (memory_size == 0)
|
if (memory_size == 0)
|
||||||
{
|
{
|
||||||
_log << "Wrong memory size == 0 for " << filedata.total_blocks_number << " blocks";
|
_log << "Wrong memory size == 0 for " << total_blocks_number << " blocks";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
filedata.total_descriptors_number = 0;
|
total_descriptors_number = 0;
|
||||||
inFile.read((char*)&filedata.total_descriptors_number, sizeof(decltype(filedata.total_descriptors_number)));
|
inFile.read((char*)&total_descriptors_number, sizeof(uint32_t));
|
||||||
if (filedata.total_descriptors_number == 0)
|
if (total_descriptors_number == 0)
|
||||||
{
|
{
|
||||||
_log << "Blocks description number == 0";
|
_log << "Blocks description number == 0";
|
||||||
return 0;
|
return 0;
|
||||||
@ -437,17 +371,17 @@ extern "C" {
|
|||||||
inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size)));
|
inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size)));
|
||||||
if (descriptors_memory_size == 0)
|
if (descriptors_memory_size == 0)
|
||||||
{
|
{
|
||||||
_log << "Wrong memory size == 0 for " << filedata.total_descriptors_number << " blocks descriptions";
|
_log << "Wrong memory size == 0 for " << total_descriptors_number << " blocks descriptions";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptors.reserve(filedata.total_descriptors_number);
|
descriptors.reserve(total_descriptors_number);
|
||||||
//const char* olddata = append_regime ? filedata.serialized_descriptors.data() : nullptr;
|
//const char* olddata = append_regime ? serialized_descriptors.data() : nullptr;
|
||||||
filedata.serialized_descriptors.set(descriptors_memory_size);
|
serialized_descriptors.set(descriptors_memory_size);
|
||||||
//validate_pointers(progress, olddata, filedata.serialized_descriptors, descriptors, descriptors.size());
|
//validate_pointers(progress, olddata, serialized_descriptors, descriptors, descriptors.size());
|
||||||
|
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
while (!inFile.eof() && descriptors.size() < filedata.total_descriptors_number)
|
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
|
||||||
{
|
{
|
||||||
uint16_t sz = 0;
|
uint16_t sz = 0;
|
||||||
inFile.read((char*)&sz, sizeof(sz));
|
inFile.read((char*)&sz, sizeof(sz));
|
||||||
@ -462,7 +396,7 @@ extern "C" {
|
|||||||
// return 0;
|
// return 0;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
char* data = filedata.serialized_descriptors[i];
|
char* data = serialized_descriptors[i];
|
||||||
inFile.read(data, sz);
|
inFile.read(data, sz);
|
||||||
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
|
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
|
||||||
descriptors.push_back(descriptor);
|
descriptors.push_back(descriptor);
|
||||||
@ -480,16 +414,16 @@ extern "C" {
|
|||||||
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
|
PerThreadStats thread_statistics, parent_statistics, frame_statistics;
|
||||||
IdMap identification_table;
|
IdMap identification_table;
|
||||||
|
|
||||||
blocks.reserve(filedata.total_blocks_number);
|
blocks.reserve(total_blocks_number);
|
||||||
//olddata = append_regime ? filedata.serialized_blocks.data() : nullptr;
|
//olddata = append_regime ? serialized_blocks.data() : nullptr;
|
||||||
filedata.serialized_blocks.set(memory_size);
|
serialized_blocks.set(memory_size);
|
||||||
//validate_pointers(progress, olddata, filedata.serialized_blocks, blocks, blocks.size());
|
//validate_pointers(progress, olddata, serialized_blocks, blocks, blocks.size());
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
uint32_t read_number = 0;
|
uint32_t read_number = 0;
|
||||||
::profiler::block_index_t blocks_counter = 0;
|
::profiler::block_index_t blocks_counter = 0;
|
||||||
::std::vector<char> name;
|
::std::vector<char> name;
|
||||||
while (!inFile.eof() && read_number < filedata.total_blocks_number)
|
while (!inFile.eof() && read_number < total_blocks_number)
|
||||||
{
|
{
|
||||||
EASY_BLOCK("Read thread data", ::profiler::colors::DarkGreen);
|
EASY_BLOCK("Read thread data", ::profiler::colors::DarkGreen);
|
||||||
|
|
||||||
@ -497,7 +431,6 @@ extern "C" {
|
|||||||
inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
|
inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
|
||||||
|
|
||||||
auto& root = threaded_trees[thread_id];
|
auto& root = threaded_trees[thread_id];
|
||||||
filedata.threads_order.push_back(thread_id);
|
|
||||||
|
|
||||||
uint16_t name_size = 0;
|
uint16_t name_size = 0;
|
||||||
inFile.read((char*)&name_size, sizeof(uint16_t));
|
inFile.read((char*)&name_size, sizeof(uint16_t));
|
||||||
@ -525,25 +458,25 @@ extern "C" {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* data = filedata.serialized_blocks[i];
|
char* data = serialized_blocks[i];
|
||||||
inFile.read(data, sz);
|
inFile.read(data, sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
||||||
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data);
|
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data);
|
||||||
auto t_end = t_begin + 1;
|
auto t_end = t_begin + 1;
|
||||||
|
|
||||||
if (filedata.cpu_frequency != 0)
|
if (cpu_frequency != 0)
|
||||||
{
|
{
|
||||||
*t_begin *= TIME_FACTOR;
|
*t_begin *= TIME_FACTOR;
|
||||||
*t_begin /= filedata.cpu_frequency;
|
*t_begin /= cpu_frequency;
|
||||||
*t_end *= TIME_FACTOR;
|
*t_end *= TIME_FACTOR;
|
||||||
*t_end /= filedata.cpu_frequency;
|
*t_end /= cpu_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*t_end > filedata.begin_time)
|
if (*t_end > begin_time)
|
||||||
{
|
{
|
||||||
if (*t_begin < filedata.begin_time)
|
if (*t_begin < begin_time)
|
||||||
*t_begin = filedata.begin_time;
|
*t_begin = begin_time;
|
||||||
|
|
||||||
blocks.emplace_back();
|
blocks.emplace_back();
|
||||||
::profiler::BlocksTree& tree = blocks.back();
|
::profiler::BlocksTree& tree = blocks.back();
|
||||||
@ -581,11 +514,11 @@ extern "C" {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* data = filedata.serialized_blocks[i];
|
char* data = serialized_blocks[i];
|
||||||
inFile.read(data, sz);
|
inFile.read(data, sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data);
|
||||||
if (baseData->id() >= filedata.total_descriptors_number)
|
if (baseData->id() >= total_descriptors_number)
|
||||||
{
|
{
|
||||||
_log << "Bad block id == " << baseData->id();
|
_log << "Bad block id == " << baseData->id();
|
||||||
return 0;
|
return 0;
|
||||||
@ -601,18 +534,18 @@ extern "C" {
|
|||||||
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data);
|
auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data);
|
||||||
auto t_end = t_begin + 1;
|
auto t_end = t_begin + 1;
|
||||||
|
|
||||||
if (filedata.cpu_frequency != 0)
|
if (cpu_frequency != 0)
|
||||||
{
|
{
|
||||||
*t_begin *= TIME_FACTOR;
|
*t_begin *= TIME_FACTOR;
|
||||||
*t_begin /= filedata.cpu_frequency;
|
*t_begin /= cpu_frequency;
|
||||||
*t_end *= TIME_FACTOR;
|
*t_end *= TIME_FACTOR;
|
||||||
*t_end /= filedata.cpu_frequency;
|
*t_end /= cpu_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*t_end >= filedata.begin_time)
|
if (*t_end >= begin_time)
|
||||||
{
|
{
|
||||||
if (*t_begin < filedata.begin_time)
|
if (*t_begin < begin_time)
|
||||||
*t_begin = filedata.begin_time;
|
*t_begin = begin_time;
|
||||||
|
|
||||||
blocks.emplace_back();
|
blocks.emplace_back();
|
||||||
::profiler::BlocksTree& tree = blocks.back();
|
::profiler::BlocksTree& tree = blocks.back();
|
||||||
@ -889,162 +822,4 @@ extern "C" {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PROFILER_API bool writeTreesToFile(::std::atomic<int>& progress,
|
|
||||||
const char* filename,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log)
|
|
||||||
{
|
|
||||||
::std::ofstream of(filename, std::fstream::binary);
|
|
||||||
if (!of.is_open())
|
|
||||||
{
|
|
||||||
_log << "Can not open file " << filename << " for writing";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
::std::stringstream str;
|
|
||||||
//typedef ::std::basic_iostream<::std::stringstream::char_type, ::std::stringstream::traits_type> stringstream_parent;
|
|
||||||
//stringstream_parent& s = str;
|
|
||||||
//auto oldbuf = s.rdbuf(of.rdbuf());
|
|
||||||
|
|
||||||
auto result = writeTreesToStream(progress, str, filedata, threaded_trees, _descriptors, _blocks, _log);
|
|
||||||
|
|
||||||
of << str.str();
|
|
||||||
//of.close();
|
|
||||||
//s.rdbuf(oldbuf);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROFILER_API bool writeTreesToStream(::std::atomic<int>& progress,
|
|
||||||
::std::stringstream& str,
|
|
||||||
const ::profiler::FileData& filedata,
|
|
||||||
const ::profiler::thread_blocks_tree_t& threaded_trees,
|
|
||||||
const ::profiler::descriptors_list_t& _descriptors,
|
|
||||||
const ::profiler::pblocks_t& _blocks,
|
|
||||||
::std::stringstream& _log)
|
|
||||||
{
|
|
||||||
auto oldprogress = progress.exchange(0, ::std::memory_order_release);
|
|
||||||
if (oldprogress < 0)
|
|
||||||
{
|
|
||||||
_log << "Writing was interrupted";
|
|
||||||
return false; // Loading interrupted
|
|
||||||
}
|
|
||||||
|
|
||||||
write(str, PROFILER_SIGNATURE);
|
|
||||||
write(str, ::profiler::EASY_FULL_VERSION);
|
|
||||||
write(str, filedata.cpu_frequency);
|
|
||||||
|
|
||||||
decltype(filedata.begin_time) begin_time = filedata.begin_time;
|
|
||||||
begin_time *= filedata.cpu_frequency;
|
|
||||||
begin_time /= TIME_FACTOR;
|
|
||||||
write(str, begin_time);
|
|
||||||
|
|
||||||
decltype(filedata.end_time) end_time = filedata.end_time;
|
|
||||||
end_time *= filedata.cpu_frequency;
|
|
||||||
end_time /= TIME_FACTOR;
|
|
||||||
write(str, end_time);
|
|
||||||
|
|
||||||
write(str, filedata.total_blocks_number);
|
|
||||||
write(str, filedata.serialized_blocks.size());
|
|
||||||
write(str, filedata.total_descriptors_number);
|
|
||||||
write(str, filedata.serialized_descriptors.size());
|
|
||||||
|
|
||||||
decltype(filedata.total_descriptors_number) n = 0;
|
|
||||||
uint64_t i = 0, size = filedata.serialized_descriptors.size();
|
|
||||||
while (i < size)
|
|
||||||
{
|
|
||||||
const char* data = filedata.serialized_descriptors[i];
|
|
||||||
auto descriptor = reinterpret_cast<const ::profiler::SerializedBlockDescriptor*>(data);
|
|
||||||
auto sz = static_cast<uint16_t>(sizeof(::profiler::SerializedBlockDescriptor) + strlen(descriptor->name()) + strlen(descriptor->file()) + 2);
|
|
||||||
|
|
||||||
write(str, sz);
|
|
||||||
write(str, data, sz);
|
|
||||||
++n;
|
|
||||||
|
|
||||||
i += sz;
|
|
||||||
|
|
||||||
auto oldprogress = progress.exchange(static_cast<int>(20 * i / filedata.serialized_descriptors.size()), ::std::memory_order_release);
|
|
||||||
if (oldprogress < 0)
|
|
||||||
{
|
|
||||||
_log << "Writing was interrupted";
|
|
||||||
return false; // Loading interrupted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n != filedata.total_descriptors_number || i != size)
|
|
||||||
printf("ERROR writing descriptors\n");
|
|
||||||
|
|
||||||
float prog = (float)progress.load(::std::memory_order_acquire);
|
|
||||||
if (prog < 0)
|
|
||||||
{
|
|
||||||
_log << "Writing was interrupted";
|
|
||||||
return false; // Loading interrupted
|
|
||||||
}
|
|
||||||
|
|
||||||
const float prog_per_thread = 80.f / (float)threaded_trees.size();
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
::std::vector<char> buffer;
|
|
||||||
for (auto tid : filedata.threads_order)
|
|
||||||
{
|
|
||||||
auto it = threaded_trees.find(tid);
|
|
||||||
if (it == threaded_trees.end())
|
|
||||||
{
|
|
||||||
printf("Bad thread id = %u\n", tid);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& root = it->second;
|
|
||||||
|
|
||||||
auto total = root.children.size() + root.sync.size();
|
|
||||||
const float prog_per_block = total > 0 ? prog_per_thread / total : 0.f;
|
|
||||||
|
|
||||||
write(str, root.thread_id);
|
|
||||||
|
|
||||||
auto name_size = static_cast<uint16_t>(strlen(root.name()) + 1);
|
|
||||||
const char* name = name_size > 1 ? root.name() : "";
|
|
||||||
write(str, name_size);
|
|
||||||
write(str, name, name_size);
|
|
||||||
|
|
||||||
auto blocks_number_in_thread = static_cast<uint32_t>(root.sync.size());
|
|
||||||
write(str, blocks_number_in_thread);
|
|
||||||
for (auto b : root.sync)
|
|
||||||
{
|
|
||||||
i += write_block_recursive(prog, prog_per_block, buffer, str, filedata, *_blocks[b], _blocks);
|
|
||||||
|
|
||||||
auto oldprogress = progress.exchange(static_cast<int>(prog), ::std::memory_order_release);
|
|
||||||
if (oldprogress < 0)
|
|
||||||
{
|
|
||||||
_log << "Writing was interrupted";
|
|
||||||
return false; // Loading interrupted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blocks_number_in_thread = static_cast<uint32_t>(root.children.size());
|
|
||||||
write(str, blocks_number_in_thread);
|
|
||||||
for (auto b : root.children)
|
|
||||||
{
|
|
||||||
i += write_block_recursive(prog, prog_per_block, buffer, str, filedata, *_blocks[b], _blocks, _descriptors);
|
|
||||||
|
|
||||||
auto oldprogress = progress.exchange(static_cast<int>(prog), ::std::memory_order_release);
|
|
||||||
if (oldprogress < 0)
|
|
||||||
{
|
|
||||||
_log << "Writing was interrupted";
|
|
||||||
return false; // Loading interrupted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i != filedata.serialized_blocks.size())
|
|
||||||
printf("ERROR writing blocks\n");
|
|
||||||
|
|
||||||
printf("Finished writing to file\n");
|
|
||||||
progress.store(100, ::std::memory_order_release);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user