C++ Logo

SG5

Advanced search

Subject: Re: [EXTERNAL] Fwd: TM-lite proposal
From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2020-01-09 15:30:31


On 09/01/2020 22.04, Michael L. Scott via SG5 wrote:
> Regarding what is allowed within transactions, our current document (P1875R0) says:
>
> An implementation must specify which kinds of operations are supported (permitted to occur) in the dynamic extent of a transaction. At a minimum, this must include: ordinary (non-atomic, non-volatile) reads and writes, ordinary (non-exceptional) control flow, and calls to constexpr functions (even if their arguments are not constants), and to functions defined in the current compilation unit whose bodies would themselves be permissible inside an atomic block. ... [T]he behavior of a program that executes an unsupported operation within the dynamic scope of a transaction is undefined.
>
>
> I’m questioning the need to restrict the guarantee down to local and constexpr functions. Note that even the current language permits non-transaction-safe operations in the static scope of the transaction. This is a deliberate choice, designed to accommodate code that never executes those operations:
>
> if (foo) {
> atomic {
> ...
> if (!foo) {
> cout << “oops”;
> }
> }
> }
>
> Given the possibility that the elided code might change foo, the compiler can’t know that this is safe.
>
> Calls to benign external functions (functions that would be transaction safe if included in the current compilation unit) are clearly no obstacle to correct execution by HTM. They are problematic for fast execution by STM, because the difficulty of obtaining a properly instrumented copy of the function’s code may prompt the compiler to fall back to a global lock. But the lock is indeed a correct implementation, and the STM implementation must be prepared to fall back to it in any case, given the possibility of recurring dynamic conflicts.
>
> In short, the only reason I can think of why an implementation might want to preclude calls to external functions is to avoid the need to check for the existence such calls.

The other problem is library functions: If we allow all functions
(even non-constexpr ones), we don't have an easy library spec marker
to indicate which functions are required to be supported and
which ones aren't. So, we'd need to specify library functions
individually or by broad clause numbers. For example, [atomics]
and [thread] functions are right out, but most of [utilities]
is ok... Except where exactly is setjmp / longjmp defined?

A slightly related issue:

Consider a "helpful" library implementation that does
special debug output (maybe in a file on the side) when
compiling certain algorithms in "debug" mode. The library
might be third-party and not privy to the existence of TM.
However, its algorithms are constexpr, and it avoids
that debug output if std::is_constant_evaluated() is true.
That library has no way of avoiding the debug output =
possibly undefined behavior if it's called inside an atomic
block.

Jens


SG5 list run by herb.sutter at gmail.com

Older Archives on Google Groups