Skip to content

Instantly share code, notes, and snippets.

@comex
Created August 28, 2019 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save comex/4bdb6c40bd31cea52f860b3bb057f0d2 to your computer and use it in GitHub Desktop.
Save comex/4bdb6c40bd31cea52f860b3bb057f0d2 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
#include "librace.h"
#include "model-assert.h"
std::atomic_int x;
std::atomic_int side_channel;
std::atomic_int tests_synchronization;
static void a(void *obj)
{
tests_synchronization.store(10, memory_order_relaxed);
x.store(1, memory_order_release);
}
static void b(void *obj)
{
int r_sc = side_channel.load(memory_order_acquire);
// Unused relaxed load that we want to remove:
x.load(memory_order_relaxed);
// ...but might pair with this fence:
atomic_thread_fence(memory_order_acquire);
// We only care about the case where r_sc == 1, implying that thread C's
// load of x both observed the write from thread A and happened-before our
// fence.
if (r_sc == 1) {
// Test whether thread A synchronized-with us. If it did, we must load 10:
int r_ts = tests_synchronization.load(memory_order_relaxed);
MODEL_ASSERT(r_ts == 10);
printf("r_ts=%d\n", r_ts);
}
printf("r_sc=%d\n", r_sc);
}
static void c(void *obj)
{
int r_x = x.load(memory_order_relaxed);
side_channel.store(r_x, memory_order_release);
printf("r_x=%d\n", r_x);
}
int user_main(int argc, char **argv)
{
thrd_t t1, t2, t3;
x = 0;
side_channel = 0;
tests_synchronization = 0;
printf("Main thread: creating 3 threads\n");
thrd_create(&t1, (thrd_start_t)&a, NULL);
thrd_create(&t2, (thrd_start_t)&b, NULL);
thrd_create(&t3, (thrd_start_t)&c, NULL);
thrd_join(t1);
thrd_join(t2);
thrd_join(t3);
printf("Main thread is finished\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment