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

#31 [Core] Fixed issue with storing arbitrary value while dumping. // [GUI] Further values viewer progress.

This commit is contained in:
Victor Zarubkin 2017-12-14 23:12:27 +03:00
parent 123358b798
commit b73044fddd
7 changed files with 192 additions and 112 deletions

View File

@ -788,18 +788,11 @@ const BaseBlockDescriptor* ProfileManager::addBlockDescriptor(EasyBlockStatus _d
void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin)
{
const auto state = m_profilerStatus.load(std::memory_order_acquire);
if (state == EASY_PROF_DISABLED || (_desc->m_status & profiler::ON) == 0)
if (state != EASY_PROF_ENABLED || (_desc->m_status & profiler::ON) == 0)
return;
if (state == EASY_PROF_DUMP)
{
if (THIS_THREAD == nullptr || THIS_THREAD->blocks.openedList.empty())
return;
}
else if (THIS_THREAD == nullptr)
{
if (THIS_THREAD == nullptr)
registerThread();
}
#if EASY_ENABLE_BLOCK_STATUS != 0
if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0)
@ -819,7 +812,7 @@ bool ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, cons
if (state == EASY_PROF_DUMP)
{
if (THIS_THREAD == nullptr || THIS_THREAD->blocks.openedList.empty())
if (THIS_THREAD == nullptr || THIS_THREAD->halt)
return false;
}
else if (THIS_THREAD == nullptr)
@ -846,7 +839,7 @@ bool ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, cons
if (state == EASY_PROF_DUMP)
{
if (THIS_THREAD == nullptr || THIS_THREAD->blocks.openedList.empty())
if (THIS_THREAD == nullptr || THIS_THREAD->halt)
return false;
}
else if (THIS_THREAD == nullptr)

View File

@ -546,7 +546,7 @@ extern "C" {
descriptors.push_back(descriptor);
i += sz;
auto oldprogress = progress.exchange(static_cast<int>(15 * i / descriptors_memory_size), ::std::memory_order_release);
oldprogress = progress.exchange(static_cast<int>(15 * i / descriptors_memory_size), ::std::memory_order_release);
if (oldprogress < 0)
{
_log << "Reading was interrupted";
@ -642,7 +642,7 @@ extern "C" {
}
}
auto oldprogress = progress.exchange(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
oldprogress = progress.exchange(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
if (oldprogress < 0)
{
_log << "Reading was interrupted";
@ -808,7 +808,7 @@ extern "C" {
}
}
auto oldprogress = progress.exchange(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
oldprogress = progress.exchange(20 + static_cast<int>(70 * i / memory_size), ::std::memory_order_release);
if (oldprogress < 0)
{
_log << "Reading was interrupted";
@ -817,7 +817,8 @@ extern "C" {
}
}
if (progress.load(::std::memory_order_acquire) < 0)
oldprogress = progress.exchange(90, ::std::memory_order_release);
if (oldprogress < 0)
{
_log << "Reading was interrupted";
return 0; // Loading interrupted
@ -926,6 +927,7 @@ extern "C" {
}
// No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors
progress.store(100, ::std::memory_order_release);
return blocks_counter;
}

View File

@ -58,6 +58,7 @@
#include <QHeaderView>
#include <QVBoxLayout>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include "arbitrary_value_inspector.h"
#include "treeview_first_column_delegate.h"
@ -354,17 +355,18 @@ EasyArbitraryValuesTreeItem::~EasyArbitraryValuesTreeItem()
enum class ArbitraryColumns : uint8_t
{
Name = 0,
Type,
Type = 0,
Name,
Value,
Vin,
Count
};
inline EASY_CONSTEXPR_FCN int int_cast(ArbitraryColumns col) {
return static_cast<int>(col);
}
struct UsedValueTypes {
QTreeWidgetItem* items[int_cast(profiler::DataType::TypesCount)];
UsedValueTypes(int = 0) { memset(items, 0, sizeof(items)); }
};
EasyArbitraryValuesWidget::EasyArbitraryValuesWidget(QWidget* _parent)
: Parent(_parent)
@ -384,8 +386,8 @@ EasyArbitraryValuesWidget::EasyArbitraryValuesWidget(QWidget* _parent)
// m_treeWidget->header()->setFont(f);
auto headerItem = new QTreeWidgetItem();
headerItem->setText(int_cast(ArbitraryColumns::Name), "Name");
headerItem->setText(int_cast(ArbitraryColumns::Type), "Type");
headerItem->setText(int_cast(ArbitraryColumns::Name), "Name");
headerItem->setText(int_cast(ArbitraryColumns::Value), "Value");
headerItem->setText(int_cast(ArbitraryColumns::Vin), "ID");
m_treeWidget->setHeaderItem(headerItem);
@ -444,6 +446,7 @@ void EasyArbitraryValuesWidget::rebuild()
void EasyArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId)
{
m_treeWidget->clear();
m_treeWidget->setColumnHidden(int_cast(ArbitraryColumns::Value), profiler_gui::is_max(_blockIndex));
if (_threadId != 0)
{
@ -466,56 +469,44 @@ void EasyArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profi
QTreeWidgetItem* EasyArbitraryValuesWidget::buildTreeForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId)
{
//std::unordered_set<profiler::vin_t, profiler::passthrough_hash<profiler::vin_t> > vins;
//std::unordered_set<std::string> names;
auto rootItem = new QTreeWidgetItem(QTreeWidgetItem::UserType);
rootItem->setText(0, profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _threadRoot, EASY_GLOBALS.hex_thread_id));
rootItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Thread"));
rootItem->setText(int_cast(ArbitraryColumns::Name),
profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _threadRoot, EASY_GLOBALS.hex_thread_id));
if (_blockIndex != ::profiler_gui::numeric_max<decltype(_blockIndex)>())
const bool hasConcreteBlock = !profiler_gui::is_max(_blockIndex);
if (hasConcreteBlock)
{
const auto& block = easyBlocksTree(_blockIndex);
auto blockItem = new QTreeWidgetItem(rootItem, QTreeWidgetItem::UserType);
blockItem->setText(int_cast(ArbitraryColumns::Name), easyBlockName(block));
for (auto childIndex : block.children)
const auto& desc = easyDescriptor(block.node->id());
if (desc.type() == profiler::BlockType::Value)
{
const auto& child = easyBlocksTree(childIndex);
const auto& desc = easyDescriptor(child.node->id());
if (desc.type() == profiler::BlockType::Value)
{
auto vin = child.value->value_id();
// if (vin == 0)
// {
// auto result = names.insert(desc.name()).second;
// if (!result)
// continue; // already in set
// }
// else
// {
// auto result = vins.insert(vin).second;
// if (!result)
// continue; // already in set
// }
auto valueItem = new QTreeWidgetItem(blockItem, QTreeWidgetItem::UserType);
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*child.value));
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16));
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value));
}
auto valueItem = new QTreeWidgetItem(rootItem, QTreeWidgetItem::UserType + 1);
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*block.value));
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(block.value->value_id(), 0, 16));
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*block.value));
return rootItem;
}
return rootItem;
_blockId = block.node->id();
}
if (_blockId == profiler_gui::numeric_max<decltype(_blockId)>())
return rootItem;
const bool noId = profiler_gui::is_max(_blockId);
QTreeWidgetItem* blockItem = nullptr;
if (!noId)
{
blockItem = new QTreeWidgetItem(rootItem, QTreeWidgetItem::UserType);
blockItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Block"));
if (hasConcreteBlock)
blockItem->setText(int_cast(ArbitraryColumns::Name), easyBlockName(_blockIndex));
else
blockItem->setText(int_cast(ArbitraryColumns::Name), easyDescriptor(_blockId).name());
}
auto blockItem = new QTreeWidgetItem(rootItem, QTreeWidgetItem::UserType);
blockItem->setText(int_cast(ArbitraryColumns::Name), easyDescriptor(_blockId).name());
std::unordered_map<profiler::block_id_t, QTreeWidgetItem*, profiler::passthrough_hash<profiler::block_id_t> > blocks;
std::unordered_map<profiler::vin_t, UsedValueTypes, profiler::passthrough_hash<profiler::vin_t> > vins;
std::unordered_map<std::string, UsedValueTypes> names;
std::vector<profiler::block_index_t> stack;
for (auto childIndex : _threadRoot.children)
@ -527,36 +518,76 @@ QTreeWidgetItem* EasyArbitraryValuesWidget::buildTreeForThread(const profiler::B
stack.pop_back();
const auto& block = easyBlocksTree(i);
if (block.node->id() == _blockId || easyDescriptor(block.node->id()).id() == _blockId)
if (noId || block.node->id() == _blockId || easyDescriptor(block.node->id()).id() == _blockId)
{
for (auto c : block.children)
{
if (noId)
stack.push_back(c);
const auto& child = easyBlocksTree(c);
const auto& desc = easyDescriptor(child.node->id());
if (desc.type() == profiler::BlockType::Value)
if (desc.type() != profiler::BlockType::Value)
continue;
if (blockItem == nullptr)
{
auto vin = child.value->value_id();
// if (vin == 0)
// {
// auto result = names.insert(desc.name()).second;
// if (!result)
// continue; // already in set
// }
// else
// {
// auto result = vins.insert(vin).second;
// if (!result)
// continue; // already in set
// }
auto valueItem = new QTreeWidgetItem(blockItem, QTreeWidgetItem::UserType);
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*child.value));
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16));
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value));
const auto id = block.node->id();
auto it = blocks.find(id);
if (it != blocks.end())
{
blockItem = it->second;
}
else
{
blockItem = new QTreeWidgetItem(rootItem, QTreeWidgetItem::UserType);
blockItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Block"));
blockItem->setText(int_cast(ArbitraryColumns::Name), easyBlockName(block));
blocks.emplace(id, blockItem);
}
}
const auto typeIndex = int_cast(child.value->type());
auto vin = child.value->value_id();
QTreeWidgetItem** usedItems = nullptr;
QTreeWidgetItem* valueItem = nullptr;
if (vin == 0)
{
auto result = names.emplace(desc.name(), 0);
usedItems = result.first->second.items;
if (!result.second && (valueItem = *(usedItems + typeIndex)))
{
if (i == _blockIndex)
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value));
continue; // already in set
}
}
else
{
auto result = vins.emplace(vin, 0);
usedItems = result.first->second.items;
if (!result.second && (valueItem = *(usedItems + typeIndex)))
{
if (i == _blockIndex)
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value));
continue; // already in set
}
}
valueItem = new QTreeWidgetItem(blockItem, QTreeWidgetItem::UserType + 1);
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*child.value));
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16));
if (i == _blockIndex)
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value));
*(usedItems + typeIndex) = valueItem;
}
if (noId)
blockItem = nullptr;
}
else
{

View File

@ -58,6 +58,7 @@
#include <QRgb>
#include <QString>
#include <QFont>
#include <type_traits>
#include "common_types.h"
//////////////////////////////////////////////////////////////////////////
@ -90,55 +91,68 @@ EASY_FORCE_INLINE qreal microseconds2units(qreal _value) {
//return _value * 1e-3;
}
#ifdef EASY_CONSTEXPR_AVAILABLE
template <class TEnum>
EASY_FORCE_INLINE EASY_CONSTEXPR_FCN typename ::std::underlying_type<TEnum>::type int_cast(TEnum _enumValue) {
return static_cast<typename ::std::underlying_type<TEnum>::type>(_enumValue);
}
#else
# define int_cast(_enumValue) static_cast<typename ::std::underlying_type<decltype(_enumValue)>::type>(_enumValue)
#endif
//////////////////////////////////////////////////////////////////////////
namespace profiler_gui {
//////////////////////////////////////////////////////////////////////////
template <class T> inline T numeric_max() {
template <class T> inline
EASY_CONSTEXPR_FCN T numeric_max() {
return ::std::numeric_limits<T>::max();
}
template <class T> inline T numeric_max(T) {
template <class T> inline
EASY_CONSTEXPR_FCN T numeric_max(T) {
return ::std::numeric_limits<T>::max();
}
template <class T> inline void set_max(T& _value) {
_value = ::std::numeric_limits<T>::max();
}
template <class T> inline bool is_max(const T& _value) {
template <class T> inline
EASY_CONSTEXPR_FCN bool is_max(const T& _value) {
return _value == ::std::numeric_limits<T>::max();
}
template <class T> inline
void set_max(T& _value) {
_value = ::std::numeric_limits<T>::max();
}
//////////////////////////////////////////////////////////////////////////
inline QRgb toRgb(uint32_t _red, uint32_t _green, uint32_t _blue) {
inline EASY_CONSTEXPR_FCN QRgb toRgb(uint32_t _red, uint32_t _green, uint32_t _blue) {
return (_red << 16) + (_green << 8) + _blue;
}
inline QRgb fromProfilerRgb(uint32_t _red, uint32_t _green, uint32_t _blue) {
if (_red == 0 && _green == 0 && _blue == 0)
return ::profiler::colors::Default;
return toRgb(_red, _green, _blue) | 0x00141414;
inline EASY_CONSTEXPR_FCN QRgb fromProfilerRgb(uint32_t _red, uint32_t _green, uint32_t _blue) {
return _red == 0 && _green == 0 && _blue == 0 ? ::profiler::colors::Default : toRgb(_red, _green, _blue) | 0x00141414;
}
inline bool isLightColor(::profiler::color_t _color) {
const auto sum = 255. - (((_color & 0x00ff0000) >> 16) * 0.299 + ((_color & 0x0000ff00) >> 8) * 0.587 + (_color & 0x000000ff) * 0.114);
return sum < 76.5 || ((_color & 0xff000000) >> 24) < 0x80;
EASY_FORCE_INLINE EASY_CONSTEXPR_FCN qreal colorSum(::profiler::color_t _color) {
return 255. - (((_color & 0x00ff0000) >> 16) * 0.299 + ((_color & 0x0000ff00) >> 8) * 0.587 + (_color & 0x000000ff) * 0.114);
}
inline bool isLightColor(::profiler::color_t _color, qreal _maxSum) {
const auto sum = 255. - (((_color & 0x00ff0000) >> 16) * 0.299 + ((_color & 0x0000ff00) >> 8) * 0.587 + (_color & 0x000000ff) * 0.114);
return sum < _maxSum || ((_color & 0xff000000) >> 24) < 0x80;
inline EASY_CONSTEXPR_FCN bool isLightColor(::profiler::color_t _color) {
return colorSum(_color) < 76.5 || ((_color & 0xff000000) >> 24) < 0x80;
}
inline ::profiler::color_t textColorForFlag(bool _is_light) {
inline EASY_CONSTEXPR_FCN bool isLightColor(::profiler::color_t _color, qreal _maxSum) {
return colorSum(_color) < _maxSum || ((_color & 0xff000000) >> 24) < 0x80;
}
inline EASY_CONSTEXPR_FCN ::profiler::color_t textColorForFlag(bool _is_light) {
return _is_light ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite;
}
inline ::profiler::color_t textColorForRgb(::profiler::color_t _color) {
inline EASY_CONSTEXPR_FCN ::profiler::color_t textColorForRgb(::profiler::color_t _color) {
return isLightColor(_color) ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite;
}
@ -159,7 +173,7 @@ QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval);
//////////////////////////////////////////////////////////////////////////
inline double percentReal(::profiler::timestamp_t _partial, ::profiler::timestamp_t _total) {
return _total ? 100. * static_cast<double>(_partial) / static_cast<double>(_total) : 0.;
return _total != 0 ? 100. * static_cast<double>(_partial) / static_cast<double>(_total) : 0.;
}
inline int percent(::profiler::timestamp_t _partial, ::profiler::timestamp_t _total) {

View File

@ -226,6 +226,7 @@ QVariant EasyDescWidgetItem::data(int _column, int _role) const
case Type::File: return QStringLiteral("File");
case Type::Event: return QStringLiteral("Event");
case Type::Block: return QStringLiteral("Block");
case Type::Value: return QStringLiteral("Arbitrary Value");
}
}
else if (_role == Qt::DisplayRole)
@ -235,6 +236,7 @@ QVariant EasyDescWidgetItem::data(int _column, int _role) const
case Type::File: return QStringLiteral("F");
case Type::Event: return QStringLiteral("E");
case Type::Block: return QStringLiteral("B");
case Type::Value: return QStringLiteral("V");
}
}
}
@ -432,10 +434,20 @@ void EasyDescTreeWidget::build()
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line());
item->setText(DESC_COL_NAME, desc->name());
if (desc->type() == ::profiler::BlockType::Block)
item->setType(EasyDescWidgetItem::Type::Block);
else
item->setType(EasyDescWidgetItem::Type::Event);
switch (desc->type())
{
case ::profiler::BlockType::Block:
item->setType(EasyDescWidgetItem::Type::Block);
break;
case ::profiler::BlockType::Event:
item->setType(EasyDescWidgetItem::Type::Event);
break;
case ::profiler::BlockType::Value:
item->setType(EasyDescWidgetItem::Type::Value);
break;
}
item->setFont(DESC_COL_STATUS, f);
item->setText(DESC_COL_STATUS, statusText(desc->status()));
@ -583,7 +595,10 @@ void EasyDescTreeWidget::resizeColumnsToContents()
void EasyDescTreeWidget::onSelectedBlockChange(uint32_t _block_index)
{
if (::profiler_gui::is_max(_block_index))
{
setCurrentItem(nullptr);
return;
}
auto item = m_items[easyBlocksTree(_block_index).node->id()];
if (item == nullptr)

View File

@ -78,7 +78,8 @@ public:
{
File,
Event,
Block
Block,
Value
};
private:

View File

@ -8,6 +8,7 @@
#include <math.h>
#include <easy/profiler.h>
#include <easy/arbitrary_value.h>
#include <easy/reader.h>
std::condition_variable cv;
@ -19,7 +20,7 @@ int MODELLING_STEPS = 1500;
int RENDER_STEPS = 1500;
int RESOURCE_LOADING_COUNT = 50;
//#define SAMPLE_NETWORK_TEST
#define SAMPLE_NETWORK_TEST
void localSleep(int magic=200000)
{
@ -36,11 +37,17 @@ void loadingResources(){
void prepareMath(){
EASY_FUNCTION(profiler::colors::Green);
uint64_t sum = 0;
int* intarray = new int[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
{
intarray[i] = i * i;
sum += i * i;
}
delete[] intarray;
//std::this_thread::sleep_for(std::chrono::milliseconds(3));
EASY_VALUE("sum", sum, profiler::colors::Blue);
}
void calcIntersect(){
@ -75,7 +82,9 @@ void calcPhys(){
double calcSubbrain(int i)
{
EASY_FUNCTION(profiler::colors::Navy);
return i * i * i - i / 10 + (OBJECTS - i) * 7 ;
auto val = i * i * i - i / 10 + (OBJECTS - i) * 7 ;
EASY_VALUE("subbrainResult", val, profiler::colors::DarkRed);
return val;
}
void calcBrain(){
@ -154,15 +163,23 @@ void modellingThread(){
//cv.wait(lk, []{return g_i == 1; });
EASY_THREAD("Modelling");
#ifdef SAMPLE_NETWORK_TEST
uint64_t step = 0;
while (true) {
#else
for (int i = 0; i < MODELLING_STEPS; i++){
#endif
EASY_END_BLOCK;
EASY_NONSCOPED_BLOCK("Frame");
EASY_NONSCOPED_BLOCK("Frame", true, 15., profiler::ON, -5.f, profiler::colors::Red);
modellingStep();
localSleep(1200000);
++step;
EASY_VALUE("step", step, profiler::colors::Gold);
if (step > 10000000)
step = 0;
EASY_TEXT("Test String", "Some short text. Hey!", profiler::colors::Red);
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
EASY_END_BLOCK;
@ -214,6 +231,13 @@ int main(int argc, char* argv[])
EASY_MAIN_THREAD;
profiler::startListen();
constexpr int grrr[] {2, -3, 4};
auto pppp = &grrr;
EASY_ARRAY("threads count", grrr, 3, false, true, "blabla", profiler::colors::Blue/*, EASY_VIN("threads count")*/, profiler::OFF);
int* intPtr = new int(2);
EASY_VALUE("count", *intPtr);
std::vector<std::thread> threads;
//for (int i=0; i < 3; i++)
{