Commit fe68dbb8 authored by Martin Marinov's avatar Martin Marinov
Browse files

Minor performance improvents to the debug level check.

[git-p4: depot-paths = "//ReForm/ReForm/main/Base/": change = 13175]
parent c5a61f40
...@@ -33,44 +33,10 @@ ...@@ -33,44 +33,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define DEB_module(MODULE);
/* TODO: This should use an atomic thread safe static int
*/
#define DEB_enter_func static int deb_enter_count = 0; \
Debug::Enter deb(__FILE__, __FUNCTION__, deb_enter_count++);
#define DEB_only(CC) CC
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
#define DEB_out_if(CC, LL, AA) { if (deb.permission(LL) && (CC)) \
{ deb.stream() << AA << deb.end(); } }
#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
#define DEB_line_if(CC, LL, AA) { if (deb.permission(LL) && (CC)) \
{ deb.stream() << AA << deb.end_lf(); } }
#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA) { if (deb.permission(LL, 1) && (CC)) \
{ deb.stream(1) << "WARNING: " << AA << deb.end_lf(); } }
#define DEB_error(AA) DEB_error_if(true, AA)
#define DEB_error_if(CC, AA) { if (deb.permission(0, 1) && (CC)) \
{ deb.stream(2) << "ERROR: " << AA << deb.end_err(); } }
// Stream does not fulfill ostream. If you want to exploit an existing
// ostream streamer to DEB_out a class as text without exploiting any
// numeric processing or custom Stream streamers then use this macro thus
// DEB_out(1, "my_class is " << DEB_os_str(my_c) )
#define DEB_os_str(AA) \
dynamic_cast<std::ostringstream &>((std::ostringstream() << AA )).str()
namespace Debug { namespace Debug {
const int INVALID_LEVEL = -1;
class Stream; class Stream;
class Command class Command
...@@ -100,31 +66,26 @@ public: ...@@ -100,31 +66,26 @@ public:
class Enter class Enter
{ {
public: public:
const char* flnm_; //!< File name for this DEB_enter
int nmbr_; //!< deb_nmbr for this function.
int lvl_; //!< deb_level for this function.
int id_; /*!< Unique identifier for this Enter (used in ANCHORS) */ int id_; /*!< Unique identifier for this Enter (used in ANCHORS) */
int count_; /*!< deb_enter_count for this function. */ int outs_; /*!< Number of DEB_outs encountered within this function
int deb_outs_; /*!< Number of DEB_outs encountered within this function
determining whether a given DEB_out should include or omit determining whether a given DEB_out should include or omit
a call stack or exit trace. */ a call stack or exit trace. */
int deb_lines_; /*!< Number of call stack indents including this call. */ int lns_; /*!< Number of call stack indents including this call. */
const char* flnm_; /*!< File name for this DEB_enter. */
Enter(const char* const _flnm, const char* const _funcname, const int _count); Enter(const char* const _flnm, const char* const _fnct, int& _nmbr, int& _lvl);
~Enter(); ~Enter();
//! pass the output on the level or not?
bool pass(const int _lvl) const { return _lvl < lvl_; }
Stream& stream(const int _warn = 0, const bool _print = true); Stream& stream(const int _warn = 0, const bool _print = true);
int permission(const int _lev, const int _warn = 0);
Command end() Command end() const { return Command(Command::CommandType::END); }
{ Command end_lf() const { return Command(Command::CommandType::END_LF); }
return Command(Command::CommandType::END); Command end_err() const { return Command(Command::CommandType::END_ERR); }
}
Command end_lf()
{
return Command(Command::CommandType::END_LF);
}
Command end_err()
{
return Command(Command::CommandType::END_ERR);
}
}; };
class File; class File;
...@@ -145,7 +106,7 @@ private: ...@@ -145,7 +106,7 @@ private:
public: public:
File* dfile() const File* dfile() const
{ {
return this ? dfile_ : nullptr; return dfile_;
} }
//! Constructor. //! Constructor.
Stream( Stream(
...@@ -214,7 +175,38 @@ Stream& operator<<(Stream& _ds, const std::pair<T0, T1>& _pair) ...@@ -214,7 +175,38 @@ Stream& operator<<(Stream& _ds, const std::pair<T0, T1>& _pair)
return _ds; return _ds;
} }
}//namespace #define DEB_module(MODULE)
//TODO: This should use an atomic thread-safe static int(s)
#define DEB_enter_func static int deb_nmbr = 0; \
static int deb_lvl = Debug::INVALID_LEVEL; \
Debug::Enter deb(__FILE__, __FUNCTION__, deb_nmbr, deb_lvl);
#define DEB_only(CC) CC
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
#define DEB_out_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << deb.end(); } }
#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
#define DEB_line_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << deb.end_lf(); } }
#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream(1) << "WARNING: " << AA << deb.end_lf(); } }
#define DEB_error(AA) { deb.stream(2) << "ERROR: " << AA << deb.end_err(); }
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }
// Stream does not fulfill ostream. If you want to exploit an existing
// ostream streamer to DEB_out a class as text without exploiting any
// numeric processing or custom Stream streamers then use this macro thus
// DEB_out(1, "my_class is " << DEB_os_str(my_c) )
#define DEB_os_str(AA) \
dynamic_cast<std::ostringstream &>((std::ostringstream() << AA )).str()
}//namespace Debug
#endif // DEB_ON #endif // DEB_ON
......
...@@ -80,7 +80,7 @@ public: ...@@ -80,7 +80,7 @@ public:
int count(int i = 0) const int count(int i = 0) const
{ {
int num = number_calls(); int num = number_calls();
if (i < num) return debs_[num - 1 - i]->count_; if (i < num) return debs_[num - 1 - i]->nmbr_;
return -1; return -1;
} }
...@@ -121,7 +121,7 @@ public: ...@@ -121,7 +121,7 @@ public:
int seq_cnt = 0; int seq_cnt = 0;
for (int i = 0; i < num; ++i) for (int i = 0; i < num; ++i)
{ {
int cnt = debs_[i]->count_; int cnt = debs_[i]->nmbr_;
if (cnt != prev + 1) if (cnt != prev + 1)
{ {
char buffer[64]; char buffer[64];
...@@ -711,9 +711,8 @@ public: ...@@ -711,9 +711,8 @@ public:
type_ = (Stream::StreamType)(type_ | Stream::StreamType::HTML); type_ = (Stream::StreamType)(type_ | Stream::StreamType::HTML);
} }
int permission(const int _lev, const int _warn, const char* const _flnm) int permission(const char* const _flnm)
{ {
_warn;
int lev = lev_; int lev = lev_;
for (const auto& fltrs : level_selc_map_) for (const auto& fltrs : level_selc_map_)
{ {
...@@ -724,12 +723,6 @@ public: ...@@ -724,12 +723,6 @@ public:
break; break;
} }
} }
lev -= _lev;
if (lev > 0)
priority_ = lev;
else if (lev < 0)
lev = 0;
return lev; return lev;
} }
...@@ -803,17 +796,22 @@ public: ...@@ -803,17 +796,22 @@ public:
}; // endclass File }; // endclass File
// ===================================== //////////////////////////////////////////////////////////////////////////
// Enter member funcs
// ===================================== Enter::Enter(const char* const _flnm, const char* const _fnct,
int& _nmbr, int& _lvl)
: flnm_(_flnm), outs_(0), lns_(0)
{// TODO: for thread-safety we will need to make the constructor body atomic!
nmbr_ = _nmbr++;
if (_lvl == INVALID_LEVEL)
_lvl = Stream::get_global().dfile()->permission(flnm_);
lvl_ = _lvl;
Enter::Enter(const char* const _flnm, const char* const _funcname, const int _count) :
flnm_(_flnm), deb_outs_(0), deb_lines_(0), count_(_count)
{
// TODO: this might have to be atomic
static int id_cnt = 0; static int id_cnt = 0;
id_ = ++id_cnt; id_ = ++id_cnt;
stream(0, false).dfile()->call_stack().add(_funcname, this);
stream(0, false).dfile()->call_stack().add(_fnct, this);
} }
Enter::~Enter() Enter::~Enter()
...@@ -822,7 +820,7 @@ Enter::~Enter() ...@@ -822,7 +820,7 @@ Enter::~Enter()
impl->call_stack().pop(); impl->call_stack().pop();
std::string str; std::string str;
if (((deb_outs_ > 0) || (deb_lines_ > 0)) && impl->anchor(str, id_, "exit", true)) if (((outs_ > 0) || (lns_ > 0)) && impl->anchor(str, id_, "exit", true))
{ {
impl->anchor(str, id_, "exit", false); impl->anchor(str, id_, "exit", false);
impl->print_direct(str); impl->print_direct(str);
...@@ -848,7 +846,7 @@ Stream& Enter::stream(const int _warn, const bool _print) ...@@ -848,7 +846,7 @@ Stream& Enter::stream(const int _warn, const bool _print)
impl->print_direct(buffer); impl->print_direct(buffer);
} }
if (deb_outs_ < 1) if (outs_ < 1)
{ {
// First DEB_out in this function so output callstack, and flush. // First DEB_out in this function so output callstack, and flush.
impl->indent(true); impl->indent(true);
...@@ -871,19 +869,12 @@ Stream& Enter::stream(const int _warn, const bool _print) ...@@ -871,19 +869,12 @@ Stream& Enter::stream(const int _warn, const bool _print)
impl->line_break(); impl->line_break();
ds.dfile()->flush(); ds.dfile()->flush();
} }
++deb_outs_; ++outs_;
} }
return ds; return ds;
} }
int Enter::permission(const int _lev, const int _warn)
{
int res = Stream::get_global().dfile()->permission(_lev, _warn, flnm_);
return res;
}
void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_html) void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_html)
{ {
int num = number_calls(); int num = number_calls();
...@@ -897,7 +888,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_ ...@@ -897,7 +888,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
> linking to the exit anchor (will be present). > linking to the exit anchor (will be present).
L is the first letter of the module name */ L is the first letter of the module name */
char hovert[1024]; char hovert[1024];
sprintf_s(hovert, sizeof(hovert), "%s[%i]", func_name_.c_str(), deb->count_); sprintf_s(hovert, sizeof(hovert), "%s[%i]", func_name_.c_str(), deb->nmbr_);
int col = 0xFFFFFF; int col = 0xFFFFFF;
char buffer[1024]; char buffer[1024];
sprintf_s(buffer, sizeof(buffer), "<FONT COLOR=\"#%06X\">.", col); sprintf_s(buffer, sizeof(buffer), "<FONT COLOR=\"#%06X\">.", col);
...@@ -907,7 +898,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_ ...@@ -907,7 +898,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
_str.append(buffer); _str.append(buffer);
std::string cstk; std::string cstk;
//impl->call_stack().get(cstk); //impl->call_stack().get(cstk);
if ((deb->deb_outs_ > 0) && _dfile->link_to(_str, deb->id_, "enter", cstk, true)) if ((deb->outs_ > 0) && _dfile->link_to(_str, deb->id_, "enter", cstk, true))
{ {
_str.append("&lt;"); _str.append("&lt;");
_dfile->link_to(_str, deb->id_, "enter", cstk, false); _dfile->link_to(_str, deb->id_, "enter", cstk, false);
...@@ -920,7 +911,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_ ...@@ -920,7 +911,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
{ {
_str.append("&gt;"); _str.append("&gt;");
_dfile->link_to(_str, deb->id_, "exit", cstk, false); _dfile->link_to(_str, deb->id_, "exit", cstk, false);
++deb->deb_lines_; ++deb->lns_;
} }
_dfile->hover(_str, std::string(hovert), false); _dfile->hover(_str, std::string(hovert), false);
......
...@@ -19,11 +19,9 @@ namespace Debug { ...@@ -19,11 +19,9 @@ namespace Debug {
class StopWatchSession class StopWatchSession
{ {
public: public:
StopWatchSession( StopWatchSession(Enter& _deb, const char* _sssn_name = nullptr,
Enter& _deb,
const char* _sssn_name = nullptr,
const int _deb_lvl = 2) const int _deb_lvl = 2)
: deb_(_deb), sssn_name_(_sssn_name), deb_lvl_(_deb_lvl) : deb(_deb), sssn_name_(_sssn_name), deb_lvl_(_deb_lvl)
{ {
sw_.start(); sw_.start();
} }
...@@ -31,14 +29,11 @@ public: ...@@ -31,14 +29,11 @@ public:
~StopWatchSession() ~StopWatchSession()
{ {
// TODO: implement "prettier" DEB out if seconds turn into minutes/hours/etc // TODO: implement "prettier" DEB out if seconds turn into minutes/hours/etc
if (!deb_.permission(deb_lvl_)) DEB_line(deb_lvl_, sssn_name_ << " took " << sw_.stop()/1000.0 << " s.");
return;
deb_.stream() << sssn_name_ << " took " << sw_.stop()/1000.0 << " s.\n"
<< deb_.end();
} }
private: private:
Enter& deb_; Enter& deb; // intentional variable name match with the DEB_marcos!
const char* sssn_name_; const char* sssn_name_;
const int deb_lvl_; const int deb_lvl_;
Base::StopWatch sw_; Base::StopWatch sw_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment