Skip to content

Instantly share code, notes, and snippets.

@JackyYin
Last active September 24, 2021 08:00
Show Gist options
  • Save JackyYin/942a74f0646f5871fbbaa9c2a51e9aa4 to your computer and use it in GitHub Desktop.
Save JackyYin/942a74f0646f5871fbbaa9c2a51e9aa4 to your computer and use it in GitHub Desktop.
A simple program using futex to mimic mutex, but much slower than mutex
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdatomic.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <linux/futex.h>
#include <sys/syscall.h>
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
static int sum = 0;
static uint32_t futex_var = 1;
const static uint32_t off = 0;
const static uint32_t on = 1;
static void futex_lock(uint32_t *futexp)
{
long s;
while (1) {
if (__sync_bool_compare_and_swap(futexp, on, off))
break;
s = syscall(SYS_futex, futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
if (unlikely(s == -1 && errno != EAGAIN)) {
printf("unexpected error...\n");
pthread_exit(NULL);
}
}
}
static void futex_unlock(uint32_t *futexp)
{
long s;
while (1) {
if (__sync_bool_compare_and_swap(futexp, off, on)) {
// wakeup 1 thread now
s= syscall(SYS_futex, futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
if (unlikely(s == -1)) {
printf("unexpected error...\n");
pthread_exit(NULL);
}
break;
}
}
}
static void* routine(void *arg)
{
printf("start routine...\n");
for (int i = 0; i < 1000000; i++) {
futex_lock(&futex_var);
sum++;
futex_unlock(&futex_var);
}
return NULL;
}
int main ()
{
long nthreads = sysconf(_SC_NPROCESSORS_ONLN);
printf("number of threads: %ld\n", nthreads);
pthread_t threads[nthreads];
for (int i = 0; i < nthreads; i++) {
if (pthread_create(&threads[i], NULL, &routine, NULL)) {
printf("%s\n", strerror(errno));
exit(-1);
}
}
for (int i = 0; i < nthreads; i++) {
pthread_join(threads[i], NULL);
}
printf("%d\n", sum);
}
@JackyYin
Copy link
Author

JackyYin commented Sep 24, 2021

All testing under 2 threads:

futex:

real	0m0.663s
user	0m0.277s
sys	0m0.876s

mutex:

real	0m0.149s
user	0m0.161s
sys	0m0.085s

atomic:

real	0m0.034s
user	0m0.026s
sys	0m0.001s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment