0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::fs::aio: Pointer to dock rather than instance per request; split request::operator().

This commit is contained in:
Jason Volk 2020-05-06 13:37:56 -07:00
parent 6d77e99a03
commit fd1db1b208
2 changed files with 51 additions and 34 deletions

View file

@ -147,11 +147,12 @@ ircd::fs::aio::translate(const int &val)
// request::fsync
//
ircd::fs::aio::request::fsync::fsync(const int &fd,
ircd::fs::aio::request::fsync::fsync(ctx::dock &waiter,
const int &fd,
const sync_opts &opts)
:request
{
fd, &opts
fd, &opts, &waiter
}
{
assert(opts.op == op::SYNC);
@ -166,14 +167,16 @@ size_t
ircd::fs::aio::fsync(const fd &fd,
const sync_opts &opts)
{
ctx::dock waiter;
aio::request::fsync request
{
fd, opts
waiter, fd, opts
};
request.submit();
const size_t bytes
{
request()
request.complete()
};
return bytes;
@ -183,12 +186,13 @@ ircd::fs::aio::fsync(const fd &fd,
// request::read
//
ircd::fs::aio::request::read::read(const int &fd,
ircd::fs::aio::request::read::read(ctx::dock &waiter,
const int &fd,
const read_opts &opts,
const const_iovec_view &iov)
:request
{
fd, &opts
fd, &opts, &waiter
}
{
assert(opts.op == op::READ);
@ -204,17 +208,19 @@ ircd::fs::aio::read(const fd &fd,
const const_iovec_view &bufs,
const read_opts &opts)
{
ctx::dock waiter;
aio::request::read request
{
fd, opts, bufs
waiter, fd, opts, bufs
};
const scope_count cur_reads{stats.cur_reads};
stats.max_reads = std::max(stats.max_reads, stats.cur_reads);
request.submit();
const size_t bytes
{
request()
request.complete()
};
stats.bytes_read += bytes;
@ -226,12 +232,13 @@ ircd::fs::aio::read(const fd &fd,
// request::write
//
ircd::fs::aio::request::write::write(const int &fd,
ircd::fs::aio::request::write::write(ctx::dock &waiter,
const int &fd,
const write_opts &opts,
const const_iovec_view &iov)
:request
{
fd, &opts
fd, &opts, &waiter
}
{
assert(opts.op == op::WRITE);
@ -271,9 +278,10 @@ ircd::fs::aio::write(const fd &fd,
const const_iovec_view &bufs,
const write_opts &opts)
{
ctx::dock waiter;
aio::request::write request
{
fd, opts, bufs
waiter, fd, opts, bufs
};
const size_t req_bytes
@ -293,9 +301,10 @@ ircd::fs::aio::write(const fd &fd,
}};
// Make the request; ircd::ctx blocks here. Throws on error
request.submit();
const size_t bytes
{
request()
request.complete()
};
// Does linux ever not complete all bytes for an AIO?
@ -349,9 +358,11 @@ ircd::fs::aio::for_each_completed(const std::function<bool (const request &)> &c
//
ircd::fs::aio::request::request(const int &fd,
const struct opts *const &opts)
const struct opts *const &opts,
ctx::dock *const &waiter)
:iocb{0}
,opts{opts}
,waiter{waiter}
{
assert(system);
assert(ctx::current);
@ -393,20 +404,14 @@ ircd::fs::aio::request::cancel()
return true;
}
/// Submit a request and properly yield the ircd::ctx. When this returns the
/// result will be available or an exception will be thrown.
size_t
ircd::fs::aio::request::operator()()
void
ircd::fs::aio::request::submit()
{
assert(system);
assert(ctx::current);
const size_t submitted_bytes
{
bytes(iovec())
};
// Update stats for submission phase
const size_t submitted_bytes(bytes(iovec()));
stats.bytes_requests += submitted_bytes;
stats.requests++;
@ -421,14 +426,18 @@ ircd::fs::aio::request::operator()()
// Submit to system
system->submit(*this);
}
size_t
ircd::fs::aio::request::complete()
{
// Wait for completion
while(!wait());
assert(completed());
assert(retval <= ssize_t(submitted_bytes));
// Update stats for completion phase.
const size_t submitted_bytes(bytes(iovec()));
assert(retval <= ssize_t(submitted_bytes));
stats.bytes_complete += submitted_bytes;
stats.complete++;
@ -480,7 +489,8 @@ bool
ircd::fs::aio::request::wait()
try
{
waiter.wait([this]
assert(waiter);
waiter->wait([this]
{
return completed();
});
@ -1162,7 +1172,8 @@ noexcept try
// Notify the waiting context. Note that we are on the main async stack
// but it is safe to notify from here.
request->waiter.notify_one();
assert(request->waiter);
request->waiter->notify_one();
stats.events++;
}
catch(const std::exception &e)

View file

@ -29,7 +29,7 @@ namespace ircd::fs::aio
size_t write(const fd &, const const_iovec_view &, const write_opts &);
size_t read(const fd &, const const_iovec_view &, const read_opts &);
void fsync(const fd &, const sync_opts &);
size_t fsync(const fd &, const sync_opts &);
}
/// AIO context instance from the system. Right now this is a singleton with
@ -125,18 +125,21 @@ struct ircd::fs::aio::request
ssize_t retval {-2L};
ssize_t errcode {0L};
const struct opts *opts {nullptr};
ctx::dock waiter;
ctx::dock *waiter {nullptr};
bool wait();
public:
const_iovec_view iovec() const;
bool completed() const;
bool queued() const;
bool wait();
size_t operator()();
size_t complete();
void submit();
bool cancel();
request(const int &fd, const struct opts *const &);
request(const int &fd, const struct opts *const &, ctx::dock *const &);
request() = default;
~request() noexcept;
};
@ -144,19 +147,22 @@ struct ircd::fs::aio::request
struct ircd::fs::aio::request::read
:request
{
read(const int &fd, const read_opts &, const const_iovec_view &);
read(ctx::dock &, const int &fd, const read_opts &, const const_iovec_view &);
read() = default;
};
/// Write request control block
struct ircd::fs::aio::request::write
:request
{
write(const int &fd, const write_opts &, const const_iovec_view &);
write(ctx::dock &, const int &fd, const write_opts &, const const_iovec_view &);
write() = default;
};
/// fsync request control block
struct ircd::fs::aio::request::fsync
:request
{
fsync(const int &fd, const sync_opts &);
fsync(ctx::dock &, const int &fd, const sync_opts &);
fsync() = default;
};