mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 13:44:32 +02:00
test: add test app for stdatomic functions
This commit is contained in:
8
components/newlib/test_apps/CMakeLists.txt
Normal file
8
components/newlib/test_apps/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# This is the project CMakeLists.txt file for the test subproject
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||||
|
set(COMPONENTS main)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(newlib_test)
|
19
components/newlib/test_apps/app_test.py
Normal file
19
components/newlib/test_apps/app_test.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import tiny_test_fw # noqa: F401 # pylint: disable=unused-import
|
||||||
|
import ttfw_idf
|
||||||
|
|
||||||
|
try:
|
||||||
|
import typing # noqa: F401 # pylint: disable=unused-import
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ttfw_idf.idf_component_unit_test(env_tag='COMPONENT_UT_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
|
||||||
|
def test_component_ut_newlib(env, _): # type: (tiny_test_fw.Env, typing.Any) -> None
|
||||||
|
dut = env.get_dut('newlib', 'components/newlib/test_apps')
|
||||||
|
dut.start_app()
|
||||||
|
stdout = dut.expect('Tests finished, rc=0', full_stdout=True)
|
||||||
|
ttfw_idf.ComponentUTResult.parse_result(stdout)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_component_ut_newlib()
|
5
components/newlib/test_apps/main/CMakeLists.txt
Normal file
5
components/newlib/test_apps/main/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
idf_component_register(SRCS
|
||||||
|
"test_newlib_main.c"
|
||||||
|
"test_stdatomic.c"
|
||||||
|
REQUIRES test_utils
|
||||||
|
PRIV_REQUIRES unity)
|
12
components/newlib/test_apps/main/test_newlib_main.c
Normal file
12
components/newlib/test_apps/main/test_newlib_main.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include "unity.h"
|
||||||
|
#include "unity_fixture.h"
|
||||||
|
|
||||||
|
static void run_all_tests(void)
|
||||||
|
{
|
||||||
|
RUN_TEST_GROUP(stdatomic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
UNITY_MAIN_FUNC(run_all_tests);
|
||||||
|
}
|
131
components/newlib/test_apps/main/test_stdatomic.c
Normal file
131
components/newlib/test_apps/main/test_stdatomic.c
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "unity_fixture.h"
|
||||||
|
|
||||||
|
/* non-static to prevent optimization */
|
||||||
|
atomic_ullong g_atomic64;
|
||||||
|
atomic_uint g_atomic32;
|
||||||
|
atomic_ushort g_atomic16;
|
||||||
|
atomic_uchar g_atomic8;
|
||||||
|
|
||||||
|
|
||||||
|
TEST_GROUP(stdatomic);
|
||||||
|
|
||||||
|
TEST_SETUP(stdatomic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_TEAR_DOWN(stdatomic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(stdatomic, test_64bit_atomics)
|
||||||
|
{
|
||||||
|
unsigned long long x64 = 0;
|
||||||
|
g_atomic64 = 0; // calls atomic_store
|
||||||
|
|
||||||
|
x64 += atomic_fetch_or (&g_atomic64, 0x1111111111111111ULL);
|
||||||
|
x64 += atomic_fetch_xor(&g_atomic64, 0x3333333333333333ULL);
|
||||||
|
x64 += atomic_fetch_and(&g_atomic64, 0xf0f0f0f0f0f0f0f0ULL);
|
||||||
|
x64 += atomic_fetch_sub(&g_atomic64, 0x0f0f0f0f0f0f0f0fULL);
|
||||||
|
x64 += atomic_fetch_add(&g_atomic64, 0x2222222222222222ULL);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_HEX64(0x6464646464646464ULL, x64);
|
||||||
|
TEST_ASSERT_EQUAL_HEX64(0x3333333333333333ULL, g_atomic64); // calls atomic_load
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(stdatomic, test_32bit_atomics)
|
||||||
|
{
|
||||||
|
unsigned int x32 = 0;
|
||||||
|
g_atomic32 = 0;
|
||||||
|
|
||||||
|
x32 += atomic_fetch_or (&g_atomic32, 0x11111111U);
|
||||||
|
x32 += atomic_fetch_xor(&g_atomic32, 0x33333333U);
|
||||||
|
x32 += atomic_fetch_and(&g_atomic32, 0xf0f0f0f0U);
|
||||||
|
x32 += atomic_fetch_sub(&g_atomic32, 0x0f0f0f0fU);
|
||||||
|
x32 += atomic_fetch_add(&g_atomic32, 0x22222222U);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_HEX32(0x64646464, x32);
|
||||||
|
TEST_ASSERT_EQUAL_HEX32(0x33333333, g_atomic32);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(stdatomic, test_16bit_atomics)
|
||||||
|
{
|
||||||
|
unsigned int x16 = 0;
|
||||||
|
g_atomic16 = 0;
|
||||||
|
|
||||||
|
x16 += atomic_fetch_or (&g_atomic16, 0x1111);
|
||||||
|
x16 += atomic_fetch_xor(&g_atomic16, 0x3333);
|
||||||
|
x16 += atomic_fetch_and(&g_atomic16, 0xf0f0);
|
||||||
|
x16 += atomic_fetch_sub(&g_atomic16, 0x0f0f);
|
||||||
|
x16 += atomic_fetch_add(&g_atomic16, 0x2222);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_HEX16(0x6464, x16);
|
||||||
|
TEST_ASSERT_EQUAL_HEX16(0x3333, g_atomic16);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(stdatomic, test_8bit_atomics)
|
||||||
|
{
|
||||||
|
unsigned int x8 = 0;
|
||||||
|
g_atomic8 = 0;
|
||||||
|
|
||||||
|
x8 += atomic_fetch_or (&g_atomic8, 0x11);
|
||||||
|
x8 += atomic_fetch_xor(&g_atomic8, 0x33);
|
||||||
|
x8 += atomic_fetch_and(&g_atomic8, 0xf0);
|
||||||
|
x8 += atomic_fetch_sub(&g_atomic8, 0x0f);
|
||||||
|
x8 += atomic_fetch_add(&g_atomic8, 0x22);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_HEX8(0x64, x8);
|
||||||
|
TEST_ASSERT_EQUAL_HEX16(0x33, g_atomic8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *exclusion_test_task(void *arg);
|
||||||
|
|
||||||
|
TEST(stdatomic, test_exclusion)
|
||||||
|
{
|
||||||
|
/* Check 64-bit atomics for exclusion.
|
||||||
|
* Only atomic_fetch_add/sub are checked, since all 64-bit atomics use the
|
||||||
|
* same locking implementation.
|
||||||
|
*/
|
||||||
|
g_atomic64 = 0;
|
||||||
|
pthread_t thread1;
|
||||||
|
pthread_t thread2;
|
||||||
|
pthread_create(&thread1, NULL, exclusion_test_task, (void*) 1);
|
||||||
|
pthread_create(&thread2, NULL, exclusion_test_task, (void*) 0);
|
||||||
|
pthread_join(thread1, NULL);
|
||||||
|
pthread_join(thread2, NULL);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(0, g_atomic64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Two threads run in parallel, incrementing and decrementing
|
||||||
|
* a single 64-bit variable. In the end the variable should
|
||||||
|
* have the same value as at the start.
|
||||||
|
*/
|
||||||
|
static void* exclusion_test_task(void *varg)
|
||||||
|
{
|
||||||
|
int arg = (int) varg;
|
||||||
|
for (int i = 0; i < 1000000; ++i) {
|
||||||
|
if (arg == 0) {
|
||||||
|
atomic_fetch_add(&g_atomic64, 1ULL);
|
||||||
|
} else {
|
||||||
|
atomic_fetch_sub(&g_atomic64, 1ULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_GROUP_RUNNER(stdatomic)
|
||||||
|
{
|
||||||
|
RUN_TEST_CASE(stdatomic, test_64bit_atomics)
|
||||||
|
RUN_TEST_CASE(stdatomic, test_32bit_atomics)
|
||||||
|
RUN_TEST_CASE(stdatomic, test_16bit_atomics)
|
||||||
|
RUN_TEST_CASE(stdatomic, test_8bit_atomics)
|
||||||
|
RUN_TEST_CASE(stdatomic, test_exclusion)
|
||||||
|
}
|
3
components/newlib/test_apps/sdkconfig.defaults
Normal file
3
components/newlib/test_apps/sdkconfig.defaults
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_UNITY_ENABLE_FIXTURE=y
|
||||||
|
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n
|
||||||
|
CONFIG_UNITY_ENABLE_64BIT=y
|
Reference in New Issue
Block a user