Skip to content

Instantly share code, notes, and snippets.

@sssgun
Created March 29, 2018 07:05
Show Gist options
  • Save sssgun/f8047b3de1ced38e6829fe0f6826fbc7 to your computer and use it in GitHub Desktop.
Save sssgun/f8047b3de1ced38e6829fe0f6826fbc7 to your computer and use it in GitHub Desktop.
futex test
#ifdef __cplusplus
extern "C" {
#endif
struct simplefu_semaphore {
int avail;
int waiters;
};
typedef struct simplefu_semaphore *simplefu;
void simplefu_down(simplefu who);
void simplefu_up(simplefu who);
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <assert.h>
#include "simple_futex.h"
int main()
{
int lockfile = open("ipc_lock", O_RDWR);
assert(lockfile != -1);
simplefu sema = mmap(NULL, sizeof(*sema), PROT_READ|PROT_WRITE,
MAP_SHARED, lockfile, 0);
assert(sema != MAP_FAILED);
int pid = fork();
assert(pid != -1);
if( pid == 0 ) { // child
printf("Initializing...\n");
sleep(10);
printf("Done initializing\n");
simplefu_up(sema);
exit(0);
}
sleep(15);
printf("Waiting for child...\n");
simplefu_down(sema);
printf("Child done initializing\n");
return 0;
}
#include "simple_futex.h"
#include <linux/futex.h>
#include <sys/syscall.h>
void simplefu_down(simplefu who)
{
int val;
do {
val = who->avail;
if( val > 0 && __sync_bool_compare_and_swap(&who->avail, val, val - 1) )
return;
__sync_fetch_and_add(&who->waiters, 1);
syscall(__NR_futex, &who->avail, FUTEX_WAIT, val, NULL, 0, 0);
__sync_fetch_and_sub(&who->waiters, 1);
} while(1);
}
void simplefu_up(simplefu who)
{
int nval = __sync_add_and_fetch(&who->avail, 1);
if( who->waiters > 0 )
{
syscall(__NR_futex, &who->avail, FUTEX_WAKE, nval, NULL, 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment