Skip to content
Snippets Groups Projects
Commit f6de4a13 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

simplify debugging TestableMode

parent 59ad2613
No related branches found
No related tags found
No related merge requests found
......@@ -15,6 +15,10 @@
#include <map>
#include <mutex>
namespace ChimeraTK {
class ConnectionMaker;
}
namespace ChimeraTK::detail {
struct TestableMode {
/** Special exception class which will be thrown if tests with the testable
......@@ -68,7 +72,7 @@ namespace ChimeraTK::detail {
/** Test if the testable mode mutex is locked by the current thread.
*
* This function should generally not be used in user code. */
bool testLock();
[[nodiscard]] bool testLock() const;
[[nodiscard]] bool canStep() const { return counter != 0; }
......@@ -211,6 +215,9 @@ namespace ChimeraTK::detail {
* output of the testable mode. Will return "*UNKNOWN_THREAD*" if the name for the given ID has not yet been set.
*/
std::string threadName(const boost::thread::id& threadId = boost::this_thread::get_id());
bool _debugDecorating{false};
friend class ChimeraTK::ConnectionMaker;
};
/********************************************************************************************************************/
......@@ -224,6 +231,11 @@ namespace ChimeraTK::detail {
AccessorPair<T> other, const VariableNetworkNode& producer, const VariableNetworkNode& consumer) {
if(not enabled) return other;
if(_debugDecorating) {
std::cout << " Decorating pair " << producer.getQualifiedName() << "[" << other.first->getId() << "] -> "
<< consumer.getQualifiedName() << "[" << other.second->getId() << "]" << std::endl;
}
// create variable IDs
size_t varId = detail::TestableMode::getNextVariableId();
size_t varIdReturn;
......@@ -264,6 +276,11 @@ namespace ChimeraTK::detail {
return other;
}
if(_debugDecorating) {
std::cout << " Decorating single " << (direction == DecoratorType::READ ? "consumer " : "feeder ") << name
<< "[" << other->getId() << "]" << std::endl;
}
if(varId == 0) {
varId = detail::TestableMode::getNextVariableId();
}
......
......@@ -121,6 +121,8 @@ namespace ChimeraTK {
void ConnectionMaker::connect() {
debug("Calling Connect...");
_app.getTestableMode()._debugDecorating = _debugConnections;
debug(" Preparing trigger networks");
debug(" Collecting triggers");
std::set<Model::ProcessVariableProxy> triggers;
......
......@@ -86,7 +86,7 @@ namespace ChimeraTK {
for(auto& pv : pvManager->getAllProcessVariables()) {
if(!pv->isReadable()) continue;
callForTypeNoVoid(pv->getValueType(), [&](auto t) {
typedef decltype(t) UserType;
using UserType = decltype(t);
this->getArray<UserType>(pv->getName()).readNonBlocking();
});
}
......
......@@ -27,13 +27,30 @@ namespace ChimeraTK::detail {
}
/*********************************************************************************************************************/
bool TestableMode::testLock() {
bool TestableMode::testLock() const {
if(not enabled) return false;
return getLockObject().owns_lock();
}
/*********************************************************************************************************************/
namespace {
/// This is a trick to make sure the exception is never caught, not even by the BOOST test framework.
void terminateTestStalled() {
struct TestStalled : std::exception {
[[nodiscard]] const char* what() const noexcept override { return "Test stalled."; }
};
try {
throw TestStalled();
}
catch(...) {
std::terminate();
}
}
} // namespace
/*********************************************************************************************************************/
void TestableMode::lock(const std::string& name) {
// don't do anything if testable mode is not enabled
if(not enabled) return;
......@@ -66,7 +83,7 @@ namespace ChimeraTK::detail {
<< std::endl; // LCOV_EXCL_LINE
// throw a specialised exception to make sure whoever catches it really knows what he does...
throw TestsStalled(); // LCOV_EXCL_LINE
terminateTestStalled(); // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE
// check if the last owner of the mutex was this thread, which may be a hint
......@@ -118,7 +135,7 @@ namespace ChimeraTK::detail {
// Check for modules waiting for initial values (prints nothing if there are no such modules)
Application::getInstance().circularDependencyDetector.printWaiters();
// throw a specialised exception to make sure whoever catches it really knows what he does...
throw TestsStalled();
terminateTestStalled();
}
}
else {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment