Skip to content

Instantly share code, notes, and snippets.

@sinelaw sinelaw/atomic.c
Created Aug 17, 2017

Embed
What would you like to do?
testing <stdatomic.h> on Intel cross-cacheline
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdatomic.h>
#define CACHELINE__BYTECOUNT (64)
struct Data {
uint8_t bytes[CACHELINE__BYTECOUNT - 4];
atomic_uint_fast64_t u64;
} __attribute__((packed)) __attribute__((aligned ((CACHELINE__BYTECOUNT))));
#define VAL1 (0x1111111111111111)
#define VAL2 (0xFFFFFFFFFFFFFFFF)
static struct Data data = { .u64 = VAL1 };
static void *test_writer(void *unused)
{
(void)unused;
for (uint32_t i = 0; i < 10000; i++) {
for (uint32_t j = 0; j < 1000; j++) {
atomic_store(&data.u64, VAL1);
atomic_store(&data.u64, VAL2);
}
const uint64_t val = atomic_load(&data.u64);
if ((val != VAL1) && (val != VAL2)) {
fprintf(stderr, "ERROR: oh no, got: %lX\n", val);
exit(1);
}
}
return NULL;
}
#define NUM_THREADS 4
int main(void)
{
pthread_attr_t attr;
{
const int res = pthread_attr_init(&attr);
if (res != 0) {
fprintf(stderr, "ERROR: pthread_attr_init error: %d\n", res);
exit(1);
}
}
struct {
char stack[0x10000];
pthread_t thread;
} threads[NUM_THREADS];
for (uint32_t i = 0; i < NUM_THREADS; i++) {
const int create_res = pthread_create(&threads[i].thread, &attr, test_writer, NULL);
if (create_res != 0) {
fprintf(stderr, "ERROR: pthread_create error: %d\n", create_res);
exit(1);
}
}
{
const int res = pthread_attr_destroy(&attr);
if (res != 0) {
fprintf(stderr, "ERROR: pthread_attr_destroy error: %d\n", res);
exit(1);
}
}
for (uint32_t i = 0; i < NUM_THREADS; i++) {
void *res;
const int join_res = pthread_join(threads[i].thread, &res);
if (join_res != 0) {
fprintf(stderr, "ERROR: pthread_join error: %d\n", join_res);
exit(1);
}
}
printf("SUCCESS\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.