Commit fe68dbb8 authored by Martin Marinov's avatar Martin Marinov

Minor performance improvents to the debug level check.

[git-p4: depot-paths = "//ReForm/ReForm/main/Base/": change = 13175]
parent c5a61f40
......@@ -33,44 +33,10 @@
#include <string>
#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 {
const int INVALID_LEVEL = -1;
class Stream;
class Command
......@@ -100,31 +66,26 @@ public:
class Enter
{
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 count_; /*!< deb_enter_count for this function. */
int deb_outs_; /*!< Number of DEB_outs encountered within this function
int outs_; /*!< Number of DEB_outs encountered within this function
determining whether a given DEB_out should include or omit
a call stack or exit trace. */
int deb_lines_; /*!< Number of call stack indents including this call. */
const char* flnm_; /*!< File name for this DEB_enter. */
int lns_; /*!< Number of call stack indents including this call. */
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();
//! 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);
int permission(const int _lev, const int _warn = 0);
Command end()
{
return Command(Command::CommandType::END);
}
Command end_lf()
{
return Command(Command::CommandType::END_LF);
}
Command end_err()
{
return Command(Command::CommandType::END_ERR);
}
Command end() const { return Command(Command::CommandType::END); }
Command end_lf() const { return Command(Command::CommandType::END_LF); }
Command end_err() const { return Command(Command::CommandType::END_ERR); }
};
class File;
......@@ -145,7 +106,7 @@ private:
public:
File* dfile() const
{
return this ? dfile_ : nullptr;
return dfile_;
}
//! Constructor.
Stream(
......@@ -214,7 +175,38 @@ Stream& operator<<(Stream& _ds, const std::pair<T0, T1>& _pair)
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
......
......@@ -80,7 +80,7 @@ public:
int count(int i = 0) const
{
int num = number_calls();
if (i < num) return debs_[num - 1 - i]->count_;
if (i < num) return debs_[num - 1 - i]->nmbr_;
return -1;
}
......@@ -121,7 +121,7 @@ public:
int seq_cnt = 0;
for (int i = 0; i < num; ++i)
{
int cnt = debs_[i]->count_;
int cnt = debs_[i]->nmbr_;
if (cnt != prev + 1)
{
char buffer[64];
......@@ -711,9 +711,8 @@ public:
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_;
for (const auto& fltrs : level_selc_map_)
{
......@@ -724,12 +723,6 @@ public:
break;
}
}
lev -= _lev;
if (lev > 0)
priority_ = lev;
else if (lev < 0)
lev = 0;
return lev;
}
......@@ -803,17 +796,22 @@ public:
}; // 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;
id_ = ++id_cnt;
stream(0, false).dfile()->call_stack().add(_funcname, this);
stream(0, false).dfile()->call_stack().add(_fnct, this);
}
Enter::~Enter()
......@@ -822,7 +820,7 @@ Enter::~Enter()
impl->call_stack().pop();
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->print_direct(str);
......@@ -848,7 +846,7 @@ Stream& Enter::stream(const int _warn, const bool _print)
impl->print_direct(buffer);
}
if (deb_outs_ < 1)
if (outs_ < 1)
{
// First DEB_out in this function so output callstack, and flush.
impl->indent(true);
......@@ -871,19 +869,12 @@ Stream& Enter::stream(const int _warn, const bool _print)
impl->line_break();
ds.dfile()->flush();
}
++deb_outs_;
++outs_;
}
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)
{
int num = number_calls();
......@@ -897,7 +888,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
> linking to the exit anchor (will be present).
L is the first letter of the module name */
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;
char buffer[1024];
sprintf_s(buffer, sizeof(buffer), "<FONT COLOR=\"#%06X\">.", col);
......@@ -907,7 +898,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
_str.append(buffer);
std::string 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;");
_dfile->link_to(_str, deb->id_, "enter", cstk, false);
......@@ -920,7 +911,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
{
_str.append("&gt;");
_dfile->link_to(_str, deb->id_, "exit", cstk, false);
++deb->deb_lines_;
++deb->lns_;
}
_dfile->hover(_str, std::string(hovert), false);
......
......@@ -19,11 +19,9 @@ namespace Debug {
class StopWatchSession
{
public:
StopWatchSession(
Enter& _deb,
const char* _sssn_name = nullptr,
StopWatchSession(Enter& _deb, const char* _sssn_name = nullptr,
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();
}
......@@ -31,14 +29,11 @@ public:
~StopWatchSession()
{
// TODO: implement "prettier" DEB out if seconds turn into minutes/hours/etc
if (!deb_.permission(deb_lvl_))
return;
deb_.stream() << sssn_name_ << " took " << sw_.stop()/1000.0 << " s.\n"
<< deb_.end();
DEB_line(deb_lvl_, sssn_name_ << " took " << sw_.stop()/1000.0 << " s.");
}
private:
Enter& deb_;
Enter& deb; // intentional variable name match with the DEB_marcos!
const char* sssn_name_;
const int deb_lvl_;
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