Skip to content

Instantly share code, notes, and snippets.

@chris-se
Created June 15, 2022 13:13
Show Gist options
  • Save chris-se/949e5ccc9dd38b78f11f924d6ab60749 to your computer and use it in GitHub Desktop.
Save chris-se/949e5ccc9dd38b78f11f924d6ab60749 to your computer and use it in GitHub Desktop.
#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