Commit aae50806 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

always build AsyncIo and IoUring sources

Summary: Their contents may be preprocessed away if the corresponding platform headers are unavailable. But this removes some of the build-time and build-config complexity.

Differential Revision: D32629035

fbshipit-source-id: a2265ceac44b5022ed53d1c7163f591e779da651
parent cec3fcac
......@@ -201,39 +201,6 @@ list(APPEND hfiles
${FOLLY_DIR}/test/TestUtils.h
)
# Exclude specific sources if we do not have third-party libraries
# required to build them.
if (NOT ${LIBAIO_FOUND})
list(REMOVE_ITEM files
${FOLLY_DIR}/experimental/io/AsyncIO.cpp
)
list(REMOVE_ITEM hfiles
${FOLLY_DIR}/experimental/io/AsyncIO.h
)
endif()
if (NOT ${LIBURING_FOUND})
list(REMOVE_ITEM files
${FOLLY_DIR}/experimental/io/IoUring.cpp
${FOLLY_DIR}/experimental/io/IoUringBackend.cpp
)
list(REMOVE_ITEM hfiles
${FOLLY_DIR}/experimental/io/IoUring.h
${FOLLY_DIR}/experimental/io/IoUringBackend.h
)
endif()
if (NOT ${LIBAIO_FOUND} AND NOT ${LIBURING_FOUND})
list(REMOVE_ITEM files
${FOLLY_DIR}/experimental/io/AsyncBase.cpp
${FOLLY_DIR}/experimental/io/PollIoBackend.cpp
${FOLLY_DIR}/experimental/io/SimpleAsyncIO.cpp
)
list(REMOVE_ITEM hfiles
${FOLLY_DIR}/experimental/io/AsyncBase.h
${FOLLY_DIR}/experimental/io/PollIoBackend.h
${FOLLY_DIR}/experimental/io/SimpleAsyncIO.h
)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
check_cxx_compiler_flag(-fcoroutines COMPILER_HAS_F_COROUTINES)
if (COMPILER_HAS_F_COROUTINES)
......
......@@ -87,7 +87,7 @@ void AsyncBaseOp::init() {
std::string AsyncBaseOp::fd2name(int fd) {
auto link = fs::path{"/proc/self/fd"} / folly::to<std::string>(fd);
return fs::read_symlink(link);
return fs::read_symlink(link).string();
}
AsyncBase::AsyncBase(size_t capacity, PollMode pollMode) : capacity_(capacity) {
......
......@@ -16,7 +16,6 @@
#include <folly/experimental/io/AsyncIO.h>
#include <sys/eventfd.h>
#include <cerrno>
#include <ostream>
#include <stdexcept>
......@@ -32,6 +31,8 @@
#include <folly/portability/Unistd.h>
#include <folly/small_vector.h>
#if __has_include(<libaio.h>)
// debugging helpers
namespace {
#define X(c) \
......@@ -274,3 +275,5 @@ Range<AsyncBase::Op**> AsyncIO::doWait(
}
} // namespace folly
#endif
......@@ -16,10 +16,12 @@
#pragma once
#include <libaio.h>
#include <folly/experimental/io/AsyncBase.h>
#if __has_include(<libaio.h>)
#include <libaio.h>
namespace folly {
class AsyncIOOp : public AsyncBaseOp {
......@@ -94,3 +96,5 @@ class AsyncIO : public AsyncBase {
using AsyncIOQueue = AsyncBaseQueue;
} // namespace folly
#endif
......@@ -16,7 +16,6 @@
#include <folly/experimental/io/IoUring.h>
#include <sys/eventfd.h>
#include <cerrno>
#include <ostream>
#include <stdexcept>
......@@ -31,6 +30,8 @@
#include <folly/String.h>
#include <folly/portability/Unistd.h>
#if __has_include(<liburing.h>)
// helpers
namespace {
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
......@@ -338,3 +339,5 @@ Range<AsyncBase::Op**> IoUring::doWait(
}
} // namespace folly
#endif
......@@ -16,11 +16,13 @@
#pragma once
#include <liburing.h>
#include <folly/SharedMutex.h>
#include <folly/experimental/io/AsyncBase.h>
#if __has_include(<liburing.h>)
#include <liburing.h>
namespace folly {
/**
......@@ -117,3 +119,5 @@ class IoUring : public AsyncBase {
using IoUringQueue = AsyncBaseQueue;
} // namespace folly
#endif
......@@ -15,7 +15,6 @@
*/
#include <signal.h>
#include <sys/timerfd.h>
#include <folly/FileUtil.h>
#include <folly/Likely.h>
......@@ -28,6 +27,12 @@
#include <folly/portability/Sockets.h>
#include <folly/synchronization/CallOnce.h>
#if __has_include(<sys/timerfd.h>)
#include <sys/timerfd.h>
#endif
#if __has_include(<liburing.h>)
extern "C" FOLLY_ATTR_WEAK void eb_poll_loop_pre_hook(uint64_t* call_time);
extern "C" FOLLY_ATTR_WEAK void eb_poll_loop_post_hook(
uint64_t call_time, int ret);
......@@ -1302,3 +1307,5 @@ void IoUringBackend::processFileOp(IoSqe* sqe, int64_t res) noexcept {
}
} // namespace folly
#endif // __has_include(<liburing.h>)
......@@ -16,8 +16,6 @@
#pragma once
#include <liburing.h>
#include <poll.h>
#include <sys/types.h>
#include <chrono>
......@@ -38,6 +36,16 @@
#include <folly/portability/Asm.h>
#include <folly/small_vector.h>
#if __has_include(<poll.h>)
#include <poll.h>
#endif
#if __has_include(<liburing.h>)
#include <liburing.h>
#endif
#if __has_include(<liburing.h>)
namespace folly {
class IoUringBackend : public EventBaseBackendBase {
......@@ -953,3 +961,5 @@ class IoUringBackend : public EventBaseBackendBase {
using PollIoBackend = IoUringBackend;
} // namespace folly
#endif // __has_include(<liburing.h>)
......@@ -17,79 +17,68 @@
#include <folly/experimental/io/SimpleAsyncIO.h>
#include <folly/String.h>
#if __has_include(<folly/experimental/io/AsyncIO.h>) && __has_include(<libaio.h>)
#define AIO_SUPPORTED
#include <folly/experimental/coro/Baton.h>
#include <folly/experimental/io/AsyncIO.h>
#endif
#if __has_include(<folly/experimental/io/IoUring.h>) && __has_include(<liburing.h>)
#define IOURING_SUPPORTED
#include <folly/experimental/io/IoUring.h>
#include <folly/portability/Sockets.h>
namespace folly {
#if __has_include(<libaio.h>)
static constexpr bool has_aio = true;
using aio_type = AsyncIO;
#else
static constexpr bool has_aio = false;
using aio_type = void;
#endif
#if !defined(AIO_SUPPORTED) && !defined(IOURING_SUPPORTED)
#error "Cannot build without at least one of AsyncIO.h and IoUring.h"
#if __has_include(<liburing.h>)
static constexpr auto has_io_uring_rt = &IoUring::isAvailable;
using io_uring_type = IoUring;
#else
static constexpr auto has_io_uring_rt = +[] { return false; };
using io_uring_type = void;
#endif
#include <folly/experimental/coro/Baton.h>
#include <folly/portability/Sockets.h>
template <typename AsyncIOType>
void SimpleAsyncIO::init() {
asyncIO_ = std::make_unique<AsyncIOType>(maxRequests_, AsyncBase::POLLABLE);
opsFreeList_.withWLock([this](auto& freeList) {
for (size_t i = 0; i < maxRequests_; ++i) {
freeList.push(std::make_unique<typename AsyncIOType::Op>());
}
});
}
namespace folly {
template <>
void SimpleAsyncIO::init<void>() {}
SimpleAsyncIO::SimpleAsyncIO(Config cfg)
: maxRequests_(cfg.maxRequests_),
completionExecutor_(cfg.completionExecutor_),
terminating_(false) {
#if !defined(AIO_SUPPORTED)
if (cfg.mode_ == AIO) {
LOG(WARNING)
<< "aio mode requested but not available at link time, falling back to io_uring.";
cfg.setMode(IOURING);
static bool has_io_uring = has_io_uring_rt();
if (!has_aio && !has_io_uring) {
LOG(FATAL) << "neither aio nor io_uring is available";
}
#endif
#if !defined(IOURING_SUPPORTED)
if (cfg.mode_ == IOURING) {
LOG(WARNING)
<< "io_uring mode requested but not available at link time, falling back to aio.";
cfg.setMode(AIO);
if (cfg.mode_ == AIO && !has_aio) {
LOG(WARNING) << "aio requested but unavailable: falling back to io_uring";
cfg.setMode(IOURING);
}
#else
if (cfg.mode_ == IOURING && !IoUring::isAvailable()) {
#if defined(AIO_SUPPORTED)
LOG(WARNING)
<< "io_uring requested but not available at runtime, falling back to aio mode.";
if (cfg.mode_ == IOURING && !has_io_uring) {
LOG(WARNING) << "io_uring requested but unavailable: falling back to aio";
cfg.setMode(AIO);
#else
LOG(FATAL)
<< "io_uring requested but not available at runtime, aio not available at link time, cannot proceed.";
#endif
}
#endif
switch (cfg.mode_) {
#if defined(AIO_SUPPORTED)
case AIO:
asyncIO_ = std::make_unique<AsyncIO>(maxRequests_, AsyncBase::POLLABLE);
opsFreeList_.withWLock(
[this](std::queue<std::unique_ptr<AsyncBaseOp>>& freeList) {
for (size_t i = 0; i < maxRequests_; ++i) {
freeList.push(std::make_unique<AsyncIOOp>());
}
});
init<aio_type>();
break;
#endif
#ifdef IOURING_SUPPORTED
case IOURING:
asyncIO_ = std::make_unique<IoUring>(maxRequests_, AsyncBase::POLLABLE);
opsFreeList_.withWLock(
[this](std::queue<std::unique_ptr<AsyncBaseOp>>& freeList) {
for (size_t i = 0; i < maxRequests_; ++i) {
freeList.push(std::make_unique<IoUringOp>());
}
});
init<io_uring_type>();
break;
#endif
default:
// Should never happen...
LOG(FATAL) << "Unavailable mode " << (int)cfg.mode_ << " requested.";
LOG(FATAL) << "unrecognized mode " << (int)cfg.mode_ << " requested";
break;
}
......
......@@ -164,6 +164,9 @@ class SimpleAsyncIO : public EventHandler {
virtual void handlerReady(uint16_t events) noexcept override;
template <typename AsyncIOType>
void init();
size_t maxRequests_;
Executor::KeepAlive<> completionExecutor_;
std::unique_ptr<AsyncBase> asyncIO_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment