Created
August 17, 2017 08:01
-
-
Save sinelaw/1230d4675d6a4fff394110f17e463954 to your computer and use it in GitHub Desktop.
testing <stdatomic.h> on Intel cross-cacheline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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