Skip to content

Commit

Permalink
support io_uring
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanFreeman committed Nov 28, 2023
1 parent b902f1b commit 91f24b3
Show file tree
Hide file tree
Showing 15 changed files with 776 additions and 97 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PROJECT(libswoole)

ENABLE_LANGUAGE(ASM)
set(SWOOLE_VERSION 5.1.1)
set(SWOOLE_VERSION 5.1.2-dev)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -g")
Expand Down
12 changes: 12 additions & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ PHP_ARG_ENABLE([cares],
[AS_HELP_STRING([--enable-cares],
[Enable cares])], [no], [no])

PHP_ARG_ENABLE([iouring],
[enable io-uring support],
[AS_HELP_STRING([--enable-iouring],
[Enable io-uring])], [no], [no])

PHP_ARG_WITH([openssl_dir],
[dir of openssl],
[AS_HELP_STRING([[--with-openssl-dir[=DIR]]],
Expand Down Expand Up @@ -924,6 +929,13 @@ EOF
PHP_ADD_LIBRARY(cares, 1, SWOOLE_SHARED_LIBADD)
fi

if test "$PHP_IOURING" = "yes"; then
AC_CHECK_LIB(uring, io_uring_queue_init, [
AC_DEFINE(SW_USE_IOURING, 1, [have io_uring])
PHP_ADD_LIBRARY(uring, 1, SWOOLE_SHARED_LIBADD)
])
fi

AC_SWOOLE_CPU_AFFINITY
AC_SWOOLE_HAVE_REUSEPORT
AC_SWOOLE_HAVE_FUTEX
Expand Down
3 changes: 3 additions & 0 deletions ext-src/php_swoole.cc
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ PHP_MINFO_FUNCTION(swoole) {
#endif
#ifdef SW_USE_SQLITE
php_info_print_table_row(2, "coroutine_sqlite", "enabled");
#endif
#if defined(__linux__) && defined(SW_USE_IOURING)
php_info_print_table_row(2, "io_uring", "enabled");
#endif
php_info_print_table_end();

Expand Down
6 changes: 6 additions & 0 deletions ext-src/swoole_async_coro.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ void php_swoole_set_aio_option(HashTable *vht) {
if (php_swoole_array_get_value(vht, "aio_max_idle_time", ztmp)) {
SwooleG.aio_max_idle_time = zval_get_double(ztmp);
}
#if defined(__linux__) && defined(SW_USE_IOURING)
if (php_swoole_array_get_value(vht, "iouring_entries", ztmp)) {
zend_long v = zval_get_long(ztmp);
SwooleG.iouring_entries = SW_MAX(0, SW_MIN(v, UINT32_MAX));
}
#endif
}

PHP_FUNCTION(swoole_async_set) {
Expand Down
17 changes: 17 additions & 0 deletions include/swoole.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
#include <list>
#include <functional>

#if defined(__linux__) && defined(SW_USE_IOURING)
#include <liburing.h>
#endif

typedef unsigned long ulong_t;

#ifndef PRId64
Expand Down Expand Up @@ -200,6 +204,9 @@ struct Socket;
struct Address;
} // namespace network
class AsyncThreads;
#if defined(__linux__) && defined(SW_USE_IOURING)
class AsyncIOUring;
#endif
namespace async {
class ThreadPool;
}
Expand Down Expand Up @@ -411,6 +418,10 @@ enum swFdType {
SW_FD_SIGNAL,
SW_FD_DNS_RESOLVER,
SW_FD_CARES,
/**
* io_uring
*/
SW_FD_IOURING,
/**
* SW_FD_USER or SW_FD_USER+n: for custom event
*/
Expand Down Expand Up @@ -656,6 +667,9 @@ struct ThreadGlobal {
Reactor *reactor;
Timer *timer;
AsyncThreads *async_threads;
#if defined(__linux__) && defined(SW_USE_IOURING)
AsyncIOUring *async_iouring;
#endif
uint32_t signal_listener_num;
uint32_t co_signal_listener_num;
int error;
Expand Down Expand Up @@ -736,6 +750,9 @@ struct Global {
//-----------------------[AIO]--------------------------
uint32_t aio_core_worker_num;
uint32_t aio_worker_num;
#if defined(__linux__) && defined(SW_USE_IOURING)
uint32_t iouring_entries;
#endif
double aio_max_wait_time;
double aio_max_idle_time;
network::Socket *aio_default_socket;
Expand Down
78 changes: 77 additions & 1 deletion include/swoole_async.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string>
#include <mutex>
#include <atomic>
#include <queue>

#ifndef O_DIRECT
#define O_DIRECT 040000
Expand All @@ -36,16 +37,32 @@ enum AsyncFlag {

struct AsyncEvent {
size_t task_id;
#if defined(__linux__) && defined(SW_USE_IOURING)
size_t count;
#endif
uint8_t canceled;
int error;
/**
* input & output
*/
void *data;
#if defined(__linux__) && defined(SW_USE_IOURING)
const char *pathname;
const char *pathname2;
struct statx *statxbuf;
void *rbuf;
const void *wbuf;
#endif
/**
* output
*/
ssize_t retval;
int error;
#if defined(__linux__) && defined(SW_USE_IOURING)
int fd;
int flags;
int opcode;
mode_t mode;
#endif
/**
* internal use only
*/
Expand Down Expand Up @@ -102,6 +119,65 @@ class AsyncThreads {
std::mutex init_lock;
};

#if defined(__linux__) && defined(SW_USE_IOURING)
class AsyncIOUring {
private:
int ring_fd;
uint32_t entries = 8192;
struct io_uring ring;
network::Socket *iou_socket = nullptr;
Reactor *reactor = nullptr;

struct io_uring_sqe *get_iouring_sqe();
bool store_events(AsyncEvent *event);
void set_iouring_sqe_data(struct io_uring_sqe *sqe, void *data);
void *get_iouring_cqe_data(struct io_uring_cqe *cqe);
int get_iouring_cqe(struct io_uring_cqe **cqe_ptr);
void finish_iouring_cqe(struct io_uring_cqe *cqe);
bool submit_iouring_sqe();

public:
uint64_t task_num = 0;
std::queue<AsyncEvent *> waitEvents;
AsyncIOUring(Reactor *reactor_);
~AsyncIOUring();

enum opcodes {
SW_IORING_OP_OPENAT = 18,
SW_IORING_OP_CLOSE = 19,
SW_IORING_OP_STATX = 21,
SW_IORING_OP_READ = 22,
SW_IORING_OP_WRITE = 23,
SW_IORING_OP_RENAMEAT = 35,
SW_IORING_OP_UNLINKAT = 36,
SW_IORING_OP_MKDIRAT = 37,
SW_IORING_OP_FSTAT = 1000,
SW_IORING_OP_LSTAT = 1001,
SW_IORING_OP_UNLINK_FILE = 1002,
SW_IORING_OP_UNLINK_DIR = 1003,
};

void add_event();
void delete_event();
bool open(AsyncEvent *event);
bool close(AsyncEvent *event);
bool wr(AsyncEvent *event);
bool statx(AsyncEvent *event);
bool mkdir(AsyncEvent *event);
bool unlink(AsyncEvent *event);
bool rename(AsyncEvent *event);
inline bool is_empty_wait_events() {
return waitEvents.size() == 0;
}

inline uint64_t get_task_num() {
return task_num;
}

static int callback(Reactor *reactor, Event *event);
};
#endif

namespace async {

typedef void (*Handler)(AsyncEvent *event);
Expand Down
16 changes: 16 additions & 0 deletions include/swoole_coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ class Coroutine {
namespace coroutine {
bool async(async::Handler handler, AsyncEvent &event, double timeout = -1);
bool async(const std::function<void(void)> &fn, double timeout = -1);
#if defined(__linux__) && defined(SW_USE_IOURING)
int async(AsyncIOUring::opcodes opcode,
const char *pathname,
const char *pathname2 = nullptr,
mode_t mode = 0,
int flags = 0,
struct statx *statxbuf = nullptr,
double timeout = -1);
int async(AsyncIOUring::opcodes opcode,
int fd,
void *rbuf = nullptr,
const void *wbuf = nullptr,
struct statx *statxbuf = nullptr,
size_t count = 0,
double timeout = -1);
#endif
bool run(const CoroutineFunc &fn, void *arg = nullptr);
} // namespace coroutine
//-------------------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions include/swoole_coroutine_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ ssize_t swoole_coroutine_read(int fd, void *buf, size_t count);
ssize_t swoole_coroutine_write(int fd, const void *buf, size_t count);
off_t swoole_coroutine_lseek(int fd, off_t offset, int whence);
int swoole_coroutine_fstat(int fd, struct stat *statbuf);
int swoole_coroutine_stat(const char *path, struct stat *statbuf);
int swoole_coroutine_lstat(const char *path, struct stat *statbuf);
int swoole_coroutine_readlink(const char *pathname, char *buf, size_t len);
int swoole_coroutine_unlink(const char *pathname);
int swoole_coroutine_mkdir(const char *pathname, mode_t mode);
Expand All @@ -56,6 +58,10 @@ int swoole_coroutine_rename(const char *oldpath, const char *newpath);
int swoole_coroutine_flock(int fd, int operation);
int swoole_coroutine_flock_ex(const char *filename, int fd, int operation);
int swoole_coroutine_statvfs(const char *path, struct statvfs *buf);
int swoole_coroutine_close_file(int fd);
#if defined(__linux__) && defined(SW_USE_IOURING)
void sw_statx_to_stat(const struct statx *statxbuf, struct stat *statbuf);
#endif
/**
* stdio
*/
Expand Down
2 changes: 2 additions & 0 deletions include/swoole_file_hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#define write(fd, buf, count) swoole_coroutine_write(fd, buf, count)
#define lseek(fd, offset, whence) swoole_coroutine_lseek(fd, offset, whence)
#define fstat(fd, statbuf) swoole_coroutine_fstat(fd, statbuf)
#define stat(path, statbuf) swoole_coroutine_stat(path, statbuf)
#define lstat(path, statbuf) swoole_coroutine_lstat(path, statbuf)
#define readlink(fd, buf, size) swoole_coroutine_readlink(fd, buf, size)
#define unlink(pathname) swoole_coroutine_unlink(pathname)
#define mkdir(pathname, mode) swoole_coroutine_mkdir(pathname, mode)
Expand Down
1 change: 1 addition & 0 deletions include/swoole_reactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class Reactor {
EXIT_CONDITION_SIGNALFD,
EXIT_CONDITION_USER_BEFORE_DEFAULT,
EXIT_CONDITION_FORCED_TERMINATION,
EXIT_CONDITION_IOURING,
EXIT_CONDITION_DEFAULT = 999,
EXIT_CONDITION_USER_AFTER_DEFAULT,
};
Expand Down
8 changes: 4 additions & 4 deletions include/swoole_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

#define SWOOLE_MAJOR_VERSION 5
#define SWOOLE_MINOR_VERSION 1
#define SWOOLE_RELEASE_VERSION 1
#define SWOOLE_EXTRA_VERSION ""
#define SWOOLE_VERSION "5.1.1"
#define SWOOLE_VERSION_ID 50101
#define SWOOLE_RELEASE_VERSION 2
#define SWOOLE_EXTRA_VERSION "dev"
#define SWOOLE_VERSION "5.1.2-dev"
#define SWOOLE_VERSION_ID 50102
#define SWOOLE_API_VERSION_ID 0x202208a

#define SWOOLE_BUG_REPORT \
Expand Down
Loading

0 comments on commit 91f24b3

Please sign in to comment.