Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
CoMISo
Base
Commits
a514eff0
Commit
a514eff0
authored
Aug 16, 2017
by
Max Lyon
Browse files
Merge from ReForm
parents
8362710d
09fd3eb7
Changes
10
Hide whitespace changes
Inline
Side-by-side
Debug/DebOut.hh
View file @
a514eff0
...
...
@@ -3,24 +3,29 @@
#ifndef BASE_DEBOUT_HH_INCLUDED
#define BASE_DEBOUT_HH_INCLUDED
#ifdef PROGRESS_ON
#include
"Base/Progress/ProgressNode.hh"
#else//PROGRESS_ON
#define PROGRESS_TICK
#endif//PROGRESS_ON
// DEB_ON is defined, or not, in CMakeLists.txt for primary project
#ifndef DEB_ON
#define DEB_module(SS)
#define DEB_enter_func
#define DEB_enter_func
PROGRESS_TICK;
#define DEB_only(CC)
#define DEB_exec(LL, AA) {}
#define DEB_exec_if(CC, LL, AA) {}
#define DEB_out(LL, AA) {}
#define DEB_out_if(CC, LL, AA) {}
#define DEB_line(LL, AA) {}
#define DEB_line_if(CC, LL, AA) {}
#define DEB_exec(LL, AA) { PROGRESS_TICK; }
#define DEB_exec_if(CC, LL, AA) { PROGRESS_TICK; }
#define DEB_out(LL, AA) { PROGRESS_TICK; }
#define DEB_out_if(CC, LL, AA) { PROGRESS_TICK; }
#define DEB_line(LL, AA) { PROGRESS_TICK; }
#define DEB_line_if(CC, LL, AA) { PROGRESS_TICK; }
#define DEB_warning(LL, AA) {}
#define DEB_warning_if(CC, LL, AA) {}
#define DEB_mesh_if(CC, LL, FF, MM) {}
#define DEB_error(AA) {}
#define DEB_error_if(CC, AA) {}
#define DEB_error(AA) {}
#define DEB_error_if(CC, AA) {}
#else // DEB_ON
...
...
@@ -130,27 +135,30 @@ std::string to_string(const T& _t)
#define DEB_module(MODULE)
//TODO: This should use an atomic thread-safe static int(s)
#define DEB_enter_func static int deb_nmbr = 0; \
#define DEB_enter_func \
PROGRESS_TICK; \
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_exec(LL, AA) DEB_exec_if(true, LL, AA)
#define DEB_exec_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) { AA; } }
#define DEB_exec_if(CC, LL, AA) { PROGRESS_TICK; \
{ if (deb.pass(LL) && (CC)) { AA; } } }
#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 << ::Base::Command::END; } }
#define DEB_out_if(CC, LL, AA) {
PROGRESS_TICK;
\
{
if (deb.pass(LL) && (CC)) {
deb.stream() << AA << ::Base::Command::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 << ::Base::LF; } }
#define DEB_line_if(CC, LL, AA) {
PROGRESS_TICK;
\
{
if (deb.pass(LL) && (CC)) {
deb.stream() << AA << ::Base::LF; } }
}
#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA)
{ if (deb.pass(LL) && (CC))
\
{ ::Base::OStringStream strm; strm << AA; \
::Debug::warning(strm.str, BASE_CODELINK); } }
#define DEB_warning_if(CC, LL, AA) \
{
if (deb.pass(LL) && (CC)) {
::Base::OStringStream strm; strm << AA; \
::Debug::warning(strm.str, BASE_CODELINK); } }
#define DEB_error(AA) { ::Base::OStringStream strm; strm << AA; \
::Debug::error(strm.str, BASE_CODELINK); }
...
...
@@ -164,5 +172,4 @@ std::string to_string(const T& _t)
#define DEB_os_str(AA) Debug::to_string(AA)
#endif // DEB_ON
#endif // BASE_DEBOUT_HH_INCLUDED
Debug/DebTime.hh
View file @
a514eff0
...
...
@@ -20,7 +20,7 @@ public:
sw_
.
start
();
}
~
StopWatchSession
()
~
StopWatchSession
()
noexcept
(
false
)
{
// TODO: implement "prettier" DEB out if seconds turn into minutes/hours/etc
DEB_line
(
deb_lvl_
,
sssn_name_
<<
" took "
<<
sw_
.
stop
()
/
1000.0
<<
" s."
);
...
...
Progress/ProgressNode.cc
0 → 100644
View file @
a514eff0
// (C) Copyright 2017 by Autodesk, Inc.
#include
"Base/Security/Mandatory.hh"
#include
"Base/Code/Quality.hh"
#include
"ProgressNode.hh"
#include
"Base/Utils/BaseError.hh"
#include
<exception>
#ifdef PROGRESS_ON
namespace
Progress
{
/// Context implementation
Context
::
Context
()
:
abrt_stte_
(
AST_NONE
),
abrt_alwd_
(
false
),
phny_root_
(
"phony"
),
root_node_
(
&
phny_root_
),
actv_node_
(
&
phny_root_
)
{}
void
Context
::
abort
()
{
// Don't throw if abort is not permitted or
// if there is stack unwinding currently in progress in this thread.
// Note that stack unwinding can be active, and it could be still possible to
// throw safely, see here:
// https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/
// But we rather just wait until the current exception is handled.
if
(
!
abrt_alwd_
||
std
::
uncaught_exception
())
return
;
abrt_stte_
=
AST_PROCESSING
;
BASE_THROW_ERROR
(
PROGRESS_ABORTED
);
}
void
Context
::
resume_abort
()
{
if
(
abrt_stte_
==
AST_PROCESSING
)
BASE_THROW_ERROR
(
PROGRESS_ABORTED
);
}
void
Context
::
end_abort
()
{
abrt_stte_
=
AST_NONE
;
}
void
Context
::
enter_node
(
Node
*
_node
)
{
// NOTE: this function is written carefully to allow asynchronous inspection
// of the node graph from a tracking thread. It assumes the tracking thread
// does not use the node parent.
_node
->
tick_nmbr_
=
0
;
if
(
phony
())
root_node_
=
_node
;
else
_node
->
prnt_
=
actv_node_
;
actv_node_
=
_node
;
}
void
Context
::
exit_node
()
{
// NOTE: this function is written carefully to allow asynchronous inspection
// of the node graph from a tracking thread. It assumes the tracking thread
// does not use the node parent.
if
(
phony
())
return
;
// TODO: this condition is a bug, so we need a DEB_error() here?
auto
*
const
prnt
=
actv_node_
->
prnt_
;
actv_node_
->
prnt_
=
nullptr
;
actv_node_
=
prnt
==
nullptr
?
&
phny_root_
:
prnt
;
}
BASE_THREAD_LOCAL
Context
cntx
;
/// Node implementation
Node
::~
Node
()
{}
TickNumber
Node
::
tick_number_max
()
const
{
return
tick_nmbr_
;
}
}
//namespace Progress
#endif//PROGRESS_ON
Progress/ProgressNode.hh
0 → 100644
View file @
a514eff0
// (C) Copyright 2017 by Autodesk, Inc.
#ifndef BASE_PROGRESS_NODE_HH_INCLUDED
#define BASE_PROGRESS_NODE_HH_INCLUDED
#ifdef PROGRESS_ON
#include
<Base/Utils/Thread.hh>
namespace
Progress
{
//! Progress tick counter type
typedef
unsigned
long
long
TickNumber
;
//! Represent an operational node in the progress graph
class
Node
{
public:
typedef
Node
*
(
*
MakeNodeFunction
)(
Node
*
_next
);
static
inline
Node
*
make_child_list
()
{
return
nullptr
;
}
template
<
typename
...
ArgT
>
static
inline
Node
*
make_child_list
(
MakeNodeFunction
_make_node_fnct
,
const
ArgT
&
...
_args
)
{
return
(
*
_make_node_fnct
)(
make_child_list
(
_args
...));
}
public:
const
char
*
const
name
;
Node
(
const
char
*
const
_name
,
Node
*
_next
=
nullptr
,
Node
*
_chld
=
nullptr
)
:
name
(
_name
),
next_
(
_next
),
chld_
(
_chld
),
prnt_
(
nullptr
),
tick_nmbr_
(
0
)
{}
virtual
~
Node
();
const
Node
*
next
()
const
{
return
next_
;
};
const
Node
*
child
()
const
{
return
chld_
;
};
TickNumber
tick_number
()
const
{
return
tick_nmbr_
;
}
virtual
TickNumber
tick_number_max
()
const
;
void
tick
()
{
++
tick_nmbr_
;
}
protected:
Node
*
next_
;
//!< next node on the same level, last if nullptr
Node
*
chld_
;
//!< first child node, leaf if nullptr
Node
*
prnt_
;
//!< parent node, set temporarily
TickNumber
tick_nmbr_
;
// number of ticks in the node
friend
class
Context
;
};
class
Context
{
public:
//! Default constructor
Context
();
/*!
Get if the progress is "faking" tracking, i.e., using a phony root node.
Phony tracking is faster than checking if a root has been set.
*/
bool
phony
()
const
{
return
actv_node_
==
&
phny_root_
;
}
/*!
Get the currently active node, only makes sense to use that if not phony().
*/
const
Node
*
active_node
()
const
{
return
actv_node_
;
}
/*!
Get the root node, only makes sense to use that if not phony().
*/
const
Node
*
root_node
()
const
{
return
root_node_
;
}
/*!
Request progress abort, intended to be called asynchronously from a "tracking"
thread.
The abort will be triggered on the next \ref tick() in the context thread.
*/
void
request_abort
()
{
abrt_stte_
=
AST_REQUEST
;
}
/*!
Resume an interrupted abort if the exception could be eaten unintentionally,
e.g., by a 3P library. This throws only if the progress is being aborted and
does nothing otherwise.
*/
void
resume_abort
();
/*!
Call this to finish the abort process and indicate that the thrown exception
has been handled.
*/
void
end_abort
();
void
tick
(
const
char
*
const
/*_fnct*/
)
{
actv_node_
->
tick
();
if
(
abrt_stte_
==
AST_REQUEST
)
abort
();
}
void
enter_node
(
Node
*
_node
);
void
exit_node
();
void
set_abort_allowed
(
bool
_abrt_alwd
)
{
abrt_alwd_
=
_abrt_alwd
;
}
bool
abort_allowed
()
const
{
return
abrt_alwd_
;
}
private:
enum
AbortStateType
{
AST_NONE
,
AST_REQUEST
,
AST_PROCESSING
};
private:
AbortStateType
abrt_stte_
;
//!< Abort state
bool
abrt_alwd_
;
//!< Abort allowed flag, ignores AST_REQUEST if false
Node
phny_root_
;
//!< "phony" root
Node
*
root_node_
;
//!< Root node
Node
*
actv_node_
;
//!< Active node
private:
//! Throws PROGRESS_ABORTED to abort the current operation.
void
abort
();
};
//! the current thread Progress context
extern
BASE_THREAD_LOCAL
Context
cntx
;
/*!
Enable (or disable) the Context::abort() processing, use to enable abort()
processing which is disabled by default.
Use this to set up a scope in which the progress can be aborted. Such scope
should be exception-handled, unless exiting the application on abort is desired.
*/
class
AbortAllowedSession
{
public:
AbortAllowedSession
(
const
bool
_abrt_alwd
)
:
abrt_alwd_bckp_
(
cntx
.
abort_allowed
())
{
cntx
.
set_abort_allowed
(
_abrt_alwd
);
}
~
AbortAllowedSession
()
{
cntx
.
set_abort_allowed
(
abrt_alwd_bckp_
);
}
private:
bool
abrt_alwd_bckp_
;
};
}
//namespace Progress
#define PROGRESS_NODE_NAME(OPRT) OPRT##_node
#define PROGRESS_MAKE_NODE_NAME(OPRT) make_##OPRT##_node
#define PROGRESS_DECLARE_NODE(OPRT) \
namespace Progress { \
extern BASE_THREAD_LOCAL Node* PROGRESS_NODE_NAME(OPRT); \
Node* PROGRESS_MAKE_NODE_NAME(OPRT)(Node* _next = nullptr); \
} //namespace Progress {
#define PROGRESS_DEFINE_NODE_CUSTOM(TYPE, OPRT, ...) \
BASE_THREAD_LOCAL Progress::Node* Progress::PROGRESS_NODE_NAME(OPRT) = nullptr; \
Progress::Node* Progress::PROGRESS_MAKE_NODE_NAME(OPRT) \
(Progress::Node* _next) \
{ \
static BASE_THREAD_LOCAL TYPE node(#OPRT, _next, \
Node::make_child_list( __VA_ARGS__ ));\
return OPRT##_node = &node; \
}
#define PROGRESS_DEFINE_NODE(OPRT, ...) \
PROGRESS_DEFINE_NODE_CUSTOM(Node, OPRT, ##__VA_ARGS__)
#if defined(_MSC_VER)
#define __PROGRESS_FUNCTION__ __FUNCTION__ // works in VC well
#else
#define __PROGRESS_FUNCTION__ __PRETTY_FUNCTION__ // needed for gcc & xcode
#endif// _MSC_VER
#define PROGRESS_TICK { Progress::cntx.tick(__PROGRESS_FUNCTION__); }
#define PROGRESS_RESUME_ABORT { Progress::cntx.resume_abort(); }
#define PROGRESS_END_ABORT { Progress::cntx.end_abort(); }
#define PROGRESS_ALLOW_ABORT Progress::AbortAllowedSession abrt_alwd_sssn(true)
#else
#define PROGRESS_DECLARE_NODE(OPRT)
#define PROGRESS_DEFINE_NODE_CUSTOM(TYPE, OPRT, ...)
#define PROGRESS_DEFINE_NODE(OPRT, ...)
#define PROGRESS_TICK
#define PROGRESS_RESUME_ABORT
#define PROGRESS_END_ABORT
#define PROGRESS_ALLOW_ABORT
#endif// PROGRESS_ON
#endif//BASE_PROGRESS_NODE_HH_INCLUDED
Test/Checksum.cc
View file @
a514eff0
...
...
@@ -10,7 +10,7 @@
namespace
Test
{
namespace
Checksum
{
extern
Level
run_lvl
=
L_NONE
;
Level
run_lvl
=
L_NONE
;
namespace
{
...
...
@@ -31,7 +31,7 @@ const Registry& registry()
// class Checksum implementation
Object
::
Object
(
const
char
*
const
_name
,
const
Level
_lvl
)
:
name_
(
_name
),
lvl_
(
_lvl
)
:
lvl_
(
_lvl
),
name_
(
_name
)
{
auto
pos
=
registry_modify
().
emplace
(
name_
,
this
);
if
(
!
pos
.
second
)
...
...
@@ -73,22 +73,66 @@ Difference Object::compare(
#define DIFFERENCE(TYPE) data_diff += Difference(Difference::TYPE)
switch
(
old_rslt_type
)
{
case
Result
::
OK
:
case
Result
::
OK
:
switch
(
new_rslt_type
)
{
return
new_rslt_type
==
Result
::
WARNING
?
DIFFERENCE
(
SUSPICIOUS
)
:
DIFFERENCE
(
REGRESSED
);
}
case
Result
::
WARNING
:
DIFFERENCE
(
SUSPICIOUS
);
break
;
case
Result
::
ERROR
:
DIFFERENCE
(
REGRESSED
);
break
;
default:
DIFFERENCE
(
FAILED
);
break
;
// FAILURE, CRASH, HANG
};
break
;
case
Result
::
WARNING
:
switch
(
new_rslt_type
)
{
return
new_rslt_type
==
Result
::
OK
?
DIFFERENCE
(
IMPROVED
)
:
DIFFERENCE
(
REGRESSED
);
}
default
:
// ERROR, CRASH, HANG, etc
case
Result
::
OK
:
DIFFERENCE
(
IMPROVED
);
break
;
case
Result
::
ERROR
:
DIFFERENCE
(
REGRESSED
);
break
;
default:
DIFFERENCE
(
FAILED
);
break
;
// FAILURE, CRASH, HANG
};
break
;
case
Result
::
ERROR
:
switch
(
new_rslt_type
)
{
return
new_rslt_type
==
Result
::
OK
||
new_rslt_type
==
Result
::
WARNING
?
DIFFERENCE
(
IMPROVED
)
:
DIFFERENCE
(
UNKNOWN
);
}
case
Result
::
OK
:
case
Result
::
WARNING
:
DIFFERENCE
(
IMPROVED
);
break
;
default:
DIFFERENCE
(
FAILED
);
break
;
// FAILURE, CRASH, HANG
};
break
;
case
Result
::
FAILURE
:
switch
(
new_rslt_type
)
{
// worked with or w/o issues, now fails
case
Result
::
OK
:
case
Result
::
WARNING
:
case
Result
::
ERROR
:
DIFFERENCE
(
WORKED
);
break
;
// gracious failure replaced by HANG or CRASH?!
default:
DIFFERENCE
(
FAILED
);
break
;
// CRASH, HANG
};
break
;
case
Result
::
CRASH
:
switch
(
new_rslt_type
)
{
case
Result
::
OK
:
case
Result
::
WARNING
:
case
Result
::
ERROR
:
DIFFERENCE
(
WORKED
);
break
;
// CRASH replaced by gracious failure!
case
Result
::
FAILURE
:
DIFFERENCE
(
IMPROVED
);
break
;
default:
DIFFERENCE
(
FAILED
);
break
;
// CRASH replaced by HANG?!
};
break
;
case
Result
::
HANG
:
switch
(
new_rslt_type
)
{
case
Result
::
OK
:
case
Result
::
WARNING
:
case
Result
::
ERROR
:
DIFFERENCE
(
WORKED
);
break
;
// HANG replaced by gracious failure!
case
Result
::
FAILURE
:
DIFFERENCE
(
IMPROVED
);
break
;
case
Result
::
CRASH
:
DIFFERENCE
(
SUSPICIOUS
);
break
;
// HANG is now CRASH!
default:
;
// disable warnings
};
break
;
}
return
data_diff
;
}
void
Object
::
add
(
const
Result
&
_rslt
,
const
String
&
_data
)
...
...
Test/Checksum.hh
View file @
a514eff0
...
...
@@ -18,9 +18,9 @@ namespace Test {
namespace
Checksum
{
//! Enumerate the checksum levels
enum
Level
{
L_NONE
,
L_PRIME
,
L_ALL
};
enum
Level
{
L_NONE
,
L_STABLE
,
L_PRIME
,
L_ALL
};
extern
Level
run_lvl
;
//<! The checksum run level
const
char
*
const
LEVEL_TEXT
[
3
]
=
{
"NONE"
,
"PRIME"
,
"ALL"
};
const
char
*
const
LEVEL_TEXT
[
4
]
=
{
"NONE"
,
"STABLE"
,
"PRIME"
,
"ALL"
};
//! typedef String, this is used a lot in this namespace
typedef
std
::
string
String
;
...
...
@@ -41,12 +41,14 @@ class Difference
public:
enum
Type
{
EQUAL
,
UNKNOWN
,
IMPROVED
,
NEGLEGIBLE
,
SUSPICIOUS
,
REGRESSED
EQUAL
,
// result is bitwise identical
UNKNOWN
,
// non-negligible difference, but of unknown quality
IMPROVED
,
// result is better
NEGLEGIBLE
,
// result is negligibly different
SUSPICIOUS
,
// result is different, and the new result might be worse
REGRESSED
,
// result is worse
WORKED
,
// result works now, but used to fail
FAILED
// result fails now, but used to work
};
static
const
char
*
const
type_text
(
const
Type
_type
)
...
...
@@ -58,7 +60,9 @@ public:
"IMPROVED"
,
"NEGLEGIBLE"
,
"SUSPICIOUS"
,
"REGRESSED"
"REGRESSED"
,
"WORKED"
,
"FAILED"
};
return
dscr
[
_type
];
}
...
...
@@ -107,6 +111,8 @@ public:
return
_os
<<
_diff
.
type_text
()
<<
" "
<<
_diff
.
dscr_
;
}
bool
operator
<
(
const
Difference
&
_othr
)
const
{
return
type_
<
_othr
.
type_
;
}
private:
Type
type_
;
String
dscr_
;
...
...
Test/ChecksumCondition.hh
View file @
a514eff0
...
...
@@ -21,7 +21,7 @@ namespace Checksum {
class
Condition
:
public
Object
{
public:
Condition
()
:
Object
(
"Condition"
,
L_
PRIM
E
),
nmbr_
(
0
),
fail_nmbr_
(
0
)
{}
Condition
()
:
Object
(
"Condition"
,
L_
STABL
E
),
nmbr_
(
0
),
fail_nmbr_
(
0
)
{}
virtual
void
record
(
const
char
*
const
_cndt
,
const
Base
::
CodeLink
&
_lnk
,
const
bool
_rslt
);
...
...
Utils/BaseErrorInc.hh
View file @
a514eff0
...
...
@@ -9,3 +9,4 @@
// and it is not an error code.
DEFINE_ERROR
(
SUCCESS
,
"Success"
)
DEFINE_ERROR
(
TODO
,
"TODO: Undefined error message"
)
DEFINE_ERROR
(
PROGRESS_ABORTED
,
"Progress aborted"
)
Utils/IOutputStream.hh
View file @
a514eff0
...
...
@@ -207,11 +207,25 @@ public:
print
(
bffr_
,
_bffr_size
,
_frmt
,
_vrbl
);
}
#if __cplusplus >= 201103L || _MSC_VER >= 1900 //C++11 support
// Variadic template constructor
template
<
typename
...
ArgT
>
FormatT
(
const
char
*
const
_frmt
,
const
ArgT
&
...
_args
)
{
print
(
bffr_
,
_bffr_size
,
_frmt
,
_args
...);
}
#endif//C++11 support
friend
IOutputStream
&
operator
<<
(
IOutputStream
&
_os
,
const
Self
&
_frmt
)
{
return
_os
<<
_frmt
.
bffr_
;
}
const
char
*
buffer
()
const
{
return
bffr_
;
}
private:
char
bffr_
[
_bffr_size
];
};
...
...
Utils/Thread.hh
0 → 100644
View file @
a514eff0
// (C) Copyright 2017 by Autodesk, Inc.
#ifndef BASE_THREAD_HH_INCLUDED
#define BASE_THREAD_HH_INCLUDED
// System specific thread support
#if defined(__apple_build_version__)
// work around the lack of thread_local support in XCode 7
#if !__has_feature(cxx_thread_local)
#define BASE_THREAD_LOCAL_BROKEN
#endif//!__has_feature(cxx_thread_local)
#endif//defined(__apple_build_version__)
// TODO: move these macros to a more suitable location
#define GCC_VERSION(MAJOR, MINOR, PATCH) \
(MAJOR * 10000 + MINOR * 100 + PATCH)
#define GCC_VERSION_CURRENT\
GCC_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#if defined(__GNUC__) && GCC_VERSION_CURRENT < GCC_VERSION(4, 8, 3)
// there is a thread_local linker bug prior to gcc-4.8.3
// see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55800
#define BASE_THREAD_LOCAL_BROKEN
#endif//__GNUC__
#ifdef BASE_THREAD_LOCAL_BROKEN // if broken do not use thread_local
#define BASE_THREAD_LOCAL
#else// BASE_THREAD_LOCAL_BROKEN
#define BASE_THREAD_LOCAL thread_local
#endif// BASE_THREAD_LOCAL_BROKEN
#endif//BASE_THREAD_HH_INCLUDED
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment