Skip to content

Instantly share code, notes, and snippets.

@koba-e964
Last active October 8, 2019 17:28
Show Gist options
  • Save koba-e964/b438cd3b6b18e35a0dc2588b2cf9d0a3 to your computer and use it in GitHub Desktop.
Save koba-e964/b438cd3b6b18e35a0dc2588b2cf9d0a3 to your computer and use it in GitHub Desktop.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <atomic>
// Modification of https://yamasa.hatenablog.jp/entry/20101016/1287227939
static volatile int flag0 __attribute__((aligned(64)));
static volatile int flag1 __attribute__((aligned(64)));
static volatile int turn __attribute__((aligned(64)));
static void
lock(volatile int *my_flag, volatile int *other_flag, int other_id)
{
*my_flag = 1;
turn = other_id;
asm volatile ("mfence" : : : "memory");
while (*other_flag && turn == other_id) {
}
}
static void
unlock(volatile int *my_flag)
{
*my_flag = 0;
}
#define LOOP_COUNT 100000000
static int counter = 0;
static void*
task0(void *arg)
{
int i;
for (i = LOOP_COUNT; i != 0; i--) {
lock(&flag0, &flag1, 1);
counter++;
unlock(&flag0);
}
return NULL;
}
static void*
task1(void *arg)
{
int i;
for (i = LOOP_COUNT; i != 0; i--) {
lock(&flag1, &flag0, 0);
counter++;
unlock(&flag1);
}
return NULL;
}
int
main(int argc, char *argv[])
{
flag0 = 0;
flag1 = 0;
pthread_t t0, t1;
if (pthread_create(&t0, NULL, task0, NULL) ||
pthread_create(&t1, NULL, task1, NULL)) {
fprintf(stderr, "pthread_create\n");
exit(1);
}
if (pthread_join(t0, NULL) ||
pthread_join(t1, NULL)) {
fprintf(stderr, "pthread_join\n");
exit(1);
}
printf("counter = %d\n", counter);
printf("difference = %d\n", LOOP_COUNT * 2 - counter);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment