Hi folks. I'm continuing to research how to turn warn, panic, etc, into
regular functions instead of macros, and one particularly sticky problem is
how to ensure something like warn_once only happens once.
Right now, the macro warn_once expands to something like this:
do {
static bool once = false;
if (!once) {
warn(...);
once = true;
}
} while (0)
So, a static bool is declared which guards the warn. The problem with this
is that it requires declaring a static bool at the call sight, which as you
can imagine is hard to do without macros.
As far as how it *might* be done, if we can extract the location of the
call (file name, source line, column offset), then we could possibly use a
template holding a static bool.
template <${source location info}>
warn_once(...)
{
static bool once = false;
....
}
There are a few problems with this approach. First, the source location
would have to be broken down into individual primitive types, like an int
for the line number, and individual characters for the file name string,
since you can't use a struct as a non-type template parameter until c++20.
This *might* be possible using fancy template tricks, but it would be a bit
ugly and may gum up the compiler, slowing builds.
Second, if the column information is not unique (I think the standard is
not very specific about what it maps to), then the "once" will apply to
more than one thing. This would be particularly true if a macro whose
contents all share the same source location had multiple warn_once-s in it.
I did a check with grep, and warn_once shows up in all of gem5 about 80
times, so while it's used, it's not used extensively.
What I would like to propose is that instead of having warn_once(...), we
add a new macro called GEM5_ONCE which would be defined something like the
following:
#define GEM5_ONCE(statement) do { \
static [[maybe_unused]] bool _once = ([](){ statement; }(), true); \
while (0)
Then when you want to warn once (or anything else once), you'd write it
like this:
GEM5_ONCE(warn("blah blah"));
This is *slightly* more verbose, but warn_once is only used 80 times in the
whole code base. Also the macro is namespaced now, which is a nice
improvement.
Gabe
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s