Demonstrates torn loads for misaligned atomics
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdatomic.h> | |
#include <limits.h> | |
#include <pthread.h> | |
/* | |
* Intel® 64 and IA-32 Architectures Software Developer’s Manual | |
* | |
* Volume 3A - 8.1.1 Guaranteed Atomic Operations | |
* | |
* Accesses to cacheable memory that are split across cache lines and | |
* page boundaries are not guaranteed to be atomic by the Intel Core 2 Duo, | |
* Intel® Atom™, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, | |
* Pentium, and Intel486 processors | |
*/ | |
typedef struct { atomic_long ub; } misaligned_atomic; | |
void* detect_misaligned_atomic_torn_load(void *arg) | |
{ | |
misaligned_atomic *p = arg; | |
long c1 = 0, c2 = 0; | |
for (;;) { | |
/* relaxed "atomic" load */ | |
long val = atomic_load(&p->ub); | |
if (val == 0) c1++; | |
else if (val == -1) c2++; | |
else { | |
printf("0x%016lx : %ld\n0x%016lx : %ld\n0x%016lx : %ld\n", | |
0UL, c1, -1UL, c2, val, 1L); | |
exit(1); | |
} | |
} | |
return NULL; | |
} | |
int main() | |
{ | |
int ret; | |
pthread_t thr; | |
long m = (long)malloc(128); | |
/* arrange for our "atomic" to straddle a cache line */ | |
misaligned_atomic *p = (void*)(((m + 64) & ~63) - (sizeof(atomic_ulong)/2)); | |
atomic_store(&p->ub, 0); | |
if (pthread_create(&thr, NULL, detect_misaligned_atomic_torn_load, p) < 0) { | |
perror("pthread_create"); | |
exit(1); | |
} | |
for (;;) { | |
atomic_fetch_add_explicit(&p->ub, -1, memory_order_relaxed); | |
atomic_fetch_add_explicit(&p->ub, 1, memory_order_relaxed); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment