base: add Activate to enable log of particular targets

When the activate list is not empty, only the target name in the list
will be enabled on logging. Even if the target name is in the activate
list, it will need to enable the flag with --debug-flags to enable the
log correctly.

Change-Id: Ic41cb97c8a2530fdc01e954d6cab76ae475d8722
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/70617
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Yan Lee
2023-05-15 00:27:22 -07:00
parent ae7476bcdc
commit b923cbe840
4 changed files with 108 additions and 3 deletions

View File

@@ -66,6 +66,10 @@ class ObjectMatch
void setExpression(const std::string &expression);
void setExpression(const std::vector<std::string> &expression);
std::vector<std::vector<std::string> > getExpressions();
bool empty() const
{
return tokens.empty();
}
bool match(const std::string &name) const
{
return tokens.empty() ? false : domatch(name);

View File

@@ -108,7 +108,7 @@ void
Logger::dump(Tick when, const std::string &name,
const void *d, int len, const std::string &flag)
{
if (!name.empty() && ignore.match(name))
if (!isEnabled(name))
return;
const char *data = static_cast<const char *>(d);
@@ -148,7 +148,7 @@ void
OstreamLogger::logMessage(Tick when, const std::string &name,
const std::string &flag, const std::string &message)
{
if (!name.empty() && ignore.match(name))
if (!isEnabled(name))
return;
if (!debug::FmtTicksOff && (when != MaxTick))

View File

@@ -39,6 +39,7 @@
#include "base/compiler.hh"
#include "base/cprintf.hh"
#include "base/debug.hh"
#include "base/logging.hh"
#include "base/match.hh"
#include "base/types.hh"
#include "sim/cur_tick.hh"
@@ -60,6 +61,23 @@ class Logger
protected:
/** Name match for objects to ignore */
ObjectMatch ignore;
/** Name match for objects to activate log */
ObjectMatch activate;
bool isEnabled(const std::string &name) const
{
if (name.empty()) // Enable the logger with a empty name.
return true;
bool ignore_match = ignore.match(name);
bool activate_match = activate.match(name);
if (ignore_match && activate_match)
panic("%s in both ignore and activate.\n", name);
if (ignore_match)
return false;
if (!activate.empty() && !activate_match)
return false;
return true;
}
public:
/** Log a single message */
@@ -76,7 +94,7 @@ class Logger
const std::string &flag,
const char *fmt, const Args &...args)
{
if (!name.empty() && ignore.match(name))
if (!isEnabled(name))
return;
std::ostringstream line;
ccprintf(line, fmt, args...);
@@ -104,6 +122,12 @@ class Logger
/** Add objects to ignore */
void addIgnore(const ObjectMatch &ignore_) { ignore.add(ignore_); }
/** Set objects to activate */
void setActivate(ObjectMatch &activate_) { activate = activate_; }
/** Add objects to activate */
void addActivate(const ObjectMatch &activate_) { activate.add(activate_); }
virtual ~Logger() { }
};

View File

@@ -166,6 +166,61 @@ TEST(TraceTest, LogMessageFlagEnabled)
trace::disable();
}
/** Test that log messages are displayed for activated objects (single). */
TEST(TraceTest, LogMessageActivateOne)
{
std::stringstream ss;
trace::OstreamLogger logger(ss);
ObjectMatch activate_foo("Foo");
ObjectMatch activate_bar("Bar");
// Activate foo.
logger.setActivate(activate_foo);
logger.logMessage(Tick(100), "Foo", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Foo: Test message");
logger.logMessage(Tick(100), "Bar", "", "Test message");
ASSERT_EQ(getString(&logger), "");
// When setting a new activate, the old activates are not kept.
logger.setActivate(activate_bar);
logger.logMessage(Tick(100), "Foo", "", "Test message");
ASSERT_EQ(getString(&logger), "");
logger.logMessage(Tick(100), "Bar", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Bar: Test message");
}
/** Test that log messages are displayed for activated objects (multiple). */
TEST(TraceTest, LogMessageActivateMultiple)
{
std::stringstream ss;
trace::OstreamLogger logger(ss);
ObjectMatch activate_foo("Foo");
ObjectMatch activate_bar("Bar");
ObjectMatch activate_thy("Thy");
// Activate foo and bar
logger.setActivate(activate_foo);
logger.addActivate(activate_bar);
logger.logMessage(Tick(100), "Foo", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Foo: Test message");
logger.logMessage(Tick(100), "Bar", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Bar: Test message");
logger.logMessage(Tick(100), "Thy", "", "Test message");
ASSERT_EQ(getString(&logger), "");
// Make sure that when setting a new activate, the old activates
// are not kept
logger.setActivate(activate_thy);
logger.logMessage(Tick(100), "Foo", "", "Test message");
ASSERT_EQ(getString(&logger), "");
logger.logMessage(Tick(100), "Bar", "", "Test message");
ASSERT_EQ(getString(&logger), "");
logger.logMessage(Tick(100), "Thy", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Thy: Test message");
}
/** Test that log messages are not displayed for ignored objects (single). */
TEST(TraceTest, LogMessageIgnoreOne)
{
@@ -221,6 +276,28 @@ TEST(TraceTest, LogMessageIgnoreMultiple)
ASSERT_EQ(getString(&logger), "");
}
/** Test that log messages are displayed properly within ignore and activate */
TEST(TraceTest, LogMessageActivateAndIgnore)
{
std::stringstream ss;
trace::OstreamLogger logger(ss);
ObjectMatch foo("Foo");
ObjectMatch bar("Bar");
// Activate foo and ignore bar
logger.setActivate(foo);
logger.setIgnore(bar);
logger.logMessage(Tick(100), "Foo", "", "Test message");
ASSERT_EQ(getString(&logger), " 100: Foo: Test message");
logger.logMessage(Tick(100), "Bar", "", "Test message");
ASSERT_EQ(getString(&logger), "");
logger.logMessage(Tick(100), "Thy", "", "Test message");
// When the Activate list is not empty and thy is not in the list,
// log of Thy will not be displayed.
ASSERT_EQ(getString(&logger), "");
}
/** Test that dumping for an ignored name does not log anything. */
TEST(TraceTest, DumpIgnored)
{