migration
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/newlib/test_apps/newlib:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: not supported yet # TODO: [esp32c61] IDF-9284
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/newlib/test_apps/newlib:
|
||||
disable:
|
||||
- if: IDF_TARGET in ["esp32c61"]
|
||||
temporary: true
|
||||
reason: not supported yet # TODO: [esp32c61] IDF-9284
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
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)
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
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)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
idf_component_register(SRCS
|
||||
"test_app_main.c"
|
||||
"test_atomic.c"
|
||||
"test_file.c"
|
||||
"test_locks.c"
|
||||
"test_misc.c"
|
||||
"test_newlib.c"
|
||||
"test_printf.c"
|
||||
"test_setjmp.c"
|
||||
"test_stdatomic.c"
|
||||
"test_time.c"
|
||||
PRIV_REQUIRES unity vfs cmock esp_timer spi_flash test_utils pthread esp_psram
|
||||
WHOLE_ARCHIVE)
|
||||
idf_component_register(SRCS
|
||||
"test_app_main.c"
|
||||
"test_atomic.c"
|
||||
"test_file.c"
|
||||
"test_locks.c"
|
||||
"test_misc.c"
|
||||
"test_newlib.c"
|
||||
"test_printf.c"
|
||||
"test_setjmp.c"
|
||||
"test_stdatomic.c"
|
||||
"test_time.c"
|
||||
PRIV_REQUIRES unity vfs cmock esp_timer spi_flash test_utils pthread esp_psram
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (-350)
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
|
||||
static void check_leak(size_t before_free, size_t after_free, const char *type)
|
||||
{
|
||||
ssize_t delta = after_free - before_free;
|
||||
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
|
||||
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
// Add a short delay of 10ms to allow the idle task to free an remaining memory
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
check_leak(before_free_8bit, after_free_8bit, "8BIT");
|
||||
check_leak(before_free_32bit, after_free_32bit, "32BIT");
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Raise priority to main task as some tests depend on the test task being at priority UNITY_FREERTOS_PRIORITY
|
||||
vTaskPrioritySet(NULL, UNITY_FREERTOS_PRIORITY);
|
||||
unity_run_menu();
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (-350)
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
|
||||
static void check_leak(size_t before_free, size_t after_free, const char *type)
|
||||
{
|
||||
ssize_t delta = after_free - before_free;
|
||||
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
|
||||
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
// Add a short delay of 10ms to allow the idle task to free an remaining memory
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
check_leak(before_free_8bit, after_free_8bit, "8BIT");
|
||||
check_leak(before_free_32bit, after_free_32bit, "32BIT");
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Raise priority to main task as some tests depend on the test task being at priority UNITY_FREERTOS_PRIORITY
|
||||
vTaskPrioritySet(NULL, UNITY_FREERTOS_PRIORITY);
|
||||
unity_run_menu();
|
||||
}
|
||||
|
||||
@@ -1,140 +1,140 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <stdatomic.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_private/cache_utils.h"
|
||||
|
||||
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
|
||||
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();}while(0)
|
||||
#define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_cycle_count(); *p_time = (__t2-__t1);}while(0)
|
||||
|
||||
#define TEST_TIMES 11
|
||||
|
||||
//Test twice, and only get the result of second time, to avoid influence of cache miss
|
||||
#define TEST_WRAP_START() \
|
||||
RECORD_TIME_PREPARE(); \
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu(); \
|
||||
for (int i = 0; i < 2; i++) { \
|
||||
RECORD_TIME_START();
|
||||
|
||||
#define TEST_WRAP_END(output) \
|
||||
RECORD_TIME_END(output); \
|
||||
} \
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
|
||||
typedef void (*test_f)(uint32_t* t_op);
|
||||
|
||||
static const char TAG[] = "test_atomic";
|
||||
static uint32_t s_t_ref;
|
||||
|
||||
static void sorted_array_insert(uint32_t* array, int* size, uint32_t item)
|
||||
{
|
||||
int pos;
|
||||
for (pos = *size; pos > 0; pos--) {
|
||||
if (array[pos - 1] < item) {
|
||||
break;
|
||||
}
|
||||
array[pos] = array[pos - 1];
|
||||
}
|
||||
array[pos] = item;
|
||||
(*size)++;
|
||||
}
|
||||
|
||||
static void test_flow(const char* name, test_f func)
|
||||
{
|
||||
int t_flight_num = 0;
|
||||
uint32_t t_flight_sorted[TEST_TIMES];
|
||||
|
||||
for (int i = 0; i < TEST_TIMES; i++) {
|
||||
uint32_t t_op;
|
||||
func(&t_op);
|
||||
sorted_array_insert(t_flight_sorted, &t_flight_num, t_op);
|
||||
}
|
||||
for (int i = 0; i < TEST_TIMES; i++) {
|
||||
ESP_LOGI(TAG, "%s: %" PRIu32 " ops", name, t_flight_sorted[i] - s_t_ref);
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_ref(uint32_t* t_op)
|
||||
{
|
||||
TEST_WRAP_START()
|
||||
TEST_WRAP_END(t_op)
|
||||
s_t_ref = *t_op;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_load(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t target = rand();
|
||||
TEST_WRAP_START()
|
||||
target = atomic_load(&var);
|
||||
TEST_WRAP_END(t_op)
|
||||
(void) target;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_store(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
atomic_store(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_store_load(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
atomic_store(&var, src);
|
||||
src = atomic_load(&var);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_fetch_and(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
src = atomic_fetch_and(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_fetch_or(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
src = atomic_fetch_or(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_compare_exchange(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
uint32_t cmp = rand();
|
||||
bool res;
|
||||
TEST_WRAP_START()
|
||||
res = atomic_compare_exchange_weak(&var, &src, cmp);
|
||||
TEST_WRAP_END(t_op)
|
||||
(void) res;
|
||||
}
|
||||
|
||||
TEST_CASE("test atomic", "[atomic]")
|
||||
{
|
||||
test_flow("ref", test_ref);
|
||||
|
||||
test_flow("atomic_load", test_atomic_load);
|
||||
test_flow("atomic_store", test_atomic_store);
|
||||
test_flow("atomic_compare_exchange", test_atomic_compare_exchange);
|
||||
test_flow("atomic_store + atomic_load", test_atomic_store_load);
|
||||
test_flow("atomic_and", test_atomic_fetch_and);
|
||||
test_flow("atomic_or", test_atomic_fetch_or);
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
#include <stdatomic.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_private/cache_utils.h"
|
||||
|
||||
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
|
||||
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();}while(0)
|
||||
#define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_cycle_count(); *p_time = (__t2-__t1);}while(0)
|
||||
|
||||
#define TEST_TIMES 11
|
||||
|
||||
//Test twice, and only get the result of second time, to avoid influence of cache miss
|
||||
#define TEST_WRAP_START() \
|
||||
RECORD_TIME_PREPARE(); \
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu(); \
|
||||
for (int i = 0; i < 2; i++) { \
|
||||
RECORD_TIME_START();
|
||||
|
||||
#define TEST_WRAP_END(output) \
|
||||
RECORD_TIME_END(output); \
|
||||
} \
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
|
||||
typedef void (*test_f)(uint32_t* t_op);
|
||||
|
||||
static const char TAG[] = "test_atomic";
|
||||
static uint32_t s_t_ref;
|
||||
|
||||
static void sorted_array_insert(uint32_t* array, int* size, uint32_t item)
|
||||
{
|
||||
int pos;
|
||||
for (pos = *size; pos > 0; pos--) {
|
||||
if (array[pos - 1] < item) {
|
||||
break;
|
||||
}
|
||||
array[pos] = array[pos - 1];
|
||||
}
|
||||
array[pos] = item;
|
||||
(*size)++;
|
||||
}
|
||||
|
||||
static void test_flow(const char* name, test_f func)
|
||||
{
|
||||
int t_flight_num = 0;
|
||||
uint32_t t_flight_sorted[TEST_TIMES];
|
||||
|
||||
for (int i = 0; i < TEST_TIMES; i++) {
|
||||
uint32_t t_op;
|
||||
func(&t_op);
|
||||
sorted_array_insert(t_flight_sorted, &t_flight_num, t_op);
|
||||
}
|
||||
for (int i = 0; i < TEST_TIMES; i++) {
|
||||
ESP_LOGI(TAG, "%s: %" PRIu32 " ops", name, t_flight_sorted[i] - s_t_ref);
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_ref(uint32_t* t_op)
|
||||
{
|
||||
TEST_WRAP_START()
|
||||
TEST_WRAP_END(t_op)
|
||||
s_t_ref = *t_op;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_load(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t target = rand();
|
||||
TEST_WRAP_START()
|
||||
target = atomic_load(&var);
|
||||
TEST_WRAP_END(t_op)
|
||||
(void) target;
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_store(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
atomic_store(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_store_load(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
atomic_store(&var, src);
|
||||
src = atomic_load(&var);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_fetch_and(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
src = atomic_fetch_and(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_fetch_or(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
TEST_WRAP_START()
|
||||
src = atomic_fetch_or(&var, src);
|
||||
TEST_WRAP_END(t_op)
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_atomic_compare_exchange(uint32_t* t_op)
|
||||
{
|
||||
atomic_uint_fast32_t var;
|
||||
uint32_t src = rand();
|
||||
uint32_t cmp = rand();
|
||||
bool res;
|
||||
TEST_WRAP_START()
|
||||
res = atomic_compare_exchange_weak(&var, &src, cmp);
|
||||
TEST_WRAP_END(t_op)
|
||||
(void) res;
|
||||
}
|
||||
|
||||
TEST_CASE("test atomic", "[atomic]")
|
||||
{
|
||||
test_flow("ref", test_ref);
|
||||
|
||||
test_flow("atomic_load", test_atomic_load);
|
||||
test_flow("atomic_store", test_atomic_store);
|
||||
test_flow("atomic_compare_exchange", test_atomic_compare_exchange);
|
||||
test_flow("atomic_store + atomic_load", test_atomic_store_load);
|
||||
test_flow("atomic_and", test_atomic_fetch_and);
|
||||
test_flow("atomic_or", test_atomic_fetch_or);
|
||||
}
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "esp_vfs.h"
|
||||
#include "unity.h"
|
||||
|
||||
/* This test checks that st_blksize value set in struct stat correctly affects the
|
||||
* FILE structure:
|
||||
* - _blksize field should be equal to st_blksize
|
||||
* - buffer size should be equal to st_blksize if it is nonzero, and __BUFSIZ__ otherwise.
|
||||
* This is more of an integration test since some of the functions responsible for this are
|
||||
* in ROM, and have been built without HAVE_BLKSIZE feature for the ESP32 chip.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned blksize;
|
||||
} blksize_test_ctx_t;
|
||||
|
||||
static int blksize_test_open(void* ctx, const char * path, int flags, int mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int blksize_test_fstat(void* ctx, int fd, struct stat * st)
|
||||
{
|
||||
blksize_test_ctx_t* test_ctx = (blksize_test_ctx_t*) ctx;
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->st_mode = S_IFREG;
|
||||
st->st_blksize = test_ctx->blksize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t blksize_test_write(void* ctx, int fd, const void * data, size_t size)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
TEST_CASE("file - blksize", "[newlib_file]")
|
||||
{
|
||||
FILE* f;
|
||||
blksize_test_ctx_t ctx = {};
|
||||
const char c = 42;
|
||||
const esp_vfs_t desc = {
|
||||
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
|
||||
.open_p = blksize_test_open,
|
||||
.fstat_p = blksize_test_fstat,
|
||||
.write_p = blksize_test_write,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_vfs_register("/test", &desc, &ctx));
|
||||
|
||||
/* test with zero st_blksize (=not set) */
|
||||
ctx.blksize = 0;
|
||||
f = fopen("/test/path", "w");
|
||||
TEST_ASSERT_NOT_NULL(f);
|
||||
fwrite(&c, 1, 1, f);
|
||||
TEST_ASSERT_EQUAL(0, f->_blksize);
|
||||
TEST_ASSERT_EQUAL(__BUFSIZ__, __fbufsize(f));
|
||||
fclose(f);
|
||||
|
||||
/* test with non-zero st_blksize */
|
||||
ctx.blksize = 4096;
|
||||
f = fopen("/test/path", "w");
|
||||
TEST_ASSERT_NOT_NULL(f);
|
||||
fwrite(&c, 1, 1, f);
|
||||
TEST_ASSERT_EQUAL(ctx.blksize, f->_blksize);
|
||||
TEST_ASSERT_EQUAL(ctx.blksize, __fbufsize(f));
|
||||
fclose(f);
|
||||
|
||||
TEST_ESP_OK(esp_vfs_unregister("/test"));
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "esp_vfs.h"
|
||||
#include "unity.h"
|
||||
|
||||
/* This test checks that st_blksize value set in struct stat correctly affects the
|
||||
* FILE structure:
|
||||
* - _blksize field should be equal to st_blksize
|
||||
* - buffer size should be equal to st_blksize if it is nonzero, and __BUFSIZ__ otherwise.
|
||||
* This is more of an integration test since some of the functions responsible for this are
|
||||
* in ROM, and have been built without HAVE_BLKSIZE feature for the ESP32 chip.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned blksize;
|
||||
} blksize_test_ctx_t;
|
||||
|
||||
static int blksize_test_open(void* ctx, const char * path, int flags, int mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int blksize_test_fstat(void* ctx, int fd, struct stat * st)
|
||||
{
|
||||
blksize_test_ctx_t* test_ctx = (blksize_test_ctx_t*) ctx;
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->st_mode = S_IFREG;
|
||||
st->st_blksize = test_ctx->blksize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t blksize_test_write(void* ctx, int fd, const void * data, size_t size)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
TEST_CASE("file - blksize", "[newlib_file]")
|
||||
{
|
||||
FILE* f;
|
||||
blksize_test_ctx_t ctx = {};
|
||||
const char c = 42;
|
||||
const esp_vfs_t desc = {
|
||||
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
|
||||
.open_p = blksize_test_open,
|
||||
.fstat_p = blksize_test_fstat,
|
||||
.write_p = blksize_test_write,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_vfs_register("/test", &desc, &ctx));
|
||||
|
||||
/* test with zero st_blksize (=not set) */
|
||||
ctx.blksize = 0;
|
||||
f = fopen("/test/path", "w");
|
||||
TEST_ASSERT_NOT_NULL(f);
|
||||
fwrite(&c, 1, 1, f);
|
||||
TEST_ASSERT_EQUAL(0, f->_blksize);
|
||||
TEST_ASSERT_EQUAL(__BUFSIZ__, __fbufsize(f));
|
||||
fclose(f);
|
||||
|
||||
/* test with non-zero st_blksize */
|
||||
ctx.blksize = 4096;
|
||||
f = fopen("/test/path", "w");
|
||||
TEST_ASSERT_NOT_NULL(f);
|
||||
fwrite(&c, 1, 1, f);
|
||||
TEST_ASSERT_EQUAL(ctx.blksize, f->_blksize);
|
||||
TEST_ASSERT_EQUAL(ctx.blksize, __fbufsize(f));
|
||||
fclose(f);
|
||||
|
||||
TEST_ESP_OK(esp_vfs_unregister("/test"));
|
||||
}
|
||||
|
||||
@@ -1,114 +1,114 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if defined(_RETARGETABLE_LOCKING)
|
||||
|
||||
static void locking_task(void* arg)
|
||||
{
|
||||
_LOCK_T lock = (_LOCK_T) arg;
|
||||
__lock_acquire(lock);
|
||||
__lock_release(lock);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void recursive_locking_task(void* arg)
|
||||
{
|
||||
_LOCK_T lock = (_LOCK_T) arg;
|
||||
__lock_acquire_recursive(lock);
|
||||
__lock_release_recursive(lock);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void test_inner_normal(_LOCK_T lock)
|
||||
{
|
||||
/* Acquire the lock */
|
||||
__lock_acquire(lock);
|
||||
|
||||
/* Create another task to try acquire same lock */
|
||||
TaskHandle_t task_hdl;
|
||||
TEST_ASSERT(xTaskCreate(&locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
|
||||
vTaskDelay(2);
|
||||
/* It should get blocked */
|
||||
TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
|
||||
|
||||
/* Once we release the lock, the task should succeed and suspend itself */
|
||||
__lock_release(lock);
|
||||
vTaskDelay(2);
|
||||
TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
|
||||
vTaskDelete(task_hdl);
|
||||
|
||||
/* Can not recursively acquire the lock from same task */
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire(lock));
|
||||
TEST_ASSERT_EQUAL(-1, __lock_try_acquire(lock));
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
static void test_inner_recursive(_LOCK_T lock)
|
||||
{
|
||||
/* Acquire the lock */
|
||||
__lock_acquire_recursive(lock);
|
||||
|
||||
/* Create another task to try acquire same lock */
|
||||
TaskHandle_t task_hdl;
|
||||
TEST_ASSERT(xTaskCreate(&recursive_locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
|
||||
vTaskDelay(2);
|
||||
/* It should get blocked */
|
||||
TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
|
||||
|
||||
/* Once we release the lock, the task should succeed and suspend itself */
|
||||
__lock_release_recursive(lock);
|
||||
vTaskDelay(2);
|
||||
TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
|
||||
vTaskDelete(task_hdl);
|
||||
|
||||
/* Try recursively acquiring the lock */
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
|
||||
__lock_release_recursive(lock);
|
||||
__lock_release_recursive(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable static locks", "[newlib_locks]")
|
||||
{
|
||||
StaticSemaphore_t semaphore;
|
||||
_LOCK_T lock = (_LOCK_T) xSemaphoreCreateMutexStatic(&semaphore);
|
||||
test_inner_normal(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable static recursive locks", "[newlib_locks]")
|
||||
{
|
||||
StaticSemaphore_t semaphore;
|
||||
_LOCK_T lock = (_LOCK_T) xSemaphoreCreateRecursiveMutexStatic(&semaphore);
|
||||
test_inner_recursive(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable dynamic locks", "[newlib_locks]")
|
||||
{
|
||||
_LOCK_T lock;
|
||||
__lock_init(lock);
|
||||
test_inner_normal(lock);
|
||||
__lock_close(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable dynamic recursive locks", "[newlib_locks]")
|
||||
{
|
||||
_LOCK_T lock;
|
||||
__lock_init_recursive(lock);
|
||||
test_inner_recursive(lock);
|
||||
__lock_close_recursive(lock);
|
||||
}
|
||||
|
||||
#endif // _RETARGETABLE_LOCKING
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if defined(_RETARGETABLE_LOCKING)
|
||||
|
||||
static void locking_task(void* arg)
|
||||
{
|
||||
_LOCK_T lock = (_LOCK_T) arg;
|
||||
__lock_acquire(lock);
|
||||
__lock_release(lock);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void recursive_locking_task(void* arg)
|
||||
{
|
||||
_LOCK_T lock = (_LOCK_T) arg;
|
||||
__lock_acquire_recursive(lock);
|
||||
__lock_release_recursive(lock);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void test_inner_normal(_LOCK_T lock)
|
||||
{
|
||||
/* Acquire the lock */
|
||||
__lock_acquire(lock);
|
||||
|
||||
/* Create another task to try acquire same lock */
|
||||
TaskHandle_t task_hdl;
|
||||
TEST_ASSERT(xTaskCreate(&locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
|
||||
vTaskDelay(2);
|
||||
/* It should get blocked */
|
||||
TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
|
||||
|
||||
/* Once we release the lock, the task should succeed and suspend itself */
|
||||
__lock_release(lock);
|
||||
vTaskDelay(2);
|
||||
TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
|
||||
vTaskDelete(task_hdl);
|
||||
|
||||
/* Can not recursively acquire the lock from same task */
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire(lock));
|
||||
TEST_ASSERT_EQUAL(-1, __lock_try_acquire(lock));
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
static void test_inner_recursive(_LOCK_T lock)
|
||||
{
|
||||
/* Acquire the lock */
|
||||
__lock_acquire_recursive(lock);
|
||||
|
||||
/* Create another task to try acquire same lock */
|
||||
TaskHandle_t task_hdl;
|
||||
TEST_ASSERT(xTaskCreate(&recursive_locking_task, "locking_task", 2048, lock, UNITY_FREERTOS_PRIORITY, &task_hdl));
|
||||
vTaskDelay(2);
|
||||
/* It should get blocked */
|
||||
TEST_ASSERT_EQUAL(eBlocked, eTaskGetState(task_hdl));
|
||||
|
||||
/* Once we release the lock, the task should succeed and suspend itself */
|
||||
__lock_release_recursive(lock);
|
||||
vTaskDelay(2);
|
||||
TEST_ASSERT_EQUAL(eSuspended, eTaskGetState(task_hdl));
|
||||
vTaskDelete(task_hdl);
|
||||
|
||||
/* Try recursively acquiring the lock */
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
|
||||
TEST_ASSERT_EQUAL(0, __lock_try_acquire_recursive(lock));
|
||||
__lock_release_recursive(lock);
|
||||
__lock_release_recursive(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable static locks", "[newlib_locks]")
|
||||
{
|
||||
StaticSemaphore_t semaphore;
|
||||
_LOCK_T lock = (_LOCK_T) xSemaphoreCreateMutexStatic(&semaphore);
|
||||
test_inner_normal(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable static recursive locks", "[newlib_locks]")
|
||||
{
|
||||
StaticSemaphore_t semaphore;
|
||||
_LOCK_T lock = (_LOCK_T) xSemaphoreCreateRecursiveMutexStatic(&semaphore);
|
||||
test_inner_recursive(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable dynamic locks", "[newlib_locks]")
|
||||
{
|
||||
_LOCK_T lock;
|
||||
__lock_init(lock);
|
||||
test_inner_normal(lock);
|
||||
__lock_close(lock);
|
||||
}
|
||||
|
||||
TEST_CASE("Retargetable dynamic recursive locks", "[newlib_locks]")
|
||||
{
|
||||
_LOCK_T lock;
|
||||
__lock_init_recursive(lock);
|
||||
test_inner_recursive(lock);
|
||||
__lock_close_recursive(lock);
|
||||
}
|
||||
|
||||
#endif // _RETARGETABLE_LOCKING
|
||||
|
||||
@@ -1,185 +1,185 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __clang__ // TODO LLVM-330
|
||||
#include <sys/dirent.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include "unity.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_vfs.h"
|
||||
|
||||
TEST_CASE("misc - posix_memalign", "[newlib_misc]")
|
||||
{
|
||||
void* outptr = NULL;
|
||||
int ret;
|
||||
|
||||
ret = posix_memalign(&outptr, 4, 0);
|
||||
TEST_ASSERT_EQUAL_PTR(NULL, outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
|
||||
void* magic = (void*) 0xEFEFEFEF;
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 0x10000000, 64); // too big alignment - should fail on all targets
|
||||
TEST_ASSERT_EQUAL_INT(ret, ENOMEM);
|
||||
TEST_ASSERT_EQUAL_PTR(magic, outptr); // was not modified
|
||||
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 16, 0x10000000); // too big size - should fail on all targets
|
||||
TEST_ASSERT_EQUAL_INT(ret, ENOMEM);
|
||||
TEST_ASSERT_EQUAL_PTR(magic, outptr); // was not modified
|
||||
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 16, 64);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
outptr = magic;
|
||||
heap_caps_malloc_extmem_enable(128);
|
||||
ret = posix_memalign(&outptr, 16, 64);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
outptr = magic;
|
||||
heap_caps_malloc_extmem_enable(64);
|
||||
ret = posix_memalign(&outptr, 16, 128);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("misc - sysconf", "[newlib_misc]")
|
||||
{
|
||||
TEST_ASSERT_NOT_EQUAL(-1, sysconf(_SC_NPROCESSORS_ONLN));
|
||||
}
|
||||
|
||||
TEST_CASE("misc - realpath", "[newlib_misc]")
|
||||
{
|
||||
char out[PATH_MAX];
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("//", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath(".", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("./", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/.", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("./.", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("../..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/a", realpath("/a/", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/a/..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/a/../..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/c", realpath("/a/../b/../c", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/abc/def", realpath("/abc/./def/ghi/..", out));
|
||||
char* out_new = realpath("/abc/./def/ghi/..", NULL);
|
||||
TEST_ASSERT_NOT_NULL(out_new);
|
||||
TEST_ASSERT_EQUAL_STRING("/abc/def", out_new);
|
||||
free(out_new);
|
||||
}
|
||||
|
||||
static int s_select_calls = 0;
|
||||
|
||||
typedef struct {
|
||||
const char **filenames;
|
||||
size_t num_files;
|
||||
size_t current_index;
|
||||
} scandir_test_dir_context_t;
|
||||
|
||||
static DIR *scandir_test_opendir(void* ctx, const char* name)
|
||||
{
|
||||
scandir_test_dir_context_t *dir_ctx = (scandir_test_dir_context_t *)ctx;
|
||||
dir_ctx->current_index = 0;
|
||||
static DIR dir = {};
|
||||
return &dir;
|
||||
}
|
||||
|
||||
static struct dirent *scandir_test_readdir(void* ctx, DIR* pdir)
|
||||
{
|
||||
scandir_test_dir_context_t *dir_ctx = (scandir_test_dir_context_t *)ctx;
|
||||
if (dir_ctx->current_index >= dir_ctx->num_files) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dirent entry;
|
||||
snprintf(entry.d_name, sizeof(entry.d_name), "%s", dir_ctx->filenames[dir_ctx->current_index]);
|
||||
dir_ctx->current_index++;
|
||||
return &entry;
|
||||
}
|
||||
|
||||
static int scandir_test_closedir(void* ctx, DIR* pdir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scandir_test_select(const struct dirent *entry)
|
||||
{
|
||||
s_select_calls++;
|
||||
return strstr(entry->d_name, "test") != NULL;
|
||||
}
|
||||
|
||||
TEST_CASE("file - scandir", "[newlib_misc]")
|
||||
{
|
||||
const char *test_filenames[] = {
|
||||
".",
|
||||
"..",
|
||||
"test_file1.txt",
|
||||
"file2.txt",
|
||||
"test_file3.txt",
|
||||
"test_file4.txt",
|
||||
"test_file5.txt",
|
||||
"test_file6.txt",
|
||||
"test_file7.txt",
|
||||
"test_file8.txt",
|
||||
"test_file9.txt",
|
||||
"test_file10.txt",
|
||||
};
|
||||
size_t num_test_files = sizeof(test_filenames) / sizeof(test_filenames[0]);
|
||||
|
||||
scandir_test_dir_context_t scandir_test_dir_ctx = { .filenames = test_filenames, .num_files = num_test_files };
|
||||
|
||||
const esp_vfs_t scandir_test_vfs = {
|
||||
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
|
||||
.opendir_p = scandir_test_opendir,
|
||||
.readdir_p = scandir_test_readdir,
|
||||
.closedir_p = scandir_test_closedir
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_vfs_register("/data", &scandir_test_vfs, &scandir_test_dir_ctx));
|
||||
|
||||
struct dirent **namelist;
|
||||
s_select_calls = 0;
|
||||
int n = scandir("/data", &namelist, scandir_test_select, alphasort);
|
||||
TEST_ASSERT_NOT_NULL(namelist);
|
||||
TEST_ASSERT_GREATER_THAN(0, n);
|
||||
|
||||
TEST_ASSERT_EQUAL(num_test_files, s_select_calls);
|
||||
TEST_ASSERT_EQUAL(9, n);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
TEST_ASSERT_NOT_NULL(strstr(namelist[i]->d_name, "test"));
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
|
||||
esp_vfs_unregister("/data");
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __clang__ // TODO LLVM-330
|
||||
#include <sys/dirent.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include "unity.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_vfs.h"
|
||||
|
||||
TEST_CASE("misc - posix_memalign", "[newlib_misc]")
|
||||
{
|
||||
void* outptr = NULL;
|
||||
int ret;
|
||||
|
||||
ret = posix_memalign(&outptr, 4, 0);
|
||||
TEST_ASSERT_EQUAL_PTR(NULL, outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
|
||||
void* magic = (void*) 0xEFEFEFEF;
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 0x10000000, 64); // too big alignment - should fail on all targets
|
||||
TEST_ASSERT_EQUAL_INT(ret, ENOMEM);
|
||||
TEST_ASSERT_EQUAL_PTR(magic, outptr); // was not modified
|
||||
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 16, 0x10000000); // too big size - should fail on all targets
|
||||
TEST_ASSERT_EQUAL_INT(ret, ENOMEM);
|
||||
TEST_ASSERT_EQUAL_PTR(magic, outptr); // was not modified
|
||||
|
||||
outptr = magic;
|
||||
ret = posix_memalign(&outptr, 16, 64);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
outptr = magic;
|
||||
heap_caps_malloc_extmem_enable(128);
|
||||
ret = posix_memalign(&outptr, 16, 64);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
outptr = magic;
|
||||
heap_caps_malloc_extmem_enable(64);
|
||||
ret = posix_memalign(&outptr, 16, 128);
|
||||
TEST_ASSERT_TRUE(outptr != magic);
|
||||
TEST_ASSERT_NOT_NULL(outptr);
|
||||
TEST_ASSERT_EQUAL_INT(ret, 0);
|
||||
free(outptr);
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("misc - sysconf", "[newlib_misc]")
|
||||
{
|
||||
TEST_ASSERT_NOT_EQUAL(-1, sysconf(_SC_NPROCESSORS_ONLN));
|
||||
}
|
||||
|
||||
TEST_CASE("misc - realpath", "[newlib_misc]")
|
||||
{
|
||||
char out[PATH_MAX];
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("//", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath(".", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("./", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/.", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("./.", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("../..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/a", realpath("/a/", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/a/..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/", realpath("/a/../..", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/c", realpath("/a/../b/../c", out));
|
||||
TEST_ASSERT_EQUAL_STRING("/abc/def", realpath("/abc/./def/ghi/..", out));
|
||||
char* out_new = realpath("/abc/./def/ghi/..", NULL);
|
||||
TEST_ASSERT_NOT_NULL(out_new);
|
||||
TEST_ASSERT_EQUAL_STRING("/abc/def", out_new);
|
||||
free(out_new);
|
||||
}
|
||||
|
||||
static int s_select_calls = 0;
|
||||
|
||||
typedef struct {
|
||||
const char **filenames;
|
||||
size_t num_files;
|
||||
size_t current_index;
|
||||
} scandir_test_dir_context_t;
|
||||
|
||||
static DIR *scandir_test_opendir(void* ctx, const char* name)
|
||||
{
|
||||
scandir_test_dir_context_t *dir_ctx = (scandir_test_dir_context_t *)ctx;
|
||||
dir_ctx->current_index = 0;
|
||||
static DIR dir = {};
|
||||
return &dir;
|
||||
}
|
||||
|
||||
static struct dirent *scandir_test_readdir(void* ctx, DIR* pdir)
|
||||
{
|
||||
scandir_test_dir_context_t *dir_ctx = (scandir_test_dir_context_t *)ctx;
|
||||
if (dir_ctx->current_index >= dir_ctx->num_files) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dirent entry;
|
||||
snprintf(entry.d_name, sizeof(entry.d_name), "%s", dir_ctx->filenames[dir_ctx->current_index]);
|
||||
dir_ctx->current_index++;
|
||||
return &entry;
|
||||
}
|
||||
|
||||
static int scandir_test_closedir(void* ctx, DIR* pdir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scandir_test_select(const struct dirent *entry)
|
||||
{
|
||||
s_select_calls++;
|
||||
return strstr(entry->d_name, "test") != NULL;
|
||||
}
|
||||
|
||||
TEST_CASE("file - scandir", "[newlib_misc]")
|
||||
{
|
||||
const char *test_filenames[] = {
|
||||
".",
|
||||
"..",
|
||||
"test_file1.txt",
|
||||
"file2.txt",
|
||||
"test_file3.txt",
|
||||
"test_file4.txt",
|
||||
"test_file5.txt",
|
||||
"test_file6.txt",
|
||||
"test_file7.txt",
|
||||
"test_file8.txt",
|
||||
"test_file9.txt",
|
||||
"test_file10.txt",
|
||||
};
|
||||
size_t num_test_files = sizeof(test_filenames) / sizeof(test_filenames[0]);
|
||||
|
||||
scandir_test_dir_context_t scandir_test_dir_ctx = { .filenames = test_filenames, .num_files = num_test_files };
|
||||
|
||||
const esp_vfs_t scandir_test_vfs = {
|
||||
.flags = ESP_VFS_FLAG_CONTEXT_PTR,
|
||||
.opendir_p = scandir_test_opendir,
|
||||
.readdir_p = scandir_test_readdir,
|
||||
.closedir_p = scandir_test_closedir
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_vfs_register("/data", &scandir_test_vfs, &scandir_test_dir_ctx));
|
||||
|
||||
struct dirent **namelist;
|
||||
s_select_calls = 0;
|
||||
int n = scandir("/data", &namelist, scandir_test_select, alphasort);
|
||||
TEST_ASSERT_NOT_NULL(namelist);
|
||||
TEST_ASSERT_GREATER_THAN(0, n);
|
||||
|
||||
TEST_ASSERT_EQUAL(num_test_files, s_select_calls);
|
||||
TEST_ASSERT_EQUAL(9, n);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
TEST_ASSERT_NOT_NULL(strstr(namelist[i]->d_name, "test"));
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
|
||||
esp_vfs_unregister("/data");
|
||||
}
|
||||
|
||||
@@ -1,239 +1,239 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "esp_rom_caps.h"
|
||||
|
||||
TEST_CASE("test ctype functions", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_TRUE(isalnum('a') && isalnum('A') && isalnum('z') && isalnum('Z') && isalnum('0') && isalnum('9'));
|
||||
TEST_ASSERT_FALSE(isalnum('(') || isalnum('-') || isalnum(' ') || isalnum('\x81') || isalnum('.') || isalnum('\\'));
|
||||
TEST_ASSERT_TRUE(isalpha('a') && isalpha('A') && isalpha('z') && isalpha('Z'));
|
||||
TEST_ASSERT_FALSE(isalpha('0') || isalpha('9') || isalpha(')') || isalpha('\t') || isalpha(' ') || isalpha('\x81'));
|
||||
TEST_ASSERT_TRUE(isspace(' ') && isspace('\t') && isspace('\n') && isspace('\r'));
|
||||
TEST_ASSERT_FALSE(isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a'));
|
||||
}
|
||||
|
||||
TEST_CASE("test atoX functions", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(-2147483648, atoi("-2147483648"));
|
||||
TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647"));
|
||||
TEST_ASSERT_EQUAL_INT(42, atoi("000000042"));
|
||||
TEST_ASSERT_EQUAL_INT(0, strtol("foo", NULL, 10));
|
||||
TEST_ASSERT_EQUAL_DOUBLE(0.123443, atof("0.123443"));
|
||||
TEST_ASSERT_EQUAL_FLOAT(0.123443f, atoff("0.123443"));
|
||||
TEST_ASSERT_EQUAL_DOUBLE(31.41238, strtod("0.3141238e2", NULL));
|
||||
TEST_ASSERT_EQUAL_FLOAT(0.025f, strtof("0.025", NULL));
|
||||
}
|
||||
|
||||
TEST_CASE("test sprintf function", "[newlib]")
|
||||
{
|
||||
char *res = NULL;
|
||||
asprintf(&res, "%d %011i %lu %p %x %c %.4f\n", 42, 2147483647, 2147483648UL, (void *) 0x40010000, 0x40020000, 'Q', 1.0f / 137.0f);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n", res);
|
||||
free(res);
|
||||
}
|
||||
|
||||
TEST_CASE("test sscanf function", "[newlib]")
|
||||
{
|
||||
const char *src = "42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n";
|
||||
int fourty_two;
|
||||
int int_max;
|
||||
unsigned long int_max_plus_one;
|
||||
void *iram_ptr;
|
||||
int irom_ptr;
|
||||
char department;
|
||||
float inv_fine_structure_constant;
|
||||
int res = sscanf(src, "%d %d %lu %p %x %c %f", &fourty_two, &int_max, &int_max_plus_one, &iram_ptr, &irom_ptr, &department, &inv_fine_structure_constant);
|
||||
TEST_ASSERT_EQUAL(7, res);
|
||||
TEST_ASSERT_EQUAL(42, fourty_two);
|
||||
TEST_ASSERT_EQUAL(2147483647, int_max);
|
||||
TEST_ASSERT_EQUAL_UINT32(2147483648UL, int_max_plus_one);
|
||||
TEST_ASSERT_EQUAL(0x40010000, (UNITY_UINT32)iram_ptr);
|
||||
TEST_ASSERT_EQUAL(0x40020000, irom_ptr);
|
||||
TEST_ASSERT_EQUAL('Q', department);
|
||||
TEST_ASSERT_TRUE(1.0f / inv_fine_structure_constant > 136 && 1.0f / inv_fine_structure_constant < 138);
|
||||
}
|
||||
|
||||
TEST_CASE("test time functions", "[newlib]")
|
||||
{
|
||||
time_t now = 1464248488;
|
||||
setenv("TZ", "UTC-8", 1);
|
||||
tzset();
|
||||
struct tm *tm_utc = gmtime(&now);
|
||||
TEST_ASSERT_EQUAL(28, tm_utc->tm_sec);
|
||||
TEST_ASSERT_EQUAL(41, tm_utc->tm_min);
|
||||
TEST_ASSERT_EQUAL(7, tm_utc->tm_hour);
|
||||
TEST_ASSERT_EQUAL(26, tm_utc->tm_mday);
|
||||
TEST_ASSERT_EQUAL(4, tm_utc->tm_mon);
|
||||
TEST_ASSERT_EQUAL(116, tm_utc->tm_year);
|
||||
TEST_ASSERT_EQUAL(4, tm_utc->tm_wday);
|
||||
TEST_ASSERT_EQUAL(146, tm_utc->tm_yday);
|
||||
|
||||
struct tm *tm_local = localtime(&now);
|
||||
TEST_ASSERT_EQUAL(28, tm_local->tm_sec);
|
||||
TEST_ASSERT_EQUAL(41, tm_local->tm_min);
|
||||
TEST_ASSERT_EQUAL(15, tm_local->tm_hour);
|
||||
TEST_ASSERT_EQUAL(26, tm_local->tm_mday);
|
||||
TEST_ASSERT_EQUAL(4, tm_local->tm_mon);
|
||||
TEST_ASSERT_EQUAL(116, tm_local->tm_year);
|
||||
TEST_ASSERT_EQUAL(4, tm_local->tm_wday);
|
||||
TEST_ASSERT_EQUAL(146, tm_local->tm_yday);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("test asctime", "[newlib]")
|
||||
{
|
||||
char buf[64];
|
||||
struct tm tm = { 0 };
|
||||
tm.tm_year = 2016 - 1900;
|
||||
tm.tm_mon = 0;
|
||||
tm.tm_mday = 10;
|
||||
tm.tm_hour = 16;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 0;
|
||||
time_t t = mktime(&tm);
|
||||
const char* time_str = asctime(&tm);
|
||||
strlcpy(buf, time_str, sizeof(buf));
|
||||
printf("Setting time: %s", time_str);
|
||||
struct timeval now = { .tv_sec = t };
|
||||
settimeofday(&now, NULL);
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
time_t mtime = tv.tv_sec;
|
||||
struct tm mtm;
|
||||
localtime_r(&mtime, &mtm);
|
||||
time_str = asctime(&mtm);
|
||||
printf("Got time: %s", time_str);
|
||||
TEST_ASSERT_EQUAL_STRING(buf, time_str);
|
||||
}
|
||||
|
||||
static bool fn_in_rom(void *fn)
|
||||
{
|
||||
const int fnaddr = (int)fn;
|
||||
return (fnaddr >= SOC_IROM_MASK_LOW && fnaddr < SOC_IROM_MASK_HIGH);
|
||||
}
|
||||
|
||||
/* Older chips have newlib nano in rom as well, but this is not linked in due to us now using 64 bit time_t
|
||||
and the ROM code was compiled for 32 bit.
|
||||
*/
|
||||
#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2)
|
||||
#define SSCANF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2)
|
||||
|
||||
TEST_CASE("check if ROM or Flash is used for functions", "[newlib]")
|
||||
{
|
||||
#if PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
TEST_ASSERT(fn_in_rom(vfprintf));
|
||||
#else
|
||||
TEST_ASSERT_FALSE(fn_in_rom(vfprintf));
|
||||
#endif // PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
|
||||
#if SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
TEST_ASSERT(fn_in_rom(sscanf));
|
||||
#else
|
||||
TEST_ASSERT_FALSE(fn_in_rom(sscanf));
|
||||
#endif // SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
|
||||
#if defined(CONFIG_SPIRAM_CACHE_WORKAROUND)
|
||||
TEST_ASSERT_FALSE(fn_in_rom(atoi));
|
||||
TEST_ASSERT_FALSE(fn_in_rom(strtol));
|
||||
#else
|
||||
TEST_ASSERT(fn_in_rom(atoi));
|
||||
TEST_ASSERT(fn_in_rom(strtol));
|
||||
#endif //CONFIG_SPIRAM_CACHE_WORKAROUND
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
/* S2 do not have these in ROM */
|
||||
TEST_ASSERT_FALSE(fn_in_rom(atoi));
|
||||
TEST_ASSERT_FALSE(fn_in_rom(strtol));
|
||||
#else
|
||||
TEST_ASSERT(fn_in_rom(atoi));
|
||||
TEST_ASSERT(fn_in_rom(strtol));
|
||||
#endif // defined(CONFIG_IDF_TARGET_ESP32)
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NEWLIB_NANO_FORMAT
|
||||
TEST_CASE("test 64bit int formats", "[newlib]")
|
||||
{
|
||||
char* res = NULL;
|
||||
const uint64_t val = 123456789012LL;
|
||||
|
||||
asprintf(&res, "%llu", val);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("123456789012", res);
|
||||
|
||||
uint64_t sval;
|
||||
int ret = sscanf(res, "%llu", &sval);
|
||||
free(res);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(val, sval);
|
||||
}
|
||||
#else // CONFIG_NEWLIB_NANO_FORMAT
|
||||
TEST_CASE("test 64bit int formats", "[newlib]")
|
||||
{
|
||||
char* res = NULL;
|
||||
const uint64_t val = 123456789012LL;
|
||||
|
||||
asprintf(&res, "%llu", val);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("lu", res);
|
||||
|
||||
uint64_t sval;
|
||||
int ret = sscanf(res, "%llu", &sval);
|
||||
free(res);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
}
|
||||
#endif // CONFIG_NEWLIB_NANO_FORMAT
|
||||
|
||||
TEST_CASE("fmod and fmodf work as expected", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0.1, fmod(10.1, 2.0));
|
||||
TEST_ASSERT_EQUAL(0.1f, fmodf(10.1f, 2.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: can link 'system', 'raise'", "[newlib]")
|
||||
{
|
||||
printf("system: %p, raise: %p\n", &system, &raise);
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: rom and toolchain localtime func gives the same result", "[newlib]")
|
||||
{
|
||||
// This UNIX time represents 2020-03-12 15:00:00 EDT (19:00 GMT)
|
||||
// as can be verified with 'date --date @1584039600'
|
||||
const time_t seconds = 1584039600;
|
||||
setenv("TZ", "EST5EDT,M3.2.0,M11.1.0", 1); // America/New_York
|
||||
tzset();
|
||||
struct tm *tm = localtime(&seconds);
|
||||
tm->tm_isdst = 1;
|
||||
static char buf[32];
|
||||
strftime(buf, sizeof(buf), "%F %T %Z", tm);
|
||||
static char test_result[64];
|
||||
sprintf(test_result, "%s (tm_isdst = %d)", buf, tm->tm_isdst);
|
||||
printf("%s\n", test_result);
|
||||
TEST_ASSERT_EQUAL_STRING("2020-03-12 15:00:00 EDT (tm_isdst = 1)", test_result);
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: printf float as expected", "[newlib]")
|
||||
{
|
||||
const float val = 1.23;
|
||||
int len = printf("test printf float val is %1.2f\n", val);
|
||||
TEST_ASSERT_EQUAL_INT(30, len);
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "esp_rom_caps.h"
|
||||
|
||||
TEST_CASE("test ctype functions", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_TRUE(isalnum('a') && isalnum('A') && isalnum('z') && isalnum('Z') && isalnum('0') && isalnum('9'));
|
||||
TEST_ASSERT_FALSE(isalnum('(') || isalnum('-') || isalnum(' ') || isalnum('\x81') || isalnum('.') || isalnum('\\'));
|
||||
TEST_ASSERT_TRUE(isalpha('a') && isalpha('A') && isalpha('z') && isalpha('Z'));
|
||||
TEST_ASSERT_FALSE(isalpha('0') || isalpha('9') || isalpha(')') || isalpha('\t') || isalpha(' ') || isalpha('\x81'));
|
||||
TEST_ASSERT_TRUE(isspace(' ') && isspace('\t') && isspace('\n') && isspace('\r'));
|
||||
TEST_ASSERT_FALSE(isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a'));
|
||||
}
|
||||
|
||||
TEST_CASE("test atoX functions", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(-2147483648, atoi("-2147483648"));
|
||||
TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647"));
|
||||
TEST_ASSERT_EQUAL_INT(42, atoi("000000042"));
|
||||
TEST_ASSERT_EQUAL_INT(0, strtol("foo", NULL, 10));
|
||||
TEST_ASSERT_EQUAL_DOUBLE(0.123443, atof("0.123443"));
|
||||
TEST_ASSERT_EQUAL_FLOAT(0.123443f, atoff("0.123443"));
|
||||
TEST_ASSERT_EQUAL_DOUBLE(31.41238, strtod("0.3141238e2", NULL));
|
||||
TEST_ASSERT_EQUAL_FLOAT(0.025f, strtof("0.025", NULL));
|
||||
}
|
||||
|
||||
TEST_CASE("test sprintf function", "[newlib]")
|
||||
{
|
||||
char *res = NULL;
|
||||
asprintf(&res, "%d %011i %lu %p %x %c %.4f\n", 42, 2147483647, 2147483648UL, (void *) 0x40010000, 0x40020000, 'Q', 1.0f / 137.0f);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n", res);
|
||||
free(res);
|
||||
}
|
||||
|
||||
TEST_CASE("test sscanf function", "[newlib]")
|
||||
{
|
||||
const char *src = "42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n";
|
||||
int fourty_two;
|
||||
int int_max;
|
||||
unsigned long int_max_plus_one;
|
||||
void *iram_ptr;
|
||||
int irom_ptr;
|
||||
char department;
|
||||
float inv_fine_structure_constant;
|
||||
int res = sscanf(src, "%d %d %lu %p %x %c %f", &fourty_two, &int_max, &int_max_plus_one, &iram_ptr, &irom_ptr, &department, &inv_fine_structure_constant);
|
||||
TEST_ASSERT_EQUAL(7, res);
|
||||
TEST_ASSERT_EQUAL(42, fourty_two);
|
||||
TEST_ASSERT_EQUAL(2147483647, int_max);
|
||||
TEST_ASSERT_EQUAL_UINT32(2147483648UL, int_max_plus_one);
|
||||
TEST_ASSERT_EQUAL(0x40010000, (UNITY_UINT32)iram_ptr);
|
||||
TEST_ASSERT_EQUAL(0x40020000, irom_ptr);
|
||||
TEST_ASSERT_EQUAL('Q', department);
|
||||
TEST_ASSERT_TRUE(1.0f / inv_fine_structure_constant > 136 && 1.0f / inv_fine_structure_constant < 138);
|
||||
}
|
||||
|
||||
TEST_CASE("test time functions", "[newlib]")
|
||||
{
|
||||
time_t now = 1464248488;
|
||||
setenv("TZ", "UTC-8", 1);
|
||||
tzset();
|
||||
struct tm *tm_utc = gmtime(&now);
|
||||
TEST_ASSERT_EQUAL(28, tm_utc->tm_sec);
|
||||
TEST_ASSERT_EQUAL(41, tm_utc->tm_min);
|
||||
TEST_ASSERT_EQUAL(7, tm_utc->tm_hour);
|
||||
TEST_ASSERT_EQUAL(26, tm_utc->tm_mday);
|
||||
TEST_ASSERT_EQUAL(4, tm_utc->tm_mon);
|
||||
TEST_ASSERT_EQUAL(116, tm_utc->tm_year);
|
||||
TEST_ASSERT_EQUAL(4, tm_utc->tm_wday);
|
||||
TEST_ASSERT_EQUAL(146, tm_utc->tm_yday);
|
||||
|
||||
struct tm *tm_local = localtime(&now);
|
||||
TEST_ASSERT_EQUAL(28, tm_local->tm_sec);
|
||||
TEST_ASSERT_EQUAL(41, tm_local->tm_min);
|
||||
TEST_ASSERT_EQUAL(15, tm_local->tm_hour);
|
||||
TEST_ASSERT_EQUAL(26, tm_local->tm_mday);
|
||||
TEST_ASSERT_EQUAL(4, tm_local->tm_mon);
|
||||
TEST_ASSERT_EQUAL(116, tm_local->tm_year);
|
||||
TEST_ASSERT_EQUAL(4, tm_local->tm_wday);
|
||||
TEST_ASSERT_EQUAL(146, tm_local->tm_yday);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("test asctime", "[newlib]")
|
||||
{
|
||||
char buf[64];
|
||||
struct tm tm = { 0 };
|
||||
tm.tm_year = 2016 - 1900;
|
||||
tm.tm_mon = 0;
|
||||
tm.tm_mday = 10;
|
||||
tm.tm_hour = 16;
|
||||
tm.tm_min = 30;
|
||||
tm.tm_sec = 0;
|
||||
time_t t = mktime(&tm);
|
||||
const char* time_str = asctime(&tm);
|
||||
strlcpy(buf, time_str, sizeof(buf));
|
||||
printf("Setting time: %s", time_str);
|
||||
struct timeval now = { .tv_sec = t };
|
||||
settimeofday(&now, NULL);
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
time_t mtime = tv.tv_sec;
|
||||
struct tm mtm;
|
||||
localtime_r(&mtime, &mtm);
|
||||
time_str = asctime(&mtm);
|
||||
printf("Got time: %s", time_str);
|
||||
TEST_ASSERT_EQUAL_STRING(buf, time_str);
|
||||
}
|
||||
|
||||
static bool fn_in_rom(void *fn)
|
||||
{
|
||||
const int fnaddr = (int)fn;
|
||||
return (fnaddr >= SOC_IROM_MASK_LOW && fnaddr < SOC_IROM_MASK_HIGH);
|
||||
}
|
||||
|
||||
/* Older chips have newlib nano in rom as well, but this is not linked in due to us now using 64 bit time_t
|
||||
and the ROM code was compiled for 32 bit.
|
||||
*/
|
||||
#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2)
|
||||
#define SSCANF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2)
|
||||
|
||||
TEST_CASE("check if ROM or Flash is used for functions", "[newlib]")
|
||||
{
|
||||
#if PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
TEST_ASSERT(fn_in_rom(vfprintf));
|
||||
#else
|
||||
TEST_ASSERT_FALSE(fn_in_rom(vfprintf));
|
||||
#endif // PRINTF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
|
||||
#if SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
TEST_ASSERT(fn_in_rom(sscanf));
|
||||
#else
|
||||
TEST_ASSERT_FALSE(fn_in_rom(sscanf));
|
||||
#endif // SSCANF_NANO_IN_ROM || (ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT && !CONFIG_NEWLIB_NANO_FORMAT)
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
|
||||
#if defined(CONFIG_SPIRAM_CACHE_WORKAROUND)
|
||||
TEST_ASSERT_FALSE(fn_in_rom(atoi));
|
||||
TEST_ASSERT_FALSE(fn_in_rom(strtol));
|
||||
#else
|
||||
TEST_ASSERT(fn_in_rom(atoi));
|
||||
TEST_ASSERT(fn_in_rom(strtol));
|
||||
#endif //CONFIG_SPIRAM_CACHE_WORKAROUND
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
/* S2 do not have these in ROM */
|
||||
TEST_ASSERT_FALSE(fn_in_rom(atoi));
|
||||
TEST_ASSERT_FALSE(fn_in_rom(strtol));
|
||||
#else
|
||||
TEST_ASSERT(fn_in_rom(atoi));
|
||||
TEST_ASSERT(fn_in_rom(strtol));
|
||||
#endif // defined(CONFIG_IDF_TARGET_ESP32)
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NEWLIB_NANO_FORMAT
|
||||
TEST_CASE("test 64bit int formats", "[newlib]")
|
||||
{
|
||||
char* res = NULL;
|
||||
const uint64_t val = 123456789012LL;
|
||||
|
||||
asprintf(&res, "%llu", val);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("123456789012", res);
|
||||
|
||||
uint64_t sval;
|
||||
int ret = sscanf(res, "%llu", &sval);
|
||||
free(res);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(val, sval);
|
||||
}
|
||||
#else // CONFIG_NEWLIB_NANO_FORMAT
|
||||
TEST_CASE("test 64bit int formats", "[newlib]")
|
||||
{
|
||||
char* res = NULL;
|
||||
const uint64_t val = 123456789012LL;
|
||||
|
||||
asprintf(&res, "%llu", val);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
TEST_ASSERT_EQUAL_STRING("lu", res);
|
||||
|
||||
uint64_t sval;
|
||||
int ret = sscanf(res, "%llu", &sval);
|
||||
free(res);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
}
|
||||
#endif // CONFIG_NEWLIB_NANO_FORMAT
|
||||
|
||||
TEST_CASE("fmod and fmodf work as expected", "[newlib]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0.1, fmod(10.1, 2.0));
|
||||
TEST_ASSERT_EQUAL(0.1f, fmodf(10.1f, 2.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: can link 'system', 'raise'", "[newlib]")
|
||||
{
|
||||
printf("system: %p, raise: %p\n", &system, &raise);
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: rom and toolchain localtime func gives the same result", "[newlib]")
|
||||
{
|
||||
// This UNIX time represents 2020-03-12 15:00:00 EDT (19:00 GMT)
|
||||
// as can be verified with 'date --date @1584039600'
|
||||
const time_t seconds = 1584039600;
|
||||
setenv("TZ", "EST5EDT,M3.2.0,M11.1.0", 1); // America/New_York
|
||||
tzset();
|
||||
struct tm *tm = localtime(&seconds);
|
||||
tm->tm_isdst = 1;
|
||||
static char buf[32];
|
||||
strftime(buf, sizeof(buf), "%F %T %Z", tm);
|
||||
static char test_result[64];
|
||||
sprintf(test_result, "%s (tm_isdst = %d)", buf, tm->tm_isdst);
|
||||
printf("%s\n", test_result);
|
||||
TEST_ASSERT_EQUAL_STRING("2020-03-12 15:00:00 EDT (tm_isdst = 1)", test_result);
|
||||
}
|
||||
|
||||
TEST_CASE("newlib: printf float as expected", "[newlib]")
|
||||
{
|
||||
const float val = 1.23;
|
||||
int len = printf("test printf float val is %1.2f\n", val);
|
||||
TEST_ASSERT_EQUAL_INT(30, len);
|
||||
}
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
static int my_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
int result = vprintf(fmt, list);
|
||||
va_end(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test_task(void* arg)
|
||||
{
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
printf("00000000%d\n", i);
|
||||
}
|
||||
SemaphoreHandle_t * p_done = (SemaphoreHandle_t *) arg;
|
||||
xSemaphoreGive(*p_done);
|
||||
vTaskDelay(1);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Test flockfile/funlockfile", "[newlib]")
|
||||
{
|
||||
SemaphoreHandle_t done = xSemaphoreCreateBinary();
|
||||
flockfile(stdout);
|
||||
{
|
||||
xTaskCreatePinnedToCore(&test_task, "test_task", 4096, &done, 5, NULL, 1);
|
||||
// make sure test_task is already running and is actually blocked by flockfile
|
||||
TEST_ASSERT_FALSE(xSemaphoreTake(done, 100 / portTICK_PERIOD_MS));
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
my_printf(LOG_ANSI_COLOR_BOLD_BACKGROUND(LOG_ANSI_COLOR_BLACK, LOG_ANSI_COLOR_BG_RED) "I ");
|
||||
my_printf("(%d) ", 737);
|
||||
my_printf("[%s]: ", "TAG");
|
||||
my_printf("%s %d ", "message ", i);
|
||||
my_printf("%s\n", LOG_ANSI_COLOR_RESET);
|
||||
}
|
||||
// test_task is still blocked by flockfile
|
||||
TEST_ASSERT_FALSE(xSemaphoreTake(done, 100 / portTICK_PERIOD_MS));
|
||||
}
|
||||
funlockfile(stdout);
|
||||
// after funlockfile, test_task can print a msg and complete test_task
|
||||
TEST_ASSERT_TRUE(xSemaphoreTake(done, portMAX_DELAY));
|
||||
vSemaphoreDelete(done);
|
||||
}
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
static int my_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
int result = vprintf(fmt, list);
|
||||
va_end(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test_task(void* arg)
|
||||
{
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
printf("00000000%d\n", i);
|
||||
}
|
||||
SemaphoreHandle_t * p_done = (SemaphoreHandle_t *) arg;
|
||||
xSemaphoreGive(*p_done);
|
||||
vTaskDelay(1);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Test flockfile/funlockfile", "[newlib]")
|
||||
{
|
||||
SemaphoreHandle_t done = xSemaphoreCreateBinary();
|
||||
flockfile(stdout);
|
||||
{
|
||||
xTaskCreatePinnedToCore(&test_task, "test_task", 4096, &done, 5, NULL, 1);
|
||||
// make sure test_task is already running and is actually blocked by flockfile
|
||||
TEST_ASSERT_FALSE(xSemaphoreTake(done, 100 / portTICK_PERIOD_MS));
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
my_printf(LOG_ANSI_COLOR_BOLD_BACKGROUND(LOG_ANSI_COLOR_BLACK, LOG_ANSI_COLOR_BG_RED) "I ");
|
||||
my_printf("(%d) ", 737);
|
||||
my_printf("[%s]: ", "TAG");
|
||||
my_printf("%s %d ", "message ", i);
|
||||
my_printf("%s\n", LOG_ANSI_COLOR_RESET);
|
||||
}
|
||||
// test_task is still blocked by flockfile
|
||||
TEST_ASSERT_FALSE(xSemaphoreTake(done, 100 / portTICK_PERIOD_MS));
|
||||
}
|
||||
funlockfile(stdout);
|
||||
// after funlockfile, test_task can print a msg and complete test_task
|
||||
TEST_ASSERT_TRUE(xSemaphoreTake(done, portMAX_DELAY));
|
||||
vSemaphoreDelete(done);
|
||||
}
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
typedef struct {
|
||||
jmp_buf jmp_env;
|
||||
uint32_t retval;
|
||||
volatile bool inner_called;
|
||||
} setjmp_test_ctx_t;
|
||||
|
||||
static __attribute__((noreturn)) void inner(setjmp_test_ctx_t *ctx)
|
||||
{
|
||||
printf("inner, retval=0x%" PRIx32 "\n", ctx->retval);
|
||||
ctx->inner_called = true;
|
||||
longjmp(ctx->jmp_env, ctx->retval);
|
||||
TEST_FAIL_MESSAGE("Should not reach here");
|
||||
}
|
||||
|
||||
TEST_CASE("setjmp and longjmp", "[newlib]")
|
||||
{
|
||||
const uint32_t expected = 0x12345678;
|
||||
setjmp_test_ctx_t ctx = {
|
||||
.retval = expected
|
||||
};
|
||||
uint32_t ret = setjmp(ctx.jmp_env);
|
||||
if (!ctx.inner_called) {
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
inner(&ctx);
|
||||
} else {
|
||||
TEST_ASSERT_EQUAL(expected, ret);
|
||||
}
|
||||
TEST_ASSERT(ctx.inner_called);
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
typedef struct {
|
||||
jmp_buf jmp_env;
|
||||
uint32_t retval;
|
||||
volatile bool inner_called;
|
||||
} setjmp_test_ctx_t;
|
||||
|
||||
static __attribute__((noreturn)) void inner(setjmp_test_ctx_t *ctx)
|
||||
{
|
||||
printf("inner, retval=0x%" PRIx32 "\n", ctx->retval);
|
||||
ctx->inner_called = true;
|
||||
longjmp(ctx->jmp_env, ctx->retval);
|
||||
TEST_FAIL_MESSAGE("Should not reach here");
|
||||
}
|
||||
|
||||
TEST_CASE("setjmp and longjmp", "[newlib]")
|
||||
{
|
||||
const uint32_t expected = 0x12345678;
|
||||
setjmp_test_ctx_t ctx = {
|
||||
.retval = expected
|
||||
};
|
||||
uint32_t ret = setjmp(ctx.jmp_env);
|
||||
if (!ctx.inner_called) {
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
inner(&ctx);
|
||||
} else {
|
||||
TEST_ASSERT_EQUAL(expected, ret);
|
||||
}
|
||||
TEST_ASSERT(ctx.inner_called);
|
||||
}
|
||||
|
||||
@@ -1,462 +1,462 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_attr.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "unity.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define MALLOC_CAP_ATOMIC MALLOC_CAP_DEFAULT
|
||||
|
||||
/* non-static to prevent optimization */
|
||||
atomic_ullong *g_atomic64;
|
||||
atomic_uint *g_atomic32;
|
||||
atomic_ushort *g_atomic16;
|
||||
atomic_uchar *g_atomic8;
|
||||
|
||||
TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned long long x64 = 0;
|
||||
g_atomic64 = heap_caps_calloc(sizeof(*g_atomic64), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x64 += __atomic_fetch_nand_8(g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX64(0x9797979797979797ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0xDDDDDDDDDDDDDDDDULL, *g_atomic64); // calls atomic_load
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX64(0x6464646464646464ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0x3333333333333333ULL, *g_atomic64); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic64);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x32 = 0;
|
||||
g_atomic32 = heap_caps_calloc(sizeof(*g_atomic32), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x32 += __atomic_fetch_nand_4(g_atomic32, 0xAAAAAAAAU, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(0x97979797U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, *g_atomic32);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX32(0x64646464U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0x33333333U, *g_atomic32); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic32);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x16 = 0;
|
||||
g_atomic16 = heap_caps_calloc(sizeof(*g_atomic16), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x16 += __atomic_fetch_nand_2(g_atomic16, 0xAAAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16(0x9797, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0xDDDD, *g_atomic16);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX16(0x6464, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0x3333, *g_atomic16); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic16);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x8 = 0;
|
||||
g_atomic8 = heap_caps_calloc(sizeof(*g_atomic8), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x8 += __atomic_fetch_nand_1(g_atomic8, 0xAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(0x97, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0xDD, *g_atomic8);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX8(0x64, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0x33, *g_atomic8); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic8);
|
||||
}
|
||||
|
||||
#ifndef __clang__
|
||||
TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned long long x64 = 0;
|
||||
g_atomic64 = heap_caps_calloc(sizeof(*g_atomic64), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x64 += __atomic_or_fetch_8(g_atomic64, 0x1111111111111111ULL, 0);
|
||||
x64 += __atomic_xor_fetch_8(g_atomic64, 0x3333333333333333ULL, 0);
|
||||
x64 += __atomic_and_fetch_8(g_atomic64, 0xf0f0f0f0f0f0f0f0ULL, 0);
|
||||
x64 += __atomic_sub_fetch_8(g_atomic64, 0x0f0f0f0f0f0f0f0fULL, 0);
|
||||
x64 += __atomic_add_fetch_8(g_atomic64, 0x2222222222222222ULL, 0);
|
||||
x64 += __atomic_nand_fetch_8(g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX64(0x7575757575757574ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0xDDDDDDDDDDDDDDDDULL, *g_atomic64); // calls atomic_load
|
||||
free(g_atomic64);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x32 = 0;
|
||||
g_atomic32 = heap_caps_calloc(sizeof(*g_atomic32), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x32 += __atomic_or_fetch_4(g_atomic32, 0x11111111U, 0);
|
||||
x32 += __atomic_xor_fetch_4(g_atomic32, 0x33333333U, 0);
|
||||
x32 += __atomic_and_fetch_4(g_atomic32, 0xf0f0f0f0U, 0);
|
||||
x32 += __atomic_sub_fetch_4(g_atomic32, 0x0f0f0f0fU, 0);
|
||||
x32 += __atomic_add_fetch_4(g_atomic32, 0x22222222U, 0);
|
||||
x32 += __atomic_nand_fetch_4(g_atomic32, 0xAAAAAAAAU, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(0x75757574U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, *g_atomic32);
|
||||
free(g_atomic32);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x16 = 0;
|
||||
g_atomic16 = heap_caps_calloc(sizeof(*g_atomic16), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x16 += __atomic_or_fetch_2(g_atomic16, 0x1111, 0);
|
||||
x16 += __atomic_xor_fetch_2(g_atomic16, 0x3333, 0);
|
||||
x16 += __atomic_and_fetch_2(g_atomic16, 0xf0f0, 0);
|
||||
x16 += __atomic_sub_fetch_2(g_atomic16, 0x0f0f, 0);
|
||||
x16 += __atomic_add_fetch_2(g_atomic16, 0x2222, 0);
|
||||
x16 += __atomic_nand_fetch_2(g_atomic16, 0xAAAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16(0x7574, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0xDDDD, *g_atomic16);
|
||||
free(g_atomic16);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x8 = 0;
|
||||
g_atomic8 = heap_caps_calloc(sizeof(*g_atomic8), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x8 += __atomic_or_fetch_1(g_atomic8, 0x11, 0);
|
||||
x8 += __atomic_xor_fetch_1(g_atomic8, 0x33, 0);
|
||||
x8 += __atomic_and_fetch_1(g_atomic8, 0xf0, 0);
|
||||
x8 += __atomic_sub_fetch_1(g_atomic8, 0x0f, 0);
|
||||
x8 += __atomic_add_fetch_1(g_atomic8, 0x22, 0);
|
||||
x8 += __atomic_nand_fetch_1(g_atomic8, 0xAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(0x74, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0xDD, *g_atomic8);
|
||||
free(g_atomic8);
|
||||
}
|
||||
|
||||
#endif // #ifndef __clang__
|
||||
|
||||
#define TEST_EXCLUSION(n, POSTFIX) TEST_CASE("stdatomic - test_" #n #POSTFIX "bit_exclusion", "[newlib_stdatomic]") \
|
||||
{ \
|
||||
g_atomic ## n = heap_caps_calloc(sizeof(*g_atomic ## n), 1, MALLOC_CAP_ATOMIC); \
|
||||
pthread_t thread1; \
|
||||
pthread_t thread2; \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % portNUM_PROCESSORS; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create(&thread1, NULL, exclusion_task_ ##n ##POSTFIX, (void*) 1); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create(&thread2, NULL, exclusion_task_ ##n ##POSTFIX, (void*) 0); \
|
||||
pthread_join(thread1, NULL); \
|
||||
pthread_join(thread2, NULL); \
|
||||
TEST_ASSERT_EQUAL(0, (*g_atomic ## n)); \
|
||||
free(g_atomic ## n); \
|
||||
}
|
||||
|
||||
#define TEST_EXCLUSION_TASK(n, POSTFIX) static void* exclusion_task_ ##n ##POSTFIX(void *varg) \
|
||||
{ \
|
||||
int arg = (int) varg; \
|
||||
for (int i = 0; i < 1000000; ++i) { \
|
||||
if (arg == 0) { \
|
||||
atomic_fetch_add(g_atomic ## n, 1ULL); \
|
||||
} else { \
|
||||
atomic_fetch_sub(g_atomic ## n, 1ULL); \
|
||||
} \
|
||||
} \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
TEST_EXCLUSION_TASK(64, _default_mem)
|
||||
TEST_EXCLUSION(64, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(32, _default_mem)
|
||||
TEST_EXCLUSION(32, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(16, _default_mem)
|
||||
TEST_EXCLUSION(16, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(8, _default_mem)
|
||||
TEST_EXCLUSION(8, _default_mem)
|
||||
|
||||
#define ITER_COUNT 20000
|
||||
|
||||
#define TEST_RACE_OPERATION(ASSERT_SUFFIX, NAME, LHSTYPE, PRE, POST, INIT, FINAL) \
|
||||
\
|
||||
static _Atomic LHSTYPE *var_##NAME; \
|
||||
\
|
||||
static void *test_thread_##NAME (void *arg) \
|
||||
{ \
|
||||
for (int i = 0; i < ITER_COUNT; i++) \
|
||||
{ \
|
||||
PRE (*var_##NAME) POST; \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \
|
||||
{ \
|
||||
pthread_t thread_id1; \
|
||||
pthread_t thread_id2; \
|
||||
var_##NAME = heap_caps_calloc(sizeof(*var_##NAME), 1, MALLOC_CAP_ATOMIC); \
|
||||
*var_##NAME = (INIT); \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % CONFIG_FREERTOS_NUMBER_OF_CORES; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \
|
||||
pthread_join (thread_id1, NULL); \
|
||||
pthread_join (thread_id2, NULL); \
|
||||
TEST_ASSERT_EQUAL##ASSERT_SUFFIX((FINAL), (*var_##NAME)); \
|
||||
free(var_##NAME); \
|
||||
}
|
||||
|
||||
// Note that the assert at the end is doing an excat bitwise comparison.
|
||||
// This easily can fail due to rounding errors. However, there is currently
|
||||
// no corresponding Unity assert macro for long double. USE THIS WITH CARE!
|
||||
#define TEST_RACE_OPERATION_LONG_DOUBLE(NAME, LHSTYPE, PRE, POST, INIT, FINAL) \
|
||||
\
|
||||
static _Atomic LHSTYPE *var_##NAME; \
|
||||
\
|
||||
static void *test_thread_##NAME (void *arg) \
|
||||
{ \
|
||||
for (int i = 0; i < ITER_COUNT; i++) \
|
||||
{ \
|
||||
PRE (*var_##NAME) POST; \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \
|
||||
{ \
|
||||
pthread_t thread_id1; \
|
||||
pthread_t thread_id2; \
|
||||
var_##NAME = heap_caps_calloc(sizeof(*var_##NAME), 1, MALLOC_CAP_ATOMIC); \
|
||||
*var_##NAME = (INIT); \
|
||||
const LHSTYPE EXPECTED = (FINAL); \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % CONFIG_FREERTOS_NUMBER_OF_CORES; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \
|
||||
pthread_join (thread_id1, NULL); \
|
||||
pthread_join (thread_id2, NULL); \
|
||||
TEST_ASSERT(EXPECTED == (*var_##NAME)); \
|
||||
free(var_##NAME); \
|
||||
}
|
||||
|
||||
TEST_RACE_OPERATION(, uint8_add, uint8_t,, += 1, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_add_3, uint8_t,, += 3, 0, (uint8_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postinc, uint8_t,, ++, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_preinc, uint8_t, ++,, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub, uint8_t,, -= 1, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_3, uint8_t,, -= 3, 0, (uint8_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postdec, uint8_t,, --, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_predec, uint8_t, --,, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_mul, uint8_t,, *= 3, 1, (uint8_t) 0x1)
|
||||
|
||||
TEST_RACE_OPERATION(, uint16_add, uint16_t,, += 1, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_add_3, uint16_t,, += 3, 0, (uint16_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postinc, uint16_t,, ++, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_preinc, uint16_t, ++,, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub, uint16_t,, -= 1, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_3, uint16_t,, -= 3, 0, (uint16_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postdec, uint16_t,, --, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_predec, uint16_t, --,, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_mul, uint16_t,, *= 3, 1, (uint16_t) 0x6D01)
|
||||
|
||||
TEST_RACE_OPERATION(, uint32_add, uint32_t,, += 1, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_add_3, uint32_t,, += 3, 0, (uint32_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postinc, uint32_t,, ++, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_preinc, uint32_t, ++,, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub, uint32_t,, -= 1, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_3, uint32_t,, -= 3, 0, (uint32_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postdec, uint32_t,, --, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_predec, uint32_t, --,, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_mul, uint32_t,, *= 3, 1, (uint32_t) 0xC1E36D01U)
|
||||
|
||||
TEST_RACE_OPERATION(, uint64_add, uint64_t,, += 1, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_3, uint64_t,, += 3, 0, (uint64_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_neg, uint64_t,, += 1, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postinc, uint64_t,, ++, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_neg, uint64_t,, ++, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_preinc, uint64_t, ++,, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_neg, uint64_t, ++,, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_sub, uint64_t,, -= 1, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_3, uint64_t,, -= 3, 0, (uint64_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_neg, uint64_t,, -= 1, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postdec, uint64_t,, --, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_neg, uint64_t,, --, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_predec, uint64_t, --,, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_predec_neg, uint64_t, --,, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_mul, uint64_t,, *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL)
|
||||
|
||||
TEST_RACE_OPERATION(_FLOAT, float_add, float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_add, _Complex float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postinc, float,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_preinc, float, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_sub, float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_sub, _Complex float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postdec, float,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_predec, float, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_add, double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_add, _Complex double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postinc, double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_preinc, double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_sub, double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_sub, _Complex double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postdec, double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_predec, double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_add, long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_add, _Complex long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postinc, long double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_sub, long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_preinc, long double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_sub, _Complex long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postdec, long double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_predec, long double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
#if CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND
|
||||
#undef MALLOC_CAP_ATOMIC
|
||||
#define MALLOC_CAP_ATOMIC MALLOC_CAP_SPIRAM
|
||||
|
||||
TEST_EXCLUSION_TASK(64, _ext_mem)
|
||||
TEST_EXCLUSION(64, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(32, _ext_mem)
|
||||
TEST_EXCLUSION(32, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(16, _ext_mem)
|
||||
TEST_EXCLUSION(16, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(8, _ext_mem)
|
||||
TEST_EXCLUSION(8, _ext_mem)
|
||||
|
||||
TEST_RACE_OPERATION(, uint8_add_ext, uint8_t,, += 1, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_add_3_ext, uint8_t,, += 3, 0, (uint8_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postinc_ext, uint8_t,, ++, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_preinc_ext, uint8_t, ++,, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_ext, uint8_t,, -= 1, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_3_ext, uint8_t,, -= 3, 0, (uint8_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postdec_ext, uint8_t,, --, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_predec_ext, uint8_t, --,, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_mul_ext, uint8_t,, *= 3, 1, (uint8_t) 0x1)
|
||||
|
||||
TEST_RACE_OPERATION(, uint16_add_ext, uint16_t,, += 1, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_add_3_ext, uint16_t,, += 3, 0, (uint16_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postinc_ext, uint16_t,, ++, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_preinc_ext, uint16_t, ++,, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_ext, uint16_t,, -= 1, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_3_ext, uint16_t,, -= 3, 0, (uint16_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postdec_ext, uint16_t,, --, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_predec_ext, uint16_t, --,, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_mul_ext, uint16_t,, *= 3, 1, (uint16_t) 0x6D01)
|
||||
|
||||
TEST_RACE_OPERATION(, uint32_add_ext, uint32_t,, += 1, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_add_3_ext, uint32_t,, += 3, 0, (uint32_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postinc_ext, uint32_t,, ++, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_preinc_ext, uint32_t, ++,, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_ext, uint32_t,, -= 1, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_3_ext, uint32_t,, -= 3, 0, (uint32_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postdec_ext, uint32_t,, --, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_predec_ext, uint32_t, --,, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_mul_ext, uint32_t,, *= 3, 1, (uint32_t) 0xC1E36D01U)
|
||||
|
||||
TEST_RACE_OPERATION(, uint64_add_ext, uint64_t,, += 1, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_3_ext, uint64_t,, += 3, 0, (uint64_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_neg_ext, uint64_t,, += 1, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_ext, uint64_t,, ++, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_neg_ext, uint64_t,, ++, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_ext, uint64_t, ++,, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_neg_ext, uint64_t, ++,, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_sub_ext, uint64_t,, -= 1, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_3_ext, uint64_t,, -= 3, 0, (uint64_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_neg_ext, uint64_t,, -= 1, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_ext, uint64_t,, --, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_neg_ext, uint64_t,, --, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_predec_ext, uint64_t, --,, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_predec_neg_ext, uint64_t, --,, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_mul_ext, uint64_t,, *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL)
|
||||
|
||||
TEST_RACE_OPERATION(_FLOAT, float_add_ext, float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_add_ext, _Complex float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postinc_ext, float,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_preinc_ext, float, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_sub_ext, float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_sub_ext, _Complex float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postdec_ext, float,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_predec_ext, float, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_add_ext, double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_add_ext, _Complex double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postinc_ext, double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_preinc_ext, double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_sub_ext, double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_sub_ext, _Complex double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postdec_ext, double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_predec_ext, double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_add_ext, long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_add_ext, _Complex long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postinc_ext, long double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_sub_ext, long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_preinc_ext, long double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_sub_ext, _Complex long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postdec_ext, long double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_predec_ext, long double, --,, 0, -(2 * ITER_COUNT))
|
||||
#endif // CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_attr.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "unity.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define MALLOC_CAP_ATOMIC MALLOC_CAP_DEFAULT
|
||||
|
||||
/* non-static to prevent optimization */
|
||||
atomic_ullong *g_atomic64;
|
||||
atomic_uint *g_atomic32;
|
||||
atomic_ushort *g_atomic16;
|
||||
atomic_uchar *g_atomic8;
|
||||
|
||||
TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned long long x64 = 0;
|
||||
g_atomic64 = heap_caps_calloc(sizeof(*g_atomic64), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x64 += __atomic_fetch_nand_8(g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX64(0x9797979797979797ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0xDDDDDDDDDDDDDDDDULL, *g_atomic64); // calls atomic_load
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX64(0x6464646464646464ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0x3333333333333333ULL, *g_atomic64); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic64);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x32 = 0;
|
||||
g_atomic32 = heap_caps_calloc(sizeof(*g_atomic32), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x32 += __atomic_fetch_nand_4(g_atomic32, 0xAAAAAAAAU, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(0x97979797U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, *g_atomic32);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX32(0x64646464U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0x33333333U, *g_atomic32); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic32);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x16 = 0;
|
||||
g_atomic16 = heap_caps_calloc(sizeof(*g_atomic16), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x16 += __atomic_fetch_nand_2(g_atomic16, 0xAAAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16(0x9797, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0xDDDD, *g_atomic16);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX16(0x6464, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0x3333, *g_atomic16); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic16);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x8 = 0;
|
||||
g_atomic8 = heap_caps_calloc(sizeof(*g_atomic8), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
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);
|
||||
#ifndef __clang__
|
||||
x8 += __atomic_fetch_nand_1(g_atomic8, 0xAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(0x97, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0xDD, *g_atomic8);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL_HEX8(0x64, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0x33, *g_atomic8); // calls atomic_load
|
||||
#endif
|
||||
free(g_atomic8);
|
||||
}
|
||||
|
||||
#ifndef __clang__
|
||||
TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned long long x64 = 0;
|
||||
g_atomic64 = heap_caps_calloc(sizeof(*g_atomic64), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x64 += __atomic_or_fetch_8(g_atomic64, 0x1111111111111111ULL, 0);
|
||||
x64 += __atomic_xor_fetch_8(g_atomic64, 0x3333333333333333ULL, 0);
|
||||
x64 += __atomic_and_fetch_8(g_atomic64, 0xf0f0f0f0f0f0f0f0ULL, 0);
|
||||
x64 += __atomic_sub_fetch_8(g_atomic64, 0x0f0f0f0f0f0f0f0fULL, 0);
|
||||
x64 += __atomic_add_fetch_8(g_atomic64, 0x2222222222222222ULL, 0);
|
||||
x64 += __atomic_nand_fetch_8(g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX64(0x7575757575757574ULL, x64);
|
||||
TEST_ASSERT_EQUAL_HEX64(0xDDDDDDDDDDDDDDDDULL, *g_atomic64); // calls atomic_load
|
||||
free(g_atomic64);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x32 = 0;
|
||||
g_atomic32 = heap_caps_calloc(sizeof(*g_atomic32), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x32 += __atomic_or_fetch_4(g_atomic32, 0x11111111U, 0);
|
||||
x32 += __atomic_xor_fetch_4(g_atomic32, 0x33333333U, 0);
|
||||
x32 += __atomic_and_fetch_4(g_atomic32, 0xf0f0f0f0U, 0);
|
||||
x32 += __atomic_sub_fetch_4(g_atomic32, 0x0f0f0f0fU, 0);
|
||||
x32 += __atomic_add_fetch_4(g_atomic32, 0x22222222U, 0);
|
||||
x32 += __atomic_nand_fetch_4(g_atomic32, 0xAAAAAAAAU, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(0x75757574U, x32);
|
||||
TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, *g_atomic32);
|
||||
free(g_atomic32);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x16 = 0;
|
||||
g_atomic16 = heap_caps_calloc(sizeof(*g_atomic16), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x16 += __atomic_or_fetch_2(g_atomic16, 0x1111, 0);
|
||||
x16 += __atomic_xor_fetch_2(g_atomic16, 0x3333, 0);
|
||||
x16 += __atomic_and_fetch_2(g_atomic16, 0xf0f0, 0);
|
||||
x16 += __atomic_sub_fetch_2(g_atomic16, 0x0f0f, 0);
|
||||
x16 += __atomic_add_fetch_2(g_atomic16, 0x2222, 0);
|
||||
x16 += __atomic_nand_fetch_2(g_atomic16, 0xAAAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16(0x7574, x16);
|
||||
TEST_ASSERT_EQUAL_HEX16(0xDDDD, *g_atomic16);
|
||||
free(g_atomic16);
|
||||
}
|
||||
|
||||
TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]")
|
||||
{
|
||||
unsigned int x8 = 0;
|
||||
g_atomic8 = heap_caps_calloc(sizeof(*g_atomic8), 1, MALLOC_CAP_DEFAULT);
|
||||
|
||||
x8 += __atomic_or_fetch_1(g_atomic8, 0x11, 0);
|
||||
x8 += __atomic_xor_fetch_1(g_atomic8, 0x33, 0);
|
||||
x8 += __atomic_and_fetch_1(g_atomic8, 0xf0, 0);
|
||||
x8 += __atomic_sub_fetch_1(g_atomic8, 0x0f, 0);
|
||||
x8 += __atomic_add_fetch_1(g_atomic8, 0x22, 0);
|
||||
x8 += __atomic_nand_fetch_1(g_atomic8, 0xAA, 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8(0x74, x8);
|
||||
TEST_ASSERT_EQUAL_HEX8(0xDD, *g_atomic8);
|
||||
free(g_atomic8);
|
||||
}
|
||||
|
||||
#endif // #ifndef __clang__
|
||||
|
||||
#define TEST_EXCLUSION(n, POSTFIX) TEST_CASE("stdatomic - test_" #n #POSTFIX "bit_exclusion", "[newlib_stdatomic]") \
|
||||
{ \
|
||||
g_atomic ## n = heap_caps_calloc(sizeof(*g_atomic ## n), 1, MALLOC_CAP_ATOMIC); \
|
||||
pthread_t thread1; \
|
||||
pthread_t thread2; \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % portNUM_PROCESSORS; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create(&thread1, NULL, exclusion_task_ ##n ##POSTFIX, (void*) 1); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create(&thread2, NULL, exclusion_task_ ##n ##POSTFIX, (void*) 0); \
|
||||
pthread_join(thread1, NULL); \
|
||||
pthread_join(thread2, NULL); \
|
||||
TEST_ASSERT_EQUAL(0, (*g_atomic ## n)); \
|
||||
free(g_atomic ## n); \
|
||||
}
|
||||
|
||||
#define TEST_EXCLUSION_TASK(n, POSTFIX) static void* exclusion_task_ ##n ##POSTFIX(void *varg) \
|
||||
{ \
|
||||
int arg = (int) varg; \
|
||||
for (int i = 0; i < 1000000; ++i) { \
|
||||
if (arg == 0) { \
|
||||
atomic_fetch_add(g_atomic ## n, 1ULL); \
|
||||
} else { \
|
||||
atomic_fetch_sub(g_atomic ## n, 1ULL); \
|
||||
} \
|
||||
} \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
TEST_EXCLUSION_TASK(64, _default_mem)
|
||||
TEST_EXCLUSION(64, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(32, _default_mem)
|
||||
TEST_EXCLUSION(32, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(16, _default_mem)
|
||||
TEST_EXCLUSION(16, _default_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(8, _default_mem)
|
||||
TEST_EXCLUSION(8, _default_mem)
|
||||
|
||||
#define ITER_COUNT 20000
|
||||
|
||||
#define TEST_RACE_OPERATION(ASSERT_SUFFIX, NAME, LHSTYPE, PRE, POST, INIT, FINAL) \
|
||||
\
|
||||
static _Atomic LHSTYPE *var_##NAME; \
|
||||
\
|
||||
static void *test_thread_##NAME (void *arg) \
|
||||
{ \
|
||||
for (int i = 0; i < ITER_COUNT; i++) \
|
||||
{ \
|
||||
PRE (*var_##NAME) POST; \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \
|
||||
{ \
|
||||
pthread_t thread_id1; \
|
||||
pthread_t thread_id2; \
|
||||
var_##NAME = heap_caps_calloc(sizeof(*var_##NAME), 1, MALLOC_CAP_ATOMIC); \
|
||||
*var_##NAME = (INIT); \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % CONFIG_FREERTOS_NUMBER_OF_CORES; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \
|
||||
pthread_join (thread_id1, NULL); \
|
||||
pthread_join (thread_id2, NULL); \
|
||||
TEST_ASSERT_EQUAL##ASSERT_SUFFIX((FINAL), (*var_##NAME)); \
|
||||
free(var_##NAME); \
|
||||
}
|
||||
|
||||
// Note that the assert at the end is doing an excat bitwise comparison.
|
||||
// This easily can fail due to rounding errors. However, there is currently
|
||||
// no corresponding Unity assert macro for long double. USE THIS WITH CARE!
|
||||
#define TEST_RACE_OPERATION_LONG_DOUBLE(NAME, LHSTYPE, PRE, POST, INIT, FINAL) \
|
||||
\
|
||||
static _Atomic LHSTYPE *var_##NAME; \
|
||||
\
|
||||
static void *test_thread_##NAME (void *arg) \
|
||||
{ \
|
||||
for (int i = 0; i < ITER_COUNT; i++) \
|
||||
{ \
|
||||
PRE (*var_##NAME) POST; \
|
||||
} \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \
|
||||
{ \
|
||||
pthread_t thread_id1; \
|
||||
pthread_t thread_id2; \
|
||||
var_##NAME = heap_caps_calloc(sizeof(*var_##NAME), 1, MALLOC_CAP_ATOMIC); \
|
||||
*var_##NAME = (INIT); \
|
||||
const LHSTYPE EXPECTED = (FINAL); \
|
||||
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \
|
||||
cfg.pin_to_core = (xPortGetCoreID() + 1) % CONFIG_FREERTOS_NUMBER_OF_CORES; \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \
|
||||
cfg.pin_to_core = xPortGetCoreID(); \
|
||||
esp_pthread_set_cfg(&cfg); \
|
||||
pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \
|
||||
pthread_join (thread_id1, NULL); \
|
||||
pthread_join (thread_id2, NULL); \
|
||||
TEST_ASSERT(EXPECTED == (*var_##NAME)); \
|
||||
free(var_##NAME); \
|
||||
}
|
||||
|
||||
TEST_RACE_OPERATION(, uint8_add, uint8_t,, += 1, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_add_3, uint8_t,, += 3, 0, (uint8_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postinc, uint8_t,, ++, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_preinc, uint8_t, ++,, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub, uint8_t,, -= 1, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_3, uint8_t,, -= 3, 0, (uint8_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postdec, uint8_t,, --, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_predec, uint8_t, --,, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_mul, uint8_t,, *= 3, 1, (uint8_t) 0x1)
|
||||
|
||||
TEST_RACE_OPERATION(, uint16_add, uint16_t,, += 1, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_add_3, uint16_t,, += 3, 0, (uint16_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postinc, uint16_t,, ++, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_preinc, uint16_t, ++,, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub, uint16_t,, -= 1, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_3, uint16_t,, -= 3, 0, (uint16_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postdec, uint16_t,, --, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_predec, uint16_t, --,, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_mul, uint16_t,, *= 3, 1, (uint16_t) 0x6D01)
|
||||
|
||||
TEST_RACE_OPERATION(, uint32_add, uint32_t,, += 1, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_add_3, uint32_t,, += 3, 0, (uint32_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postinc, uint32_t,, ++, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_preinc, uint32_t, ++,, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub, uint32_t,, -= 1, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_3, uint32_t,, -= 3, 0, (uint32_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postdec, uint32_t,, --, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_predec, uint32_t, --,, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_mul, uint32_t,, *= 3, 1, (uint32_t) 0xC1E36D01U)
|
||||
|
||||
TEST_RACE_OPERATION(, uint64_add, uint64_t,, += 1, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_3, uint64_t,, += 3, 0, (uint64_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_neg, uint64_t,, += 1, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postinc, uint64_t,, ++, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_neg, uint64_t,, ++, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_preinc, uint64_t, ++,, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_neg, uint64_t, ++,, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_sub, uint64_t,, -= 1, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_3, uint64_t,, -= 3, 0, (uint64_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_neg, uint64_t,, -= 1, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postdec, uint64_t,, --, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_neg, uint64_t,, --, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_predec, uint64_t, --,, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_predec_neg, uint64_t, --,, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_mul, uint64_t,, *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL)
|
||||
|
||||
TEST_RACE_OPERATION(_FLOAT, float_add, float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_add, _Complex float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postinc, float,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_preinc, float, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_sub, float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_sub, _Complex float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postdec, float,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_predec, float, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_add, double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_add, _Complex double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postinc, double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_preinc, double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_sub, double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_sub, _Complex double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postdec, double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_predec, double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_add, long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_add, _Complex long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postinc, long double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_sub, long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_preinc, long double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_sub, _Complex long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postdec, long double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_predec, long double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
#if CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND
|
||||
#undef MALLOC_CAP_ATOMIC
|
||||
#define MALLOC_CAP_ATOMIC MALLOC_CAP_SPIRAM
|
||||
|
||||
TEST_EXCLUSION_TASK(64, _ext_mem)
|
||||
TEST_EXCLUSION(64, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(32, _ext_mem)
|
||||
TEST_EXCLUSION(32, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(16, _ext_mem)
|
||||
TEST_EXCLUSION(16, _ext_mem)
|
||||
|
||||
TEST_EXCLUSION_TASK(8, _ext_mem)
|
||||
TEST_EXCLUSION(8, _ext_mem)
|
||||
|
||||
TEST_RACE_OPERATION(, uint8_add_ext, uint8_t,, += 1, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_add_3_ext, uint8_t,, += 3, 0, (uint8_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postinc_ext, uint8_t,, ++, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_preinc_ext, uint8_t, ++,, 0, (uint8_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_ext, uint8_t,, -= 1, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_sub_3_ext, uint8_t,, -= 3, 0, (uint8_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_postdec_ext, uint8_t,, --, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_predec_ext, uint8_t, --,, 0, (uint8_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint8_mul_ext, uint8_t,, *= 3, 1, (uint8_t) 0x1)
|
||||
|
||||
TEST_RACE_OPERATION(, uint16_add_ext, uint16_t,, += 1, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_add_3_ext, uint16_t,, += 3, 0, (uint16_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postinc_ext, uint16_t,, ++, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_preinc_ext, uint16_t, ++,, 0, (uint16_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_ext, uint16_t,, -= 1, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_sub_3_ext, uint16_t,, -= 3, 0, (uint16_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_postdec_ext, uint16_t,, --, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_predec_ext, uint16_t, --,, 0, (uint16_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint16_mul_ext, uint16_t,, *= 3, 1, (uint16_t) 0x6D01)
|
||||
|
||||
TEST_RACE_OPERATION(, uint32_add_ext, uint32_t,, += 1, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_add_3_ext, uint32_t,, += 3, 0, (uint32_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postinc_ext, uint32_t,, ++, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_preinc_ext, uint32_t, ++,, 0, (uint32_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_ext, uint32_t,, -= 1, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_sub_3_ext, uint32_t,, -= 3, 0, (uint32_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_postdec_ext, uint32_t,, --, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_predec_ext, uint32_t, --,, 0, (uint32_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint32_mul_ext, uint32_t,, *= 3, 1, (uint32_t) 0xC1E36D01U)
|
||||
|
||||
TEST_RACE_OPERATION(, uint64_add_ext, uint64_t,, += 1, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_3_ext, uint64_t,, += 3, 0, (uint64_t)(6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_add_neg_ext, uint64_t,, += 1, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_ext, uint64_t,, ++, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postinc_neg_ext, uint64_t,, ++, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_ext, uint64_t, ++,, 0, (uint64_t)(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_preinc_neg_ext, uint64_t, ++,, -10000, (uint64_t)(2 * ITER_COUNT - 10000))
|
||||
TEST_RACE_OPERATION(, uint64_sub_ext, uint64_t,, -= 1, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_3_ext, uint64_t,, -= 3, 0, (uint64_t) - (6 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_sub_neg_ext, uint64_t,, -= 1, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_ext, uint64_t,, --, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_postdec_neg_ext, uint64_t,, --, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_predec_ext, uint64_t, --,, 0, (uint64_t) - (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(, uint64_predec_neg_ext, uint64_t, --,, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000))
|
||||
TEST_RACE_OPERATION(, uint64_mul_ext, uint64_t,, *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL)
|
||||
|
||||
TEST_RACE_OPERATION(_FLOAT, float_add_ext, float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_add_ext, _Complex float,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postinc_ext, float,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_preinc_ext, float, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_sub_ext, float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, complex_float_sub_ext, _Complex float,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_postdec_ext, float,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_FLOAT, float_predec_ext, float, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_add_ext, double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_add_ext, _Complex double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postinc_ext, double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_preinc_ext, double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_sub_ext, double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, complex_double_sub_ext, _Complex double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_postdec_ext, double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION(_DOUBLE, double_predec_ext, double, --,, 0, -(2 * ITER_COUNT))
|
||||
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_add_ext, long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_add_ext, _Complex long double,, += 1, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postinc_ext, long double,, ++, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_sub_ext, long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_preinc_ext, long double, ++,, 0, (2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_sub_ext, _Complex long double,, -= 1, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postdec_ext, long double,, --, 0, -(2 * ITER_COUNT))
|
||||
TEST_RACE_OPERATION_LONG_DOUBLE(long_double_predec_ext, long double, --,, 0, -(2 * ITER_COUNT))
|
||||
#endif // CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,48 +1,48 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import subprocess
|
||||
from os import path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def validate_sbom(dut: Dut) -> None:
|
||||
dirname = path.dirname(path.abspath(__file__))
|
||||
sbom_file = path.join(path.dirname(path.dirname(dirname)), 'sbom.yml')
|
||||
gcc_input_file = path.join(dirname, 'test_sbom', 'newlib_version.c')
|
||||
gcc = 'riscv32-esp-elf-gcc'
|
||||
if dut.target in dut.XTENSA_TARGETS:
|
||||
gcc = f'xtensa-{dut.target}-elf-gcc'
|
||||
gcc_process = subprocess.run(f'{gcc} -E {gcc_input_file}',
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True)
|
||||
output_lines = gcc_process.stdout.splitlines()
|
||||
assert output_lines, 'Can not get newlib version'
|
||||
toolchain_newlib_version = output_lines[-1].replace(' ', '.')
|
||||
with open(sbom_file, 'r', encoding='utf-8') as yaml_file:
|
||||
sbom_newlib_version = yaml.safe_load(yaml_file).get('version')
|
||||
assert sbom_newlib_version, 'Can not get newlib version from sbom.yml'
|
||||
assert toolchain_newlib_version == sbom_newlib_version, 'toolchain_newlib_version != sbom_newlib_version'
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
pytest.param('default', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('options', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('single_core_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('psram_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('release_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('release_esp32c2', marks=[pytest.mark.esp32c2]),
|
||||
],
|
||||
indirect=True
|
||||
)
|
||||
def test_newlib(dut: Dut) -> None:
|
||||
validate_sbom(dut)
|
||||
dut.run_all_single_board_cases()
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import subprocess
|
||||
from os import path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def validate_sbom(dut: Dut) -> None:
|
||||
dirname = path.dirname(path.abspath(__file__))
|
||||
sbom_file = path.join(path.dirname(path.dirname(dirname)), 'sbom.yml')
|
||||
gcc_input_file = path.join(dirname, 'test_sbom', 'newlib_version.c')
|
||||
gcc = 'riscv32-esp-elf-gcc'
|
||||
if dut.target in dut.XTENSA_TARGETS:
|
||||
gcc = f'xtensa-{dut.target}-elf-gcc'
|
||||
gcc_process = subprocess.run(f'{gcc} -E {gcc_input_file}',
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True)
|
||||
output_lines = gcc_process.stdout.splitlines()
|
||||
assert output_lines, 'Can not get newlib version'
|
||||
toolchain_newlib_version = output_lines[-1].replace(' ', '.')
|
||||
with open(sbom_file, 'r', encoding='utf-8') as yaml_file:
|
||||
sbom_newlib_version = yaml.safe_load(yaml_file).get('version')
|
||||
assert sbom_newlib_version, 'Can not get newlib version from sbom.yml'
|
||||
assert toolchain_newlib_version == sbom_newlib_version, 'toolchain_newlib_version != sbom_newlib_version'
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
pytest.param('default', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('options', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('single_core_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('psram_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('release_esp32', marks=[pytest.mark.esp32]),
|
||||
pytest.param('release_esp32c2', marks=[pytest.mark.esp32c2]),
|
||||
],
|
||||
indirect=True
|
||||
)
|
||||
def test_newlib(dut: Dut) -> None:
|
||||
validate_sbom(dut)
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# Test all chips with nano off, nano on is tested in options config
|
||||
CONFIG_NEWLIB_NANO_FORMAT=n
|
||||
# Test all chips with nano off, nano on is tested in options config
|
||||
CONFIG_NEWLIB_NANO_FORMAT=n
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# Test with misc newlib config options turned on
|
||||
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||
# Test with misc newlib config options turned on
|
||||
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_SPIRAM=y
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
CONFIG_IDF_TARGET="esp32c2"
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
||||
# C2 specific moved from old C2 default config
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE=n
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT=y
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC=n
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=n
|
||||
CONFIG_IDF_TARGET="esp32c2"
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
||||
# C2 specific moved from old C2 default config
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE=n
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT=y
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC=n
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=n
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_FREERTOS_UNICORE=y
|
||||
# IDF-6964 test nano format in this configuration (current tests are not passing, so keep disabled for now)
|
||||
CONFIG_NEWLIB_NANO_FORMAT=n
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_FREERTOS_UNICORE=y
|
||||
# IDF-6964 test nano format in this configuration (current tests are not passing, so keep disabled for now)
|
||||
CONFIG_NEWLIB_NANO_FORMAT=n
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# certain 64-bit related asserts need this option to be enabled in unity in order to work correctly
|
||||
CONFIG_UNITY_ENABLE_64BIT=y
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y
|
||||
CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y
|
||||
# certain 64-bit related asserts need this option to be enabled in unity in order to work correctly
|
||||
CONFIG_UNITY_ENABLE_64BIT=y
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y
|
||||
CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <_newlib_version.h>
|
||||
__NEWLIB__ __NEWLIB_MINOR__ __NEWLIB_PATCHLEVEL__
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <_newlib_version.h>
|
||||
__NEWLIB__ __NEWLIB_MINOR__ __NEWLIB_PATCHLEVEL__
|
||||
|
||||
Reference in New Issue
Block a user