mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 23:54:16 +08:00
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
workflows/build.yml: - win32/64: install mingw32/64 gcc on msys (because the default gcc installed elsewhere seems to use ucrt, producing incompatible fp printf formats.) tccgen.c: - cleanup funcs: save any lvalues from return expressions. Also use get_temp_local_var() which however was causing a problem on i386 because its gfunc_call() removes the arguments from vstack and by that defeats the 'in-use' tracking of get_temp_local_var(). Fixed by: i386/arm/arm64/x86_64-gen.c: - in gfunc_call(): save_regs before anything else, fixes problems seen in arm64/i386 tccpp.c: - allow arm asm specific use of '#' in macros libtcc.c: - organize -M options, and: tccpe.c: - move the subsystem option parsing from libtcc.c tccelf.c: - improved error handling in tcc_load_ldscript() lib/atomic.S: - TCC_TARGET_... not defined when building the lib - endbrNN security feature not supported by TCC tests/tests2/136_atomic_gcc_style.c: - never use standard assert() in tests
79 lines
2.3 KiB
C
79 lines
2.3 KiB
C
#include <stdatomic.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
|
|
// standard assert would popup a dialog box on windows
|
|
#define assert(x) \
|
|
printf("assert \"%s\" : %s\n", #x, (x) ? "yes" : "no");
|
|
|
|
int main() {
|
|
// Test 1: Basic functionality of __atomic_store_n and __atomic_load_n
|
|
{
|
|
int atomic_var = 0;
|
|
__atomic_store_n(&atomic_var, 42, __ATOMIC_SEQ_CST);
|
|
int loaded = __atomic_load_n(&atomic_var, __ATOMIC_SEQ_CST);
|
|
assert(loaded == 42);
|
|
}
|
|
|
|
// Test 2: Successful exchange with __atomic_compare_exchange_n
|
|
{
|
|
int atomic_var = 100;
|
|
int expected = 100;
|
|
bool success = __atomic_compare_exchange_n(
|
|
&atomic_var, &expected, 200,
|
|
false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST
|
|
);
|
|
assert(success);
|
|
assert(atomic_var == 200);
|
|
assert(expected == 100); // expected remains unchanged on success
|
|
}
|
|
|
|
// Test 3: Failed exchange with __atomic_compare_exchange_n (update expected)
|
|
{
|
|
int atomic_var = 100;
|
|
int expected = 99;
|
|
bool success = __atomic_compare_exchange_n(
|
|
&atomic_var, &expected, 200,
|
|
false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST
|
|
);
|
|
assert(!success);
|
|
assert(atomic_var == 100);
|
|
assert(expected == 100); // expected updated to current value on failure
|
|
}
|
|
|
|
// Test 4: Weak version (spurious failure handling)
|
|
{
|
|
int atomic_var = 50;
|
|
int expected = 50;
|
|
for (int i = 0; i < 10; i++) {
|
|
if (__atomic_compare_exchange_n(
|
|
&atomic_var, &expected, 60,
|
|
true, __ATOMIC_RELAXED, __ATOMIC_RELAXED
|
|
)) {
|
|
break;
|
|
}
|
|
}
|
|
assert(atomic_var == 60);
|
|
}
|
|
|
|
// Test 5: Pointer type operations
|
|
{
|
|
int value = 100;
|
|
int* atomic_ptr = &value;
|
|
int* new_ptr = NULL;
|
|
__atomic_store_n(&atomic_ptr, new_ptr, __ATOMIC_RELEASE);
|
|
int* loaded_ptr = __atomic_load_n(&atomic_ptr, __ATOMIC_ACQUIRE);
|
|
assert(loaded_ptr == NULL);
|
|
}
|
|
|
|
// Test 6: Relaxed memory ordering
|
|
{
|
|
int atomic_var = 0;
|
|
__atomic_store_n(&atomic_var, 10, __ATOMIC_RELAXED);
|
|
assert(__atomic_load_n(&atomic_var, __ATOMIC_RELAXED) == 10);
|
|
}
|
|
|
|
printf("All atomic tests passed!\n");
|
|
return 0;
|
|
}
|