2020-04-07 08:33:49 +00:00
|
|
|
#include <IO/AIO.h>
|
2018-06-18 01:33:34 +00:00
|
|
|
|
2020-04-07 08:33:49 +00:00
|
|
|
#if defined(OS_LINUX)
|
2018-06-18 01:33:34 +00:00
|
|
|
|
2020-04-07 08:33:49 +00:00
|
|
|
# include <Common/Exception.h>
|
|
|
|
|
|
|
|
# include <sys/syscall.h>
|
|
|
|
# include <unistd.h>
|
2021-07-28 07:05:22 +00:00
|
|
|
# include <utility>
|
2018-06-18 01:33:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
/** Small wrappers for asynchronous I/O.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int CANNOT_IOSETUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int io_setup(unsigned nr, aio_context_t * ctxp)
|
|
|
|
{
|
2022-10-07 10:46:45 +00:00
|
|
|
return static_cast<int>(syscall(__NR_io_setup, nr, ctxp));
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int io_destroy(aio_context_t ctx)
|
|
|
|
{
|
2022-10-07 10:46:45 +00:00
|
|
|
return static_cast<int>(syscall(__NR_io_destroy, ctx));
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 03:27:32 +00:00
|
|
|
int io_submit(aio_context_t ctx, long nr, struct iocb * iocbpp[]) // NOLINT
|
2018-06-18 01:33:34 +00:00
|
|
|
{
|
2022-10-07 10:46:45 +00:00
|
|
|
return static_cast<int>(syscall(__NR_io_submit, ctx, nr, iocbpp));
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 03:27:32 +00:00
|
|
|
int io_getevents(aio_context_t ctx, long min_nr, long max_nr, io_event * events, struct timespec * timeout) // NOLINT
|
2018-06-18 01:33:34 +00:00
|
|
|
{
|
2022-10-07 10:46:45 +00:00
|
|
|
return static_cast<int>(syscall(__NR_io_getevents, ctx, min_nr, max_nr, events, timeout));
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AIOContext::AIOContext(unsigned int nr_events)
|
|
|
|
{
|
|
|
|
ctx = 0;
|
|
|
|
if (io_setup(nr_events, &ctx) < 0)
|
2023-12-15 18:25:49 +00:00
|
|
|
throw DB::ErrnoException(DB::ErrorCodes::CANNOT_IOSETUP, "io_setup failed");
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AIOContext::~AIOContext()
|
|
|
|
{
|
2021-07-28 22:30:12 +00:00
|
|
|
if (ctx)
|
|
|
|
io_destroy(ctx);
|
2018-06-18 01:33:34 +00:00
|
|
|
}
|
|
|
|
|
2022-02-25 19:04:48 +00:00
|
|
|
AIOContext::AIOContext(AIOContext && rhs) noexcept
|
2021-07-28 07:05:22 +00:00
|
|
|
{
|
|
|
|
*this = std::move(rhs);
|
|
|
|
}
|
|
|
|
|
2022-02-25 19:04:48 +00:00
|
|
|
AIOContext & AIOContext::operator=(AIOContext && rhs) noexcept
|
2021-07-28 07:05:22 +00:00
|
|
|
{
|
|
|
|
std::swap(ctx, rhs.ctx);
|
2021-07-28 09:16:08 +00:00
|
|
|
return *this;
|
2021-07-28 07:05:22 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 08:33:49 +00:00
|
|
|
#elif defined(OS_FREEBSD)
|
2019-02-07 15:08:45 +00:00
|
|
|
|
2019-02-08 13:36:58 +00:00
|
|
|
# include <Common/Exception.h>
|
2019-02-07 15:08:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
/** Small wrappers for asynchronous I/O.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2019-02-08 13:36:58 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int CANNOT_IOSETUP;
|
|
|
|
}
|
2019-02-07 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int io_setup(void)
|
|
|
|
{
|
|
|
|
return kqueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
int io_destroy(int ctx)
|
|
|
|
{
|
|
|
|
return close(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
int io_submit(int ctx, long nr, struct iocb * iocbpp[])
|
|
|
|
{
|
2021-12-20 12:55:07 +00:00
|
|
|
for (long i = 0; i < nr; ++i)
|
2019-02-08 13:36:58 +00:00
|
|
|
{
|
|
|
|
struct aiocb * iocb = &iocbpp[i]->aio;
|
|
|
|
|
|
|
|
struct sigevent * se = &iocb->aio_sigevent;
|
|
|
|
se->sigev_notify_kqueue = ctx;
|
|
|
|
se->sigev_notify_kevent_flags = 0;
|
|
|
|
se->sigev_notify = SIGEV_KEVENT;
|
|
|
|
se->sigev_value.sival_ptr = iocbpp[i];
|
|
|
|
|
|
|
|
switch (iocb->aio_lio_opcode)
|
|
|
|
{
|
|
|
|
case LIO_READ:
|
|
|
|
{
|
|
|
|
int r = aio_read(iocb);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LIO_WRITE:
|
|
|
|
{
|
|
|
|
int r = aio_write(iocb);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-02-07 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
2022-12-10 10:08:40 +00:00
|
|
|
return static_cast<int>(nr);
|
2019-02-07 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:36:58 +00:00
|
|
|
int io_getevents(int ctx, long, long max_nr, struct kevent * events, struct timespec * timeout)
|
2019-02-07 15:08:45 +00:00
|
|
|
{
|
2022-12-10 10:08:40 +00:00
|
|
|
return kevent(ctx, nullptr, 0, events, static_cast<int>(max_nr), timeout);
|
2019-02-07 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-02-08 13:36:58 +00:00
|
|
|
AIOContext::AIOContext(unsigned int)
|
2019-02-07 15:08:45 +00:00
|
|
|
{
|
|
|
|
ctx = io_setup();
|
|
|
|
if (ctx < 0)
|
2023-12-15 18:25:49 +00:00
|
|
|
throw ErrnoException(DB::ErrorCodes::CANNOT_IOSETUP, "io_setup failed");
|
2019-02-07 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AIOContext::~AIOContext()
|
|
|
|
{
|
|
|
|
io_destroy(ctx);
|
|
|
|
}
|
|
|
|
|
2018-06-18 01:33:34 +00:00
|
|
|
#endif
|