Created
June 15, 2022 13:13
-
-
Save chris-se/949e5ccc9dd38b78f11f924d6ab60749 to your computer and use it in GitHub Desktop.
This file contains 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 <stdlib.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#include <pthread.h> | |
#include <liburing.h> | |
static pthread_mutex_t submit_mutex = PTHREAD_MUTEX_INITIALIZER; | |
static struct io_uring ring; | |
static pthread_mutex_t threadinit_mutex = PTHREAD_MUTEX_INITIALIZER; | |
static pthread_cond_t threadinit_cv = PTHREAD_COND_INITIALIZER; | |
static bool threadinit_done = false; | |
static void* thread_main(void*); | |
int main(int argc, char** argv) | |
{ | |
int rc = 0; | |
pthread_t thread; | |
void* thread_result; | |
rc = pthread_create(&thread, NULL, &thread_main, NULL); | |
if (rc < 0) { | |
fprintf(stderr, "pthread_create failed\n"); | |
return 1; | |
} | |
/* Wait until the thread has done initializing */ | |
rc = pthread_mutex_lock(&threadinit_mutex); | |
if (rc < 0) { | |
fprintf(stderr, "pthread_mutex_lock failed [threadinit mutex]\n"); | |
exit(1); | |
} | |
while (!threadinit_done) | |
pthread_cond_wait(&threadinit_cv, &threadinit_mutex); | |
pthread_mutex_unlock(&threadinit_mutex); | |
if (argc <= 1 || strcmp(argv[1], "wait") != 0) { | |
struct io_uring_sqe* sqe; | |
/* Queue a wakeup operation */ | |
rc = pthread_mutex_lock(&submit_mutex); | |
if (rc < 0) { | |
fprintf(stderr, "pthread_mutex_lock failed [submit mutex]\n"); | |
exit(1); | |
} | |
sqe = io_uring_get_sqe(&ring); | |
io_uring_prep_nop(sqe); | |
io_uring_sqe_set_data(sqe, (void*) 2); | |
io_uring_submit(&ring); | |
pthread_mutex_unlock(&submit_mutex); | |
} | |
pthread_join(thread, &thread_result); | |
return 0; | |
} | |
void* thread_main(void*) | |
{ | |
int rc; | |
struct io_uring_sqe* sqe; | |
struct io_uring_cqe* cqe; | |
struct __kernel_timespec ts; | |
rc = io_uring_queue_init(10, &ring, 0); | |
if (rc < 0) { | |
fprintf(stderr, "io_uring_queue_init failed\n"); | |
exit(1); | |
} | |
/* Queue a timeout operation */ | |
rc = pthread_mutex_lock(&submit_mutex); | |
if (rc < 0) { | |
fprintf(stderr, "pthread_mutex_lock failed [submit mutex]\n"); | |
exit(1); | |
} | |
sqe = io_uring_get_sqe(&ring); | |
ts.tv_sec = 10; | |
ts.tv_nsec = 0; | |
io_uring_prep_timeout(sqe, &ts, 1, 0); | |
io_uring_sqe_set_data(sqe, (void*) 1); | |
io_uring_submit(&ring); | |
pthread_mutex_unlock(&submit_mutex); | |
/* Signal the main thread that we're done */ | |
rc = pthread_mutex_lock(&threadinit_mutex); | |
if (rc < 0) { | |
fprintf(stderr, "pthread_mutex_lock failed [threadinit mutex]\n"); | |
exit(1); | |
} | |
threadinit_done = true; | |
pthread_cond_signal(&threadinit_cv); | |
pthread_mutex_unlock(&threadinit_mutex); | |
rc = io_uring_wait_cqe(&ring, &cqe); | |
if (rc == 0) { | |
int v = (int) io_uring_cqe_get_data(cqe); | |
if (v == 1) | |
printf("Reached timeout\n"); | |
else if (v == 2) | |
printf("Was woken from main thread\n"); | |
else | |
printf("Unknown queue completion\n"); | |
io_uring_cqe_seen(&ring, cqe); | |
} else { | |
fprintf(stderr, "io_uring_wait_cqe failed\n"); | |
} | |
/* Free the queue */ | |
io_uring_queue_exit(&ring); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment