Title
Is the std::atomic_flag class signal-safe?
Status
c++23
Section
[support.signal][atomics.flag]
Submitter
Ruslan Baratov

Created on 2022-08-18.00:00:00 last changed 12 months ago

Messages

Date: 2023-02-13.10:17:57

Proposed resolution:

This wording is relative to N4917.

  1. Modify [support.signal] as indicated:

    -1- A call to the function signal synchronizes with any resulting invocation of the signal handler so installed.

    -2- A plain lock-free atomic operation is an invocation of a function f from [atomics], such that:

    1. (2.1) — f is the function atomic_is_lock_free(), or
    2. (2.2) — f is the member function is_lock_free(), or
    3. (2.?) — f is a non-static member function of class atomic_flag, or
    4. (2.?) — f is a non-member function, and the first parameter of f has type cv atomic_flag*, or
    5. (2.3) — f is a non-static member function invoked on an object A, such that A.is_lock_free() yields true, or
    6. (2.4) — f is a non-member function, and for every pointer-to-atomic argument A passed to f, atomic_is_lock_free(A) yields true.

    -3- An evaluation is signal-safe unless it includes one of the following:

    1. (3.1) — a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe;

      [Note 1: This implicitly excludes the use of new and delete expressions that rely on a library-provided memory allocator. — end note]

    2. (3.2) — an access to an object with thread storage duration;
    3. (3.3) — a dynamic_cast expression;
    4. (3.4) — throwing of an exception;
    5. (3.5) — control entering a try-block or function-try-block;
    6. (3.6) — initialization of a variable with static storage duration requiring dynamic initialization ([basic.start.dynamic], [stmt.dcl])206; or
    7. (3.7) — waiting for the completion of the initialization of a variable with static storage duration ([stmt.dcl]).

    A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.

Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP. ]

Date: 2022-11-11.02:52:57

[ Kona 2022-11-11; Move to Ready ]

Date: 2022-11-15.00:00:00

[ 2022-11-11; Jonathan provides improved wording ]

Date: 2022-11-11.02:45:23

[ Kona 2022-11-10; SG1 yields a recommendation ]

Poll: Adopt the proposed resolution for LWG3756
"f is a non-static member function invoked on an atomic_flag object, or"
"f is a non-member function, and every pointer-to- atomic argument passed to f is atomic_flag, or"

SF F N A SA
11 3 0 0 0

Unanimous consent

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify [support.signal] as indicated:

    -1- A call to the function signal synchronizes with any resulting invocation of the signal handler so installed.

    -2- A plain lock-free atomic operation is an invocation of a function f from [atomics], such that:

    1. (2.1) — f is the function atomic_is_lock_free(), or
    2. (2.2) — f is the member function is_lock_free(), or
    3. (2.?) — f is a non-static member function invoked on an atomic_flag object, or
    4. (2.?) — f is a non-member function, and every pointer-to-atomic argument passed to f is atomic_flag, or
    5. (2.3) — f is a non-static member function invoked on an object A, such that A.is_lock_free() yields true, or
    6. (2.4) — f is a non-member function, and for every pointer-to-atomic argument A passed to f, atomic_is_lock_free(A) yields true.

    -3- An evaluation is signal-safe unless it includes one of the following:

    1. (3.1) — a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe;

      [Note 1: This implicitly excludes the use of new and delete expressions that rely on a library-provided memory allocator. — end note]

    2. (3.2) — an access to an object with thread storage duration;
    3. (3.3) — a dynamic_cast expression;
    4. (3.4) — throwing of an exception;
    5. (3.5) — control entering a try-block or function-try-block;
    6. (3.6) — initialization of a variable with static storage duration requiring dynamic initialization ([basic.start.dynamic], [stmt.dcl])206; or
    7. (3.7) — waiting for the completion of the initialization of a variable with static storage duration ([stmt.dcl]).

    A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.

Date: 2022-09-15.00:00:00

[ 2022-09-23; Reflector poll ]

Set priority to 3 after reflector poll. Send to SG1.

Another way to fix this is to add is_always_lock_free (=true) and is_lock_free() { return true; } to atomic_flag.

Date: 2022-08-18.00:00:00

Following document number N4910 about signal-safe instructions [support.signal] Signal handlers, and it's unclear whether std::atomic_flag is signal-safe.

Formally it doesn't fit any of the mentioned conditions:

  • f is a non-static member function invoked on an object A, such that A.is_lock_free() yields true, or

    (there is no is_lock_free method in std::atomic_flag class)

  • f is a non-member function, and for every pointer-to-atomic argument A passed to f, atomic_is_lock_free(A) yields true

    (std::atomic_flag object can't be passed to atomic_is_lock_free as argument)

However, std::atomic_flag seem to fit well here, it's atomic, and it's always lock-free.

The suggestion is as follows: If std::atomic_flag is signal-safe, then it should be explicitly mentioned in [support.signal], e.g., the following lines should be added:

  • f is a non-static member function invoked on an atomic_flag object, or

  • f is a non-member function, and every pointer-to-atomic argument passed to f is atomic_flag, or

If the std::atomic_flag is not signal-safe, the following note could be added:

[Note: Even though atomic_flag is atomic and lock-free, it's not signal-safe. — end note]

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 10:17:57adminsetmessages: + msg13355
2023-02-13 10:17:57adminsetstatus: voting -> wp
2023-02-06 15:33:48adminsetstatus: ready -> voting
2022-11-11 02:52:57adminsetmessages: + msg13019
2022-11-11 02:52:57adminsetstatus: open -> ready
2022-11-11 02:45:23adminsetmessages: + msg13018
2022-11-10 21:03:13adminsetmessages: + msg12996
2022-11-10 21:03:13adminsetmessages: + msg12995
2022-09-23 15:44:07adminsetmessages: + msg12797
2022-09-23 15:44:07adminsetstatus: new -> open
2022-08-18 00:00:00admincreate