Hey folks. One thing I think we should do over time is move away from
putting everything in the global namespace. One major impediment to that
are the macro logging functions we have like warn, fatal, panic, etc.
There are two factors that make these tricky to de-macro, the line/file
information, and the once-ness of warn_once, etc.
In c++20, there is a new standard library feature called
std::source_location which (with some major caveats) can tell you the line
and file information in normal c++. It can only do that if called in place
where you need the information (not that useful) or as the default value
for a function argument which will tell you the information for the
*caller*, not the function. There are builtins creeping into gcc and clang,
__builtin_LINE and __builtin_FILE, which do similar things and are intended
to support std::source_location.
The other tricky issue is to make warn_once happen once without being able
to hang a "static bool" in front of it to keep track of whether that
particular call sight has been visited yet. I have dug into some deep c++
voodoo which helps make that happen. The major c++20 dependence that has is
that it uses a struct (not a struct type, an actual struct) as a template
parameter. I can nearly get rid of that, but not quite.
Anyway, for posterity and for the curious, what I have so far is below. It
should compile and run successfully on new enough versions of gcc and
clang. One problem it has is that warn_once has become warn<once>(), and
both of those values may need to have namespace qualification if they were
in, say, a Gem5 namespace, ie Gem5::warn<Gem5::once>().
Gabe
#include <iostream>
#include <cstdint>
struct Helper {};
struct LocationHash
{
uint64_t hash = 0xcbf29ce484222325;
constexpr void
addToHash(uint8_t byte)
{
hash ^= byte;
hash *= 1099511628211;
}
constexpr LocationHash(Helper helper, int line = __builtin_LINE(),
const char *file = __builtin_FILE()) noexcept
{
while (*file)
addToHash(*file++);
for (int i = 0; i < sizeof(uint64_t); i++) {
addToHash(line & 0xff);
line = line >> 8;
}
}
};
constexpr Helper once;
template <uint64_t>
static bool bonce = false;
void
warn(const char *format,
int line = __builtin_LINE(), const char *file = __builtin_FILE())
{
std::cout << file << ":" << line << " " << format << "\n";
}
template <LocationHash loc>
void
warn(const char *format,
int line = __builtin_LINE(), const char *file = __builtin_FILE())
{
if (!bonce<loc.hash>) {
std::cout << file << ":" << line << " " << format << "\n";
bonce<loc.hash> = true;
}
}
void
func1()
{
warn<once>("Func 1 once.");
warn("Func 1.");
}
void
func2()
{
warn<once>("Func 2 once.");
}
int
main(int argc, const char *argv[])
{
func1();
func1();
func2();
func1();
}
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s