Skip to content

Commit

Permalink
Define TR_VerboseLog::CriticalSection as a vlog RAII lock guard
Browse files Browse the repository at this point in the history
The verbose log can now be locked by declaring a local variable of type
TR_VerboseLog::CriticalSection, and the lock will be automatically
released at the end of the variable's scope. Locking this way is
advantageous because it's not possible to forget to release the lock,
and because the lock will always be released even if an exception is
thrown.

In general, releasing a lock while unexpectedly unwinding for an
exception could leave a program in a bad state. If the lock protects an
invariant, it's possible to take the lock, temporarily violate the
invariant, and then unwind before restoring it. However, in the case of
the verbose log lock specifically, the only effect of unlocking on
unwind will be to prematurely truncate the output being generated at the
time. The output is just diagnostic, so it's best to simply release the
lock.

There is an optional boolean parameter to specify whether or not to
actually acquire the lock. This is useful for cases where we are
incrementally generating output that needs to stay together, but we're
doing so conditionally in the midst of other logic, e.g.

    if (verbose)
        TR_VerboseLog::write(...);

    ...

    if (verbose)
        TR_VerboseLog::write(...);

    ...

    if (verbose)
        TR_VerboseLog::writeLine(...);

The boolean parameter allows for a sequence like this to use
CriticalSection while still only locking when necessary:

    TR_VerboseLog::CriticalSection vlogLock(verbose);

Without it, the use of CriticalSection would force the code either to
lock each write individually, which is too fine a granularity and allows
unwanted interleaving, or to take the lock even when not outputting to
the verbose log.
  • Loading branch information
jdmpapin committed Nov 16, 2021
1 parent 79e5193 commit 38d242b
Showing 1 changed file with 26 additions and 2 deletions.
28 changes: 26 additions & 2 deletions compiler/env/VerboseLog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ enum TR_VlogTag
class TR_VerboseLog
{
public:
//writeLine and write provide multi line write capabilities, and are to be used with vlogAcquire() and vlogRelease(),
//this ensures nice formatted verbose logs
// writeLine and write provide multi line write capabilities, and are to be
// used with CriticalSection or vlogAcquire() and vlogRelease() to ensure
// nicely formatted verbose logs
static void write(const char *format, ...);
static void write(TR_VlogTag tag, const char *format, ...);
static void writeLine(TR_VlogTag tag, const char *format, ...);
Expand All @@ -92,6 +93,29 @@ class TR_VerboseLog
static void writeLineLocked(TR_VlogTag tag, const char *format, ...);
static void vlogAcquire(); //defined in each front end
static void vlogRelease(); //defined in each front end

class CriticalSection
{
public:
CriticalSection(bool lock = true) : _locked(false)
{
if (lock)
{
vlogAcquire();
_locked = true;
}
}

~CriticalSection()
{
if (_locked)
vlogRelease();
}

private:
bool _locked;
};

//only called once early on, after we can print to the vlog
static void initialize(void *config);
private:
Expand Down

0 comments on commit 38d242b

Please sign in to comment.