io/uring: basic Linux io_uring support
This commit is contained in:
parent
935e622915
commit
62d0ceabcc
|
@ -334,6 +334,7 @@ endif
|
||||||
subdir('src/util')
|
subdir('src/util')
|
||||||
subdir('src/time')
|
subdir('src/time')
|
||||||
subdir('src/io')
|
subdir('src/io')
|
||||||
|
subdir('src/io/uring')
|
||||||
subdir('src/system')
|
subdir('src/system')
|
||||||
subdir('src/thread')
|
subdir('src/thread')
|
||||||
subdir('src/net')
|
subdir('src/net')
|
||||||
|
|
|
@ -4,6 +4,7 @@ option('test', type: 'boolean', value: false, description: 'Build the unit tests
|
||||||
|
|
||||||
option('syslog', type: 'feature', description: 'syslog support')
|
option('syslog', type: 'feature', description: 'syslog support')
|
||||||
option('inotify', type: 'boolean', value: true, description: 'inotify support (for automatic database update)')
|
option('inotify', type: 'boolean', value: true, description: 'inotify support (for automatic database update)')
|
||||||
|
option('io_uring', type: 'feature', description: 'Linux io_uring support using liburing')
|
||||||
|
|
||||||
option('daemon', type: 'boolean', value: true, description: 'enable daemonization')
|
option('daemon', type: 'boolean', value: true, description: 'enable daemonization')
|
||||||
option('systemd', type: 'feature', description: 'systemd support')
|
option('systemd', type: 'feature', description: 'systemd support')
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Operation.hxx"
|
||||||
|
|
||||||
|
#include <boost/intrusive/list_hook.hpp>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
class CancellableOperation
|
||||||
|
: public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>
|
||||||
|
{
|
||||||
|
Operation *operation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CancellableOperation(Operation &_operation) noexcept
|
||||||
|
:operation(&_operation)
|
||||||
|
{
|
||||||
|
assert(operation->cancellable == nullptr);
|
||||||
|
operation->cancellable = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CancellableOperation() noexcept {
|
||||||
|
assert(operation == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cancel(Operation &_operation) noexcept {
|
||||||
|
(void)_operation;
|
||||||
|
assert(operation == &_operation);
|
||||||
|
|
||||||
|
operation = nullptr;
|
||||||
|
|
||||||
|
// TODO: io_uring_prep_cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUringCompletion(int res) noexcept {
|
||||||
|
if (operation == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(operation->cancellable == this);
|
||||||
|
operation->cancellable = nullptr;
|
||||||
|
|
||||||
|
std::exchange(operation, nullptr)->OnUringCompletion(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
struct statx;
|
||||||
|
class UniqueFileDescriptor;
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
class OpenStatHandler {
|
||||||
|
public:
|
||||||
|
virtual void OnOpenStat(UniqueFileDescriptor fd,
|
||||||
|
struct statx &st) noexcept = 0;
|
||||||
|
virtual void OnOpenStatError(std::exception_ptr e) noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Operation.hxx"
|
||||||
|
#include "CancellableOperation.hxx"
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
void
|
||||||
|
Operation::CancelUring() noexcept
|
||||||
|
{
|
||||||
|
if (cancellable == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::exchange(cancellable, nullptr)->Cancel(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
class CancellableOperation;
|
||||||
|
|
||||||
|
class Operation {
|
||||||
|
friend class CancellableOperation;
|
||||||
|
|
||||||
|
CancellableOperation *cancellable = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~Operation() noexcept {
|
||||||
|
CancelUring();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUringPending() const noexcept {
|
||||||
|
return cancellable != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CancelUring() noexcept;
|
||||||
|
|
||||||
|
virtual void OnUringCompletion(int res) noexcept = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Queue.hxx"
|
||||||
|
#include "CancellableOperation.hxx"
|
||||||
|
#include "Operation.hxx"
|
||||||
|
#include "util/DeleteDisposer.hxx"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
Queue::Queue(unsigned entries, unsigned flags)
|
||||||
|
:ring(entries, flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Queue::~Queue() noexcept
|
||||||
|
{
|
||||||
|
operations.clear_and_dispose(DeleteDisposer{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Queue::AddPending(struct io_uring_sqe &sqe,
|
||||||
|
Operation &operation) noexcept
|
||||||
|
{
|
||||||
|
auto *c = new CancellableOperation(operation);
|
||||||
|
operations.push_back(*c);
|
||||||
|
io_uring_sqe_set_data(&sqe, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Queue::DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept
|
||||||
|
{
|
||||||
|
void *data = io_uring_cqe_get_data(&cqe);
|
||||||
|
if (data != nullptr) {
|
||||||
|
auto *c = (CancellableOperation *)data;
|
||||||
|
c->OnUringCompletion(cqe.res);
|
||||||
|
operations.erase_and_dispose(operations.iterator_to(*c),
|
||||||
|
DeleteDisposer{});
|
||||||
|
}
|
||||||
|
|
||||||
|
ring.SeenCompletion(cqe);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Queue::DispatchOneCompletion()
|
||||||
|
{
|
||||||
|
auto *cqe = ring.PeekCompletion();
|
||||||
|
if (cqe == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DispatchOneCompletion(*cqe);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Queue::WaitDispatchOneCompletion()
|
||||||
|
{
|
||||||
|
auto *cqe = ring.WaitCompletion();
|
||||||
|
if (cqe == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DispatchOneCompletion(*cqe);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Ring.hxx"
|
||||||
|
|
||||||
|
#include <liburing.h>
|
||||||
|
|
||||||
|
#include <boost/intrusive/list.hpp>
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
class Operation;
|
||||||
|
class CancellableOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* High-level C++ wrapper for a `struct io_uring`. It supports a
|
||||||
|
* handler class, cancellation, ...
|
||||||
|
*/
|
||||||
|
class Queue {
|
||||||
|
Ring ring;
|
||||||
|
|
||||||
|
boost::intrusive::list<CancellableOperation,
|
||||||
|
boost::intrusive::base_hook<boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
|
||||||
|
boost::intrusive::constant_time_size<false>> operations;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Queue(unsigned entries, unsigned flags);
|
||||||
|
~Queue() noexcept;
|
||||||
|
|
||||||
|
FileDescriptor GetFileDescriptor() const noexcept {
|
||||||
|
return ring.GetFileDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct io_uring_sqe *GetSubmitEntry() noexcept {
|
||||||
|
return ring.GetSubmitEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasPending() const noexcept {
|
||||||
|
return !operations.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void AddPending(struct io_uring_sqe &sqe,
|
||||||
|
Operation &operation) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Push(struct io_uring_sqe &sqe,
|
||||||
|
Operation &operation) noexcept {
|
||||||
|
AddPending(sqe, operation);
|
||||||
|
Submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Submit() {
|
||||||
|
ring.Submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DispatchOneCompletion();
|
||||||
|
|
||||||
|
void DispatchCompletions() {
|
||||||
|
while (DispatchOneCompletion()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitDispatchOneCompletion();
|
||||||
|
|
||||||
|
void WaitDispatchCompletions() {
|
||||||
|
while (WaitDispatchOneCompletion()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Ring.hxx"
|
||||||
|
#include "system/Error.hxx"
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
Ring::Ring(unsigned entries, unsigned flags)
|
||||||
|
{
|
||||||
|
int error = io_uring_queue_init(entries, &ring, flags);
|
||||||
|
if (error < 0)
|
||||||
|
throw MakeErrno(-error, "io_uring_queue_init() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Ring::Submit()
|
||||||
|
{
|
||||||
|
int error = io_uring_submit(&ring);
|
||||||
|
if (error < 0)
|
||||||
|
throw MakeErrno(-error, "io_uring_submit() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct io_uring_cqe *
|
||||||
|
Ring::WaitCompletion()
|
||||||
|
{
|
||||||
|
struct io_uring_cqe *cqe;
|
||||||
|
int error = io_uring_wait_cqe(&ring, &cqe);
|
||||||
|
if (error < 0) {
|
||||||
|
if (error == -EAGAIN)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
throw MakeErrno(-error, "io_uring_wait_cqe() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cqe;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct io_uring_cqe *
|
||||||
|
Ring::PeekCompletion()
|
||||||
|
{
|
||||||
|
struct io_uring_cqe *cqe;
|
||||||
|
int error = io_uring_peek_cqe(&ring, &cqe);
|
||||||
|
if (error < 0) {
|
||||||
|
if (error == -EAGAIN)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
throw MakeErrno(-error, "io_uring_peek_cqe() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cqe;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 CM4all GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* author: Max Kellermann <mk@cm4all.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "io/FileDescriptor.hxx"
|
||||||
|
|
||||||
|
#include <liburing.h>
|
||||||
|
|
||||||
|
namespace Uring {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low-level C++ wrapper for a `struct io_uring`. It provides simple
|
||||||
|
* wrappers to liburing functions and throws std::system_error on
|
||||||
|
* errors.
|
||||||
|
*/
|
||||||
|
class Ring {
|
||||||
|
struct io_uring ring;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ring(unsigned entries, unsigned flags);
|
||||||
|
|
||||||
|
~Ring() noexcept {
|
||||||
|
io_uring_queue_exit(&ring);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ring(const Ring &) = delete;
|
||||||
|
Ring &operator=(const Ring &) = delete;
|
||||||
|
|
||||||
|
FileDescriptor GetFileDescriptor() const noexcept {
|
||||||
|
return FileDescriptor(ring.ring_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct io_uring_sqe *GetSubmitEntry() noexcept {
|
||||||
|
return io_uring_get_sqe(&ring);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Submit();
|
||||||
|
|
||||||
|
struct io_uring_cqe *WaitCompletion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a completion queue entry or nullptr on EAGAIN
|
||||||
|
*/
|
||||||
|
struct io_uring_cqe *PeekCompletion();
|
||||||
|
|
||||||
|
void SeenCompletion(struct io_uring_cqe &cqe) noexcept {
|
||||||
|
io_uring_cqe_seen(&ring, &cqe);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Uring
|
|
@ -0,0 +1,36 @@
|
||||||
|
uring_features = configuration_data()
|
||||||
|
|
||||||
|
if host_machine.system() != 'linux'
|
||||||
|
uring_dep = dependency('', required: false)
|
||||||
|
uring_features.set('HAVE_URING', false)
|
||||||
|
configure_file(output: 'Features.h', configuration: uring_features)
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
liburing = dependency('liburing', required: get_option('io_uring'))
|
||||||
|
uring_features.set('HAVE_URING', liburing.found())
|
||||||
|
configure_file(output: 'Features.h', configuration: uring_features)
|
||||||
|
|
||||||
|
if not liburing.found()
|
||||||
|
uring_dep = dependency('', required: false)
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
uring = static_library(
|
||||||
|
'uring',
|
||||||
|
'Ring.cxx',
|
||||||
|
'Queue.cxx',
|
||||||
|
'Operation.cxx',
|
||||||
|
include_directories: inc,
|
||||||
|
dependencies: [
|
||||||
|
liburing,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
uring_dep = declare_dependency(
|
||||||
|
link_with: uring,
|
||||||
|
dependencies: [
|
||||||
|
liburing,
|
||||||
|
io_dep,
|
||||||
|
],
|
||||||
|
)
|
Loading…
Reference in New Issue