mirror of
https://github.com/upx/upx.git
synced 2025-08-11 22:52:30 +08:00
src: restrict upx::atomic_exchange to pointer-size for now
This commit is contained in:
@ -1,14 +1,22 @@
|
||||
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// check ABI - require proper alignment of fundamental types for use in atomics
|
||||
static_assert(alignof(char) == sizeof(char), "");
|
||||
static_assert(alignof(signed char) == sizeof(signed char), "");
|
||||
static_assert(alignof(unsigned char) == sizeof(unsigned char), "");
|
||||
static_assert(alignof(short) == sizeof(short), "");
|
||||
static_assert(alignof(unsigned short) == sizeof(unsigned short), "");
|
||||
static_assert(alignof(int) == sizeof(int), "");
|
||||
static_assert(alignof(unsigned int) == sizeof(unsigned int), "");
|
||||
static_assert(alignof(long) == sizeof(long), "");
|
||||
static_assert(alignof(unsigned long) == sizeof(unsigned long), "");
|
||||
static_assert(alignof(ptrdiff_t) == sizeof(ptrdiff_t), "");
|
||||
static_assert(alignof(size_t) == sizeof(size_t), "");
|
||||
static_assert(alignof(intptr_t) == sizeof(intptr_t), "");
|
||||
static_assert(alignof(uintptr_t) == sizeof(uintptr_t), "");
|
||||
static_assert(alignof(void *) == sizeof(void *), "");
|
||||
|
||||
int main() { return 0; }
|
||||
|
@ -252,48 +252,31 @@ struct Z2_X2 : public X2 {
|
||||
|
||||
#if WITH_THREADS
|
||||
TEST_CASE("upx::ptr_std_atomic_cast") {
|
||||
(void) upx::ptr_std_atomic_cast((upx_int8_t *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((upx_int16_t *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((upx_int32_t *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((int *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((long *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((size_t *) nullptr);
|
||||
(void) upx::ptr_std_atomic_cast((void **) nullptr);
|
||||
// pointer-size
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((void **) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((uintptr_t *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((upx_uintptr_t *) nullptr), nullptr);
|
||||
#if 1
|
||||
// more fundamental types
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((char *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((short *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((int *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((long *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((size_t *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int8_t *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int16_t *) nullptr), nullptr);
|
||||
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int32_t *) nullptr), nullptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("upx::atomic_exchange") {
|
||||
#if defined(__riscv)
|
||||
// RISC-V has no support for subword atomic operations and needs libatomic to emulate
|
||||
#else
|
||||
{
|
||||
upx_int8_t x = -1;
|
||||
upx_int8_t y = upx::atomic_exchange(&x, (upx_int8_t) 2);
|
||||
upx_uintptr_t x = (upx_uintptr_t) 0 - 1;
|
||||
upx_uintptr_t y = upx::atomic_exchange(&x, (upx_uintptr_t) 2);
|
||||
CHECK_EQ(x, 2);
|
||||
CHECK_EQ(y, -1);
|
||||
UNUSED(y);
|
||||
}
|
||||
{
|
||||
upx_int16_t x = -1;
|
||||
upx_int16_t y = upx::atomic_exchange(&x, (upx_int16_t) 2);
|
||||
CHECK_EQ(x, 2);
|
||||
CHECK_EQ(y, -1);
|
||||
UNUSED(y);
|
||||
}
|
||||
{
|
||||
upx_int32_t x = -1;
|
||||
upx_int32_t y = upx::atomic_exchange(&x, (upx_int32_t) 2);
|
||||
CHECK_EQ(x, 2);
|
||||
CHECK_EQ(y, -1);
|
||||
UNUSED(y);
|
||||
}
|
||||
#endif // __riscv
|
||||
{
|
||||
size_t x = (size_t) 0 - 1;
|
||||
size_t y = upx::atomic_exchange(&x, (size_t) 2);
|
||||
CHECK_EQ(x, 2);
|
||||
CHECK_EQ(y, (size_t) 0 - 1);
|
||||
CHECK_EQ(y, (upx_uintptr_t) 0 - 1);
|
||||
UNUSED(y);
|
||||
}
|
||||
{
|
||||
|
@ -204,6 +204,9 @@ forceinline std::atomic<T> *ptr_std_atomic_cast(T *ptr) noexcept {
|
||||
// atomic_exchange
|
||||
template <class T>
|
||||
forceinline T atomic_exchange(T *ptr, T new_value) noexcept {
|
||||
#if 1
|
||||
static_assert(sizeof(T) == sizeof(void *)); // UPX convention: restrict to pointer-size for now
|
||||
#endif
|
||||
static_assert(std::is_standard_layout_v<T>);
|
||||
static_assert(std::is_trivially_copyable_v<T>);
|
||||
#if !(WITH_THREADS)
|
||||
|
Reference in New Issue
Block a user