Hi Gabe,

Is there a use case for GEM5_ONCE() other than warn_once()?

Thanks,

Steve


On Mon, Jul 26, 2021 at 6:06 PM Gabe Black via gem5-dev <[email protected]>
wrote:

> 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
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to