core: Fix undefined behaviour in C11 atomics
Casting pointers to volatile memory to pointers to regular memory is permitted, but using those pointers to access the memory results in undefined behavior. This commit changes the casts to no longer drop the volatile qualifier. References: https://en.cppreference.com/w/c/language/volatile
This commit is contained in:
parent
bf000a1fa5
commit
7749e621b8
@ -64,11 +64,11 @@ typedef uint64_t I8;
|
|||||||
#define TEMPLATE_ATOMIC_LOAD_N(n) \
|
#define TEMPLATE_ATOMIC_LOAD_N(n) \
|
||||||
I##n __atomic_load_##n (const volatile void *ptr, int memorder) \
|
I##n __atomic_load_##n (const volatile void *ptr, int memorder) \
|
||||||
{ \
|
{ \
|
||||||
(void) memorder; \
|
(void) memorder; \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
I##n old = *(I##n *)ptr; \
|
I##n old = *(const volatile I##n *)ptr; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return old; \
|
return old; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +81,7 @@ typedef uint64_t I8;
|
|||||||
{ \
|
{ \
|
||||||
(void) memorder; \
|
(void) memorder; \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
*(I##n *)ptr = val; \
|
*(volatile I##n *)ptr = val; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +95,8 @@ typedef uint64_t I8;
|
|||||||
{ \
|
{ \
|
||||||
(void) memorder; \
|
(void) memorder; \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
I##n old = *(I##n *)ptr; \
|
I##n old = *(volatile I##n *)ptr; \
|
||||||
*(I##n *)ptr = desired; \
|
*(volatile I##n *)ptr = desired; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return old; \
|
return old; \
|
||||||
}
|
}
|
||||||
@ -114,14 +114,14 @@ typedef uint64_t I8;
|
|||||||
(void) success_memorder; \
|
(void) success_memorder; \
|
||||||
(void) failure_memorder; \
|
(void) failure_memorder; \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
I##n cur = *(I##n *)ptr; \
|
I##n cur = *(volatile I##n *)ptr; \
|
||||||
if (cur != *(I##n *)expected) { \
|
if (cur != *(I##n *)expected) { \
|
||||||
*(I##n *)expected = cur; \
|
*(I##n *)expected = cur; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
*(I##n *)ptr = desired; \
|
*(volatile I##n *)ptr = desired; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return true; \
|
return true; \
|
||||||
}
|
}
|
||||||
@ -137,12 +137,12 @@ typedef uint64_t I8;
|
|||||||
#define TEMPLATE_ATOMIC_FETCH_OP_N(opname, op, n, prefixop) \
|
#define TEMPLATE_ATOMIC_FETCH_OP_N(opname, op, n, prefixop) \
|
||||||
I##n __atomic_fetch_##opname##_##n(volatile void *ptr, I##n val, int memmodel) \
|
I##n __atomic_fetch_##opname##_##n(volatile void *ptr, I##n val, int memmodel) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
(void)memmodel; \
|
(void)memmodel; \
|
||||||
I##n tmp = *(I##n *)ptr; \
|
I##n tmp = *(volatile I##n *)ptr; \
|
||||||
*(I##n *)ptr = prefixop(tmp op val); \
|
*(volatile I##n *)ptr = prefixop(tmp op val); \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return tmp; \
|
return tmp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,12 +156,12 @@ typedef uint64_t I8;
|
|||||||
#define TEMPLATE_ATOMIC_OP_FETCH_N(opname, op, n, prefixop) \
|
#define TEMPLATE_ATOMIC_OP_FETCH_N(opname, op, n, prefixop) \
|
||||||
I##n __atomic_##opname##_fetch_##n(volatile void *ptr, I##n val, int memmodel) \
|
I##n __atomic_##opname##_fetch_##n(volatile void *ptr, I##n val, int memmodel) \
|
||||||
{ \
|
{ \
|
||||||
(void)memmodel; \
|
(void)memmodel; \
|
||||||
unsigned int mask = irq_disable(); \
|
unsigned int mask = irq_disable(); \
|
||||||
I##n tmp = prefixop((*(I##n *)ptr) op val); \
|
I##n tmp = prefixop((*(volatile I##n *)ptr) op val); \
|
||||||
*(I##n *)ptr = tmp; \
|
*(volatile I##n *)ptr = tmp; \
|
||||||
irq_restore(mask); \
|
irq_restore(mask); \
|
||||||
return tmp; \
|
return tmp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Template instantiations below */
|
/* Template instantiations below */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user