mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(build): add CONFIG_COMPILER_CXX_ATOMIC_LOCK_POLICY option
libstdc++ selects between a lock-free and a mutex-based policy for std::shared_ptr reference counting based on this macro. Enabling this option forces the lock-free policy, which avoids pulling in the mutex-based implementation and can reduce code size. Note: the lock-free policy avoids embedding a mutex in each control block, saving about 88 bytes per shared_ptr, and improves performance by using atomic operations instead of mutex locking. Note: this option changes the ABI of libstdc++ atomic/shared_ptr helpers. It can be incompatible when linking against prebuilt libraries that were compiled without it, leading to link errors or undefined runtime behavior. Only enable it if all C++ objects and libraries in the build use the same setting.
This commit is contained in:
@@ -9,3 +9,10 @@ components/cxx/test_apps:
|
||||
- cxx
|
||||
- pthread
|
||||
- freertos
|
||||
|
||||
components/cxx/test_apps/atomic_lock_policy:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32c5"
|
||||
disable:
|
||||
- if: IDF_TARGET != "esp32c5"
|
||||
reason: only built on ESP32-C5
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(test_cxx_atomic_lock_policy)
|
||||
@@ -0,0 +1,12 @@
|
||||
| Supported Targets | ESP32-C5 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# C++ atomic lock policy test
|
||||
|
||||
Build-only app. Validates ``CONFIG_COMPILER_CXX_ATOMIC_LOCK_POLICY``: both
|
||||
translation units use ``std::shared_ptr`` under the forced lock-free policy, and
|
||||
the cxx post-build hook accepts the linked executable.
|
||||
|
||||
For the negative build-system check (mixed ``__gnu_cxx::_Lock_policy``), see
|
||||
``tools/test_build_system/test_cxx_atomic_policy.py``, which builds this app with
|
||||
``-DTEST_INVALID_LOCK_POLICIES=1``.
|
||||
@@ -0,0 +1,12 @@
|
||||
idf_component_register(SRCS "test_cxx_atomic_lock_policy.cpp"
|
||||
"cxx_atomic_a.cpp"
|
||||
"cxx_atomic_b.cpp")
|
||||
|
||||
# Default build: both TUs inherit CONFIG_COMPILER_CXX_ATOMIC_LOCK_POLICY.
|
||||
# With -DTEST_INVALID_LOCK_POLICIES=1, undefine the macro for one TU so the
|
||||
# linked image mixes __gnu_cxx::_Lock_policy instantiations; the cxx post-build
|
||||
# hook (check_cxx_atomic_policy.cmake) must then fail the build.
|
||||
if(TEST_INVALID_LOCK_POLICIES)
|
||||
set_source_files_properties("cxx_atomic_b.cpp" PROPERTIES
|
||||
COMPILE_OPTIONS "-U_GLIBCXX_HAVE_ATOMIC_LOCK_POLICY")
|
||||
endif()
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
// Compiled with the project-wide atomic lock policy (CONFIG_COMPILER_CXX_ATOMIC_LOCK_POLICY).
|
||||
// std::make_shared instantiates the __gnu_cxx::_Lock_policy-parameterized
|
||||
// reference counting templates.
|
||||
int cxx_atomic_use_a(void)
|
||||
{
|
||||
auto p = std::make_shared<int>(1);
|
||||
return *p;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
// By default compiled with the same project-wide atomic lock policy as
|
||||
// cxx_atomic_a.cpp. When TEST_INVALID_LOCK_POLICIES is set, main/CMakeLists.txt
|
||||
// adds -U_GLIBCXX_HAVE_ATOMIC_LOCK_POLICY so this TU instantiates a different
|
||||
// __gnu_cxx::_Lock_policy.
|
||||
int cxx_atomic_use_b(void)
|
||||
{
|
||||
auto p = std::make_shared<int>(2);
|
||||
return *p;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int cxx_atomic_use_a(void);
|
||||
int cxx_atomic_use_b(void);
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
// Reference both translation units so the linker keeps their
|
||||
// _Lock_policy instantiations (needed for the invalid-policy build check).
|
||||
volatile int r = cxx_atomic_use_a() + cxx_atomic_use_b();
|
||||
printf("cxx atomic lock policy: %d\n", r);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_COMPILER_CXX_ATOMIC_LOCK_POLICY=y
|
||||
Reference in New Issue
Block a user