Created
March 29, 2018 07:05
-
-
Save sssgun/f8047b3de1ced38e6829fe0f6826fbc7 to your computer and use it in GitHub Desktop.
futex test
This file contains hidden or 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
| #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 |
This file contains hidden or 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 <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; | |
| } |
This file contains hidden or 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 "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