Commit f7920221 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Apply clang-format to folly/experimental/io/

Summary: [Folly] Apply `clang-format` to `folly/experimental/io/`.

Reviewed By: Orvid

Differential Revision: D5460571

fbshipit-source-id: d19aff829316dd277e65620196e12db8cad46787
parent 1804caee
...@@ -34,9 +34,7 @@ ...@@ -34,9 +34,7 @@
namespace folly { namespace folly {
AsyncIOOp::AsyncIOOp(NotificationCallback cb) AsyncIOOp::AsyncIOOp(NotificationCallback cb)
: cb_(std::move(cb)), : cb_(std::move(cb)), state_(State::UNINITIALIZED), result_(-EINVAL) {
state_(State::UNINITIALIZED),
result_(-EINVAL) {
memset(&iocb_, 0, sizeof(iocb_)); memset(&iocb_, 0, sizeof(iocb_));
} }
...@@ -142,13 +140,13 @@ void AsyncIO::initializeContext() { ...@@ -142,13 +140,13 @@ void AsyncIO::initializeContext() {
// returns negative errno // returns negative errno
if (rc == -EAGAIN) { if (rc == -EAGAIN) {
long aio_nr, aio_max; long aio_nr, aio_max;
std::unique_ptr<FILE, int(*)(FILE*)> std::unique_ptr<FILE, int (*)(FILE*)> fp(
fp(fopen("/proc/sys/fs/aio-nr", "r"), fclose); fopen("/proc/sys/fs/aio-nr", "r"), fclose);
PCHECK(fp); PCHECK(fp);
CHECK_EQ(fscanf(fp.get(), "%ld", &aio_nr), 1); CHECK_EQ(fscanf(fp.get(), "%ld", &aio_nr), 1);
std::unique_ptr<FILE, int(*)(FILE*)> std::unique_ptr<FILE, int (*)(FILE*)> aio_max_fp(
aio_max_fp(fopen("/proc/sys/fs/aio-max-nr", "r"), fclose); fopen("/proc/sys/fs/aio-max-nr", "r"), fclose);
PCHECK(aio_max_fp); PCHECK(aio_max_fp);
CHECK_EQ(fscanf(aio_max_fp.get(), "%ld", &aio_max), 1); CHECK_EQ(fscanf(aio_max_fp.get(), "%ld", &aio_max), 1);
...@@ -165,7 +163,7 @@ void AsyncIO::initializeContext() { ...@@ -165,7 +163,7 @@ void AsyncIO::initializeContext() {
void AsyncIO::submit(Op* op) { void AsyncIO::submit(Op* op) {
CHECK_EQ(op->state(), Op::State::INITIALIZED); CHECK_EQ(op->state(), Op::State::INITIALIZED);
initializeContext(); // on demand initializeContext(); // on demand
// We can increment past capacity, but we'll clean up after ourselves. // We can increment past capacity, but we'll clean up after ourselves.
auto p = pending_.fetch_add(1, std::memory_order_acq_rel); auto p = pending_.fetch_add(1, std::memory_order_acq_rel);
...@@ -174,7 +172,7 @@ void AsyncIO::submit(Op* op) { ...@@ -174,7 +172,7 @@ void AsyncIO::submit(Op* op) {
throw std::range_error("AsyncIO: too many pending requests"); throw std::range_error("AsyncIO: too many pending requests");
} }
iocb* cb = &op->iocb_; iocb* cb = &op->iocb_;
cb->data = nullptr; // unused cb->data = nullptr; // unused
if (pollFd_ != -1) { if (pollFd_ != -1) {
io_set_eventfd(cb, pollFd_); io_set_eventfd(cb, pollFd_);
} }
...@@ -213,7 +211,7 @@ Range<AsyncIO::Op**> AsyncIO::pollCompleted() { ...@@ -213,7 +211,7 @@ Range<AsyncIO::Op**> AsyncIO::pollCompleted() {
rc = ::read(pollFd_, &numEvents, 8); rc = ::read(pollFd_, &numEvents, 8);
} while (rc == -1 && errno == EINTR); } while (rc == -1 && errno == EINTR);
if (UNLIKELY(rc == -1 && errno == EAGAIN)) { if (UNLIKELY(rc == -1 && errno == EAGAIN)) {
return Range<Op**>(); // nothing completed return Range<Op**>(); // nothing completed
} }
checkUnixError(rc, "AsyncIO: read from event fd failed"); checkUnixError(rc, "AsyncIO: read from event fd failed");
DCHECK_EQ(rc, 8); DCHECK_EQ(rc, 8);
...@@ -241,11 +239,12 @@ Range<AsyncIO::Op**> AsyncIO::doWait( ...@@ -241,11 +239,12 @@ Range<AsyncIO::Op**> AsyncIO::doWait(
// GOTCHA: io_getevents() may returns less than min_nr results if // GOTCHA: io_getevents() may returns less than min_nr results if
// interrupted after some events have been read (if before, -EINTR // interrupted after some events have been read (if before, -EINTR
// is returned). // is returned).
ret = io_getevents(ctx_, ret = io_getevents(
minRequests - count, ctx_,
maxRequests - count, minRequests - count,
events + count, maxRequests - count,
/* timeout */ nullptr); // wait forever events + count,
/* timeout */ nullptr); // wait forever
} while (ret == -EINTR); } while (ret == -EINTR);
// Check as may not be able to recover without leaking events. // Check as may not be able to recover without leaking events.
CHECK_GE(ret, 0) << "AsyncIO: io_getevents failed with error " CHECK_GE(ret, 0) << "AsyncIO: io_getevents failed with error "
...@@ -274,9 +273,7 @@ Range<AsyncIO::Op**> AsyncIO::doWait( ...@@ -274,9 +273,7 @@ Range<AsyncIO::Op**> AsyncIO::doWait(
return range(result); return range(result);
} }
AsyncIOQueue::AsyncIOQueue(AsyncIO* asyncIO) AsyncIOQueue::AsyncIOQueue(AsyncIO* asyncIO) : asyncIO_(asyncIO) {}
: asyncIO_(asyncIO) {
}
AsyncIOQueue::~AsyncIOQueue() { AsyncIOQueue::~AsyncIOQueue() {
CHECK_EQ(asyncIO_->pending(), 0); CHECK_EQ(asyncIO_->pending(), 0);
...@@ -291,7 +288,9 @@ void AsyncIOQueue::submit(OpFactory op) { ...@@ -291,7 +288,9 @@ void AsyncIOQueue::submit(OpFactory op) {
maybeDequeue(); maybeDequeue();
} }
void AsyncIOQueue::onCompleted(AsyncIOOp* /* op */) { maybeDequeue(); } void AsyncIOQueue::onCompleted(AsyncIOOp* /* op */) {
maybeDequeue();
}
void AsyncIOQueue::maybeDequeue() { void AsyncIOQueue::maybeDequeue() {
while (!queue_.empty() && asyncIO_->pending() < asyncIO_->capacity()) { while (!queue_.empty() && asyncIO_->pending() < asyncIO_->capacity()) {
...@@ -303,7 +302,9 @@ void AsyncIOQueue::maybeDequeue() { ...@@ -303,7 +302,9 @@ void AsyncIOQueue::maybeDequeue() {
auto& nextCb = op->notificationCallback(); auto& nextCb = op->notificationCallback();
op->setNotificationCallback([this, nextCb](AsyncIOOp* op2) { op->setNotificationCallback([this, nextCb](AsyncIOOp* op2) {
this->onCompleted(op2); this->onCompleted(op2);
if (nextCb) nextCb(op2); if (nextCb) {
nextCb(op2);
}
}); });
asyncIO_->submit(op); asyncIO_->submit(op);
...@@ -314,7 +315,9 @@ void AsyncIOQueue::maybeDequeue() { ...@@ -314,7 +315,9 @@ void AsyncIOQueue::maybeDequeue() {
namespace { namespace {
#define X(c) case c: return #c #define X(c) \
case c: \
return #c
const char* asyncIoOpStateToString(AsyncIOOp::State state) { const char* asyncIoOpStateToString(AsyncIOOp::State state) {
switch (state) { switch (state) {
...@@ -348,21 +351,28 @@ std::string fd2name(int fd) { ...@@ -348,21 +351,28 @@ std::string fd2name(int fd) {
std::string path = folly::to<std::string>("/proc/self/fd/", fd); std::string path = folly::to<std::string>("/proc/self/fd/", fd);
char link[PATH_MAX]; char link[PATH_MAX];
const ssize_t length = const ssize_t length =
std::max<ssize_t>(readlink(path.c_str(), link, PATH_MAX), 0); std::max<ssize_t>(readlink(path.c_str(), link, PATH_MAX), 0);
return path.assign(link, length); return path.assign(link, length);
} }
std::ostream& operator<<(std::ostream& os, const iocb& cb) { std::ostream& operator<<(std::ostream& os, const iocb& cb) {
os << folly::format( os << folly::format(
"data={}, key={}, opcode={}, reqprio={}, fd={}, f={}, ", "data={}, key={}, opcode={}, reqprio={}, fd={}, f={}, ",
cb.data, cb.key, iocbCmdToString(cb.aio_lio_opcode), cb.data,
cb.aio_reqprio, cb.aio_fildes, fd2name(cb.aio_fildes)); cb.key,
iocbCmdToString(cb.aio_lio_opcode),
cb.aio_reqprio,
cb.aio_fildes,
fd2name(cb.aio_fildes));
switch (cb.aio_lio_opcode) { switch (cb.aio_lio_opcode) {
case IO_CMD_PREAD: case IO_CMD_PREAD:
case IO_CMD_PWRITE: case IO_CMD_PWRITE:
os << folly::format("buf={}, offset={}, nbytes={}, ", os << folly::format(
cb.u.c.buf, cb.u.c.offset, cb.u.c.nbytes); "buf={}, offset={}, nbytes={}, ",
cb.u.c.buf,
cb.u.c.offset,
cb.u.c.nbytes);
break; break;
default: default:
os << "[TODO: write debug string for " os << "[TODO: write debug string for "
...@@ -373,7 +383,7 @@ std::ostream& operator<<(std::ostream& os, const iocb& cb) { ...@@ -373,7 +383,7 @@ std::ostream& operator<<(std::ostream& os, const iocb& cb) {
return os; return os;
} }
} // anonymous namespace } // anonymous namespace
std::ostream& operator<<(std::ostream& os, const AsyncIOOp& op) { std::ostream& operator<<(std::ostream& os, const AsyncIOOp& op) {
os << "{" << op.state_ << ", "; os << "{" << op.state_ << ", ";
...@@ -397,4 +407,4 @@ std::ostream& operator<<(std::ostream& os, AsyncIOOp::State state) { ...@@ -397,4 +407,4 @@ std::ostream& operator<<(std::ostream& os, AsyncIOOp::State state) {
return os << asyncIoOpStateToString(state); return os << asyncIoOpStateToString(state);
} }
} // namespace folly } // namespace folly
...@@ -77,7 +77,9 @@ class AsyncIOOp : private boost::noncopyable { ...@@ -77,7 +77,9 @@ class AsyncIOOp : private boost::noncopyable {
/** /**
* Return the current operation state. * Return the current operation state.
*/ */
State state() const { return state_; } State state() const {
return state_;
}
/** /**
* Reset the operation for reuse. It is an error to call reset() on * Reset the operation for reuse. It is an error to call reset() on
...@@ -85,8 +87,12 @@ class AsyncIOOp : private boost::noncopyable { ...@@ -85,8 +87,12 @@ class AsyncIOOp : private boost::noncopyable {
*/ */
void reset(NotificationCallback cb = NotificationCallback()); void reset(NotificationCallback cb = NotificationCallback());
void setNotificationCallback(NotificationCallback cb) { cb_ = std::move(cb); } void setNotificationCallback(NotificationCallback cb) {
const NotificationCallback& notificationCallback() const { return cb_; } cb_ = std::move(cb);
}
const NotificationCallback& notificationCallback() const {
return cb_;
}
/** /**
* Retrieve the result of this operation. Returns >=0 on success, * Retrieve the result of this operation. Returns >=0 on success,
...@@ -164,26 +170,34 @@ class AsyncIO : private boost::noncopyable { ...@@ -164,26 +170,34 @@ class AsyncIO : private boost::noncopyable {
/** /**
* Return the number of pending requests. * Return the number of pending requests.
*/ */
size_t pending() const { return pending_; } size_t pending() const {
return pending_;
}
/** /**
* Return the maximum number of requests that can be kept outstanding * Return the maximum number of requests that can be kept outstanding
* at any one time. * at any one time.
*/ */
size_t capacity() const { return capacity_; } size_t capacity() const {
return capacity_;
}
/** /**
* Return the accumulative number of submitted I/O, since this object * Return the accumulative number of submitted I/O, since this object
* has been created. * has been created.
*/ */
size_t totalSubmits() const { return submitted_; } size_t totalSubmits() const {
return submitted_;
}
/** /**
* If POLLABLE, return a file descriptor that can be passed to poll / epoll * If POLLABLE, return a file descriptor that can be passed to poll / epoll
* and will become readable when any async IO operations have completed. * and will become readable when any async IO operations have completed.
* If NOT_POLLABLE, return -1. * If NOT_POLLABLE, return -1.
*/ */
int pollFd() const { return pollFd_; } int pollFd() const {
return pollFd_;
}
/** /**
* If POLLABLE, call instead of wait after the file descriptor returned * If POLLABLE, call instead of wait after the file descriptor returned
...@@ -235,7 +249,9 @@ class AsyncIOQueue { ...@@ -235,7 +249,9 @@ class AsyncIOQueue {
explicit AsyncIOQueue(AsyncIO* asyncIO); explicit AsyncIOQueue(AsyncIO* asyncIO);
~AsyncIOQueue(); ~AsyncIOQueue();
size_t queued() const { return queue_.size(); } size_t queued() const {
return queue_.size();
}
/** /**
* Submit an op to the AsyncIO queue. The op will be queued until * Submit an op to the AsyncIO queue. The op will be queued until
...@@ -260,4 +276,4 @@ class AsyncIOQueue { ...@@ -260,4 +276,4 @@ class AsyncIOQueue {
std::deque<OpFactory> queue_; std::deque<OpFactory> queue_;
}; };
} // namespace folly } // namespace folly
...@@ -40,7 +40,7 @@ bool skipPrefix(const path& pth, const path& prefix, path::const_iterator& it) { ...@@ -40,7 +40,7 @@ bool skipPrefix(const path& pth, const path& prefix, path::const_iterator& it) {
} }
return true; return true;
} }
} // namespace } // namespace
bool starts_with(const path& pth, const path& prefix) { bool starts_with(const path& pth, const path& prefix) {
path::const_iterator it; path::const_iterator it;
...@@ -52,7 +52,8 @@ path remove_prefix(const path& pth, const path& prefix) { ...@@ -52,7 +52,8 @@ path remove_prefix(const path& pth, const path& prefix) {
if (!skipPrefix(pth, prefix, it)) { if (!skipPrefix(pth, prefix, it)) {
throw filesystem_error( throw filesystem_error(
"Path does not start with prefix", "Path does not start with prefix",
pth, prefix, pth,
prefix,
bsys::errc::make_error_code(bsys::errc::invalid_argument)); bsys::errc::make_error_code(bsys::errc::invalid_argument));
} }
...@@ -72,5 +73,5 @@ path executable_path() { ...@@ -72,5 +73,5 @@ path executable_path() {
return read_symlink("/proc/self/exe"); return read_symlink("/proc/self/exe");
} }
} // namespace fs } // namespace fs
} // namespace folly } // namespace folly
...@@ -65,5 +65,5 @@ path canonical_parent(const path& p, const path& basePath = current_path()); ...@@ -65,5 +65,5 @@ path canonical_parent(const path& p, const path& basePath = current_path());
*/ */
path executable_path(); path executable_path();
} // namespace fs } // namespace fs
} // namespace folly } // namespace folly
...@@ -56,16 +56,19 @@ void list() { ...@@ -56,16 +56,19 @@ void list() {
} }
} }
} // namespace } // namespace
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_cp) { if (FLAGS_cp) {
if (argc != 3) usage(argv[0]); if (argc != 3) {
usage(argv[0]);
}
copy(argv[1], argv[2]); copy(argv[1], argv[2]);
} else { } else {
if (argc != 1) usage(argv[0]); if (argc != 1) {
usage(argv[0]);
}
list(); list();
} }
return 0; return 0;
......
...@@ -50,16 +50,15 @@ size_t getDefaultHugePageSize() { ...@@ -50,16 +50,15 @@ size_t getDefaultHugePageSize() {
size_t pageSize = 0; size_t pageSize = 0;
boost::cmatch match; boost::cmatch match;
bool error = gen::byLine("/proc/meminfo") | bool error = gen::byLine("/proc/meminfo") | [&](StringPiece line) -> bool {
[&] (StringPiece line) -> bool { if (boost::regex_match(line.begin(), line.end(), match, regex)) {
if (boost::regex_match(line.begin(), line.end(), match, regex)) { StringPiece numStr(
StringPiece numStr( line.begin() + match.position(1), size_t(match.length(1)));
line.begin() + match.position(1), size_t(match.length(1))); pageSize = to<size_t>(numStr) * 1024; // in KiB
pageSize = to<size_t>(numStr) * 1024; // in KiB return false; // stop
return false; // stop }
} return true;
return true; };
};
if (error) { if (error) {
throw std::runtime_error("Can't find default huge page size"); throw std::runtime_error("Can't find default huge page size");
...@@ -123,7 +122,7 @@ size_t parsePageSizeValue(StringPiece value) { ...@@ -123,7 +122,7 @@ size_t parsePageSizeValue(StringPiece value) {
HugePageSizeVec readHugePageSizes() { HugePageSizeVec readHugePageSizes() {
HugePageSizeVec sizeVec = readRawHugePageSizes(); HugePageSizeVec sizeVec = readRawHugePageSizes();
if (sizeVec.empty()) { if (sizeVec.empty()) {
return sizeVec; // nothing to do return sizeVec; // nothing to do
} }
std::sort(sizeVec.begin(), sizeVec.end()); std::sort(sizeVec.begin(), sizeVec.end());
...@@ -143,61 +142,61 @@ HugePageSizeVec readHugePageSizes() { ...@@ -143,61 +142,61 @@ HugePageSizeVec readHugePageSizes() {
std::vector<StringPiece> options; std::vector<StringPiece> options;
gen::byLine("/proc/mounts") | gen::eachAs<StringPiece>() | gen::byLine("/proc/mounts") | gen::eachAs<StringPiece>() |
[&](StringPiece line) { [&](StringPiece line) {
parts.clear(); parts.clear();
split(" ", line, parts); split(" ", line, parts);
// device path fstype options uid gid // device path fstype options uid gid
if (parts.size() != 6) { if (parts.size() != 6) {
throw std::runtime_error("Invalid /proc/mounts line"); throw std::runtime_error("Invalid /proc/mounts line");
} }
if (parts[2] != "hugetlbfs") { if (parts[2] != "hugetlbfs") {
return; // we only care about hugetlbfs return; // we only care about hugetlbfs
} }
options.clear(); options.clear();
split(",", parts[3], options); split(",", parts[3], options);
size_t pageSize = defaultHugePageSize; size_t pageSize = defaultHugePageSize;
// Search for the "pagesize" option, which must have a value // Search for the "pagesize" option, which must have a value
for (auto& option : options) { for (auto& option : options) {
// key=value // key=value
const char* p = static_cast<const char*>( const char* p = static_cast<const char*>(
memchr(option.data(), '=', option.size())); memchr(option.data(), '=', option.size()));
if (!p) { if (!p) {
continue; continue;
}
if (StringPiece(option.data(), p) != "pagesize") {
continue;
}
pageSize = parsePageSizeValue(StringPiece(p + 1, option.end()));
break;
}
auto pos = std::lower_bound(
sizeVec.begin(), sizeVec.end(), pageSize, PageSizeLess());
if (pos == sizeVec.end() || pos->size != pageSize) {
throw std::runtime_error("Mount page size not found");
} }
if (StringPiece(option.data(), p) != "pagesize") { if (!pos->mountPoint.empty()) {
continue; // Only one mount point per page size is allowed
return;
}
// Store mount point
fs::path path(parts[1].begin(), parts[1].end());
struct stat st;
const int ret = stat(path.string().c_str(), &st);
if (ret == -1 && errno == ENOENT) {
return;
} }
pageSize = parsePageSizeValue(StringPiece(p + 1, option.end())); checkUnixError(ret, "stat hugepage mountpoint failed");
break; pos->mountPoint = fs::canonical(path);
} pos->device = st.st_dev;
};
auto pos = std::lower_bound(sizeVec.begin(), sizeVec.end(), pageSize,
PageSizeLess());
if (pos == sizeVec.end() || pos->size != pageSize) {
throw std::runtime_error("Mount page size not found");
}
if (!pos->mountPoint.empty()) {
// Only one mount point per page size is allowed
return;
}
// Store mount point
fs::path path(parts[1].begin(), parts[1].end());
struct stat st;
const int ret = stat(path.string().c_str(), &st);
if (ret == -1 && errno == ENOENT) {
return;
}
checkUnixError(ret, "stat hugepage mountpoint failed");
pos->mountPoint = fs::canonical(path);
pos->device = st.st_dev;
};
return sizeVec; return sizeVec;
} }
} // namespace } // namespace
const HugePageSizeVec& getHugePageSizes() { const HugePageSizeVec& getHugePageSizes() {
static HugePageSizeVec sizes = readHugePageSizes(); static HugePageSizeVec sizes = readHugePageSizes();
...@@ -230,4 +229,4 @@ const HugePageSize* getHugePageSizeForDevice(dev_t device) { ...@@ -230,4 +229,4 @@ const HugePageSize* getHugePageSizeForDevice(dev_t device) {
return nullptr; return nullptr;
} }
} // namespace folly } // namespace folly
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
namespace folly { namespace folly {
struct HugePageSize : private boost::totally_ordered<HugePageSize> { struct HugePageSize : private boost::totally_ordered<HugePageSize> {
explicit HugePageSize(size_t s) : size(s) { } explicit HugePageSize(size_t s) : size(s) {}
fs::path filePath(const fs::path& relpath) const { fs::path filePath(const fs::path& relpath) const {
return mountPoint / relpath; return mountPoint / relpath;
...@@ -77,4 +77,4 @@ const HugePageSize* getHugePageSize(size_t size = 0); ...@@ -77,4 +77,4 @@ const HugePageSize* getHugePageSize(size_t size = 0);
*/ */
const HugePageSize* getHugePageSizeForDevice(dev_t device); const HugePageSize* getHugePageSizeForDevice(dev_t device);
} // namespace folly } // namespace folly
...@@ -43,7 +43,7 @@ using folly::AsyncIOQueue; ...@@ -43,7 +43,7 @@ using folly::AsyncIOQueue;
namespace { namespace {
constexpr size_t kAlign = 4096; // align reads to 4096 B (for O_DIRECT) constexpr size_t kAlign = 4096; // align reads to 4096 B (for O_DIRECT)
struct TestSpec { struct TestSpec {
off_t start; off_t start;
...@@ -57,10 +57,10 @@ void waitUntilReadable(int fd) { ...@@ -57,10 +57,10 @@ void waitUntilReadable(int fd) {
int r; int r;
do { do {
r = poll(&pfd, 1, -1); // wait forever r = poll(&pfd, 1, -1); // wait forever
} while (r == -1 && errno == EINTR); } while (r == -1 && errno == EINTR);
PCHECK(r == 1); PCHECK(r == 1);
CHECK_EQ(pfd.revents, POLLIN); // no errors etc CHECK_EQ(pfd.revents, POLLIN); // no errors etc
} }
folly::Range<AsyncIO::Op**> readerWait(AsyncIO* reader) { folly::Range<AsyncIO::Op**> readerWait(AsyncIO* reader) {
...@@ -80,7 +80,9 @@ class TemporaryFile { ...@@ -80,7 +80,9 @@ class TemporaryFile {
explicit TemporaryFile(size_t size); explicit TemporaryFile(size_t size);
~TemporaryFile(); ~TemporaryFile();
const fs::path path() const { return path_; } const fs::path path() const {
return path_;
}
private: private:
fs::path path_; fs::path path_;
...@@ -118,9 +120,9 @@ TemporaryFile::~TemporaryFile() { ...@@ -118,9 +120,9 @@ TemporaryFile::~TemporaryFile() {
} }
} }
TemporaryFile tempFile(6 << 20); // 6MiB TemporaryFile tempFile(6 << 20); // 6MiB
typedef std::unique_ptr<char, void(*)(void*)> ManagedBuffer; typedef std::unique_ptr<char, void (*)(void*)> ManagedBuffer;
ManagedBuffer allocateAligned(size_t size) { ManagedBuffer allocateAligned(size_t size) {
void* buf; void* buf;
int rc = posix_memalign(&buf, kAlign, size); int rc = posix_memalign(&buf, kAlign, size);
...@@ -128,8 +130,9 @@ ManagedBuffer allocateAligned(size_t size) { ...@@ -128,8 +130,9 @@ ManagedBuffer allocateAligned(size_t size) {
return ManagedBuffer(reinterpret_cast<char*>(buf), free); return ManagedBuffer(reinterpret_cast<char*>(buf), free);
} }
void testReadsSerially(const std::vector<TestSpec>& specs, void testReadsSerially(
AsyncIO::PollMode pollMode) { const std::vector<TestSpec>& specs,
AsyncIO::PollMode pollMode) {
AsyncIO aioReader(1, pollMode); AsyncIO aioReader(1, pollMode);
AsyncIO::Op op; AsyncIO::Op op;
int fd = ::open(tempFile.path().c_str(), O_DIRECT | O_RDONLY); int fd = ::open(tempFile.path().c_str(), O_DIRECT | O_RDONLY);
...@@ -155,9 +158,10 @@ void testReadsSerially(const std::vector<TestSpec>& specs, ...@@ -155,9 +158,10 @@ void testReadsSerially(const std::vector<TestSpec>& specs,
} }
} }
void testReadsParallel(const std::vector<TestSpec>& specs, void testReadsParallel(
AsyncIO::PollMode pollMode, const std::vector<TestSpec>& specs,
bool multithreaded) { AsyncIO::PollMode pollMode,
bool multithreaded) {
AsyncIO aioReader(specs.size(), pollMode); AsyncIO aioReader(specs.size(), pollMode);
std::unique_ptr<AsyncIO::Op[]> ops(new AsyncIO::Op[specs.size()]); std::unique_ptr<AsyncIO::Op[]> ops(new AsyncIO::Op[specs.size()]);
std::vector<ManagedBuffer> bufs; std::vector<ManagedBuffer> bufs;
...@@ -176,7 +180,7 @@ void testReadsParallel(const std::vector<TestSpec>& specs, ...@@ -176,7 +180,7 @@ void testReadsParallel(const std::vector<TestSpec>& specs,
for (size_t i = 0; i < specs.size(); i++) { for (size_t i = 0; i < specs.size(); i++) {
bufs.push_back(allocateAligned(specs[i].size)); bufs.push_back(allocateAligned(specs[i].size));
} }
auto submit = [&] (size_t i) { auto submit = [&](size_t i) {
ops[i].pread(fd, bufs[i].get(), specs[i].size, specs[i].start); ops[i].pread(fd, bufs[i].get(), specs[i].size, specs[i].start);
aioReader.submit(&ops[i]); aioReader.submit(&ops[i]);
}; };
...@@ -219,8 +223,9 @@ void testReadsParallel(const std::vector<TestSpec>& specs, ...@@ -219,8 +223,9 @@ void testReadsParallel(const std::vector<TestSpec>& specs,
} }
} }
void testReadsQueued(const std::vector<TestSpec>& specs, void testReadsQueued(
AsyncIO::PollMode pollMode) { const std::vector<TestSpec>& specs,
AsyncIO::PollMode pollMode) {
size_t readerCapacity = std::max(specs.size() / 2, size_t(1)); size_t readerCapacity = std::max(specs.size() / 2, size_t(1));
AsyncIO aioReader(readerCapacity, pollMode); AsyncIO aioReader(readerCapacity, pollMode);
AsyncIOQueue aioQueue(&aioReader); AsyncIOQueue aioQueue(&aioReader);
...@@ -272,15 +277,14 @@ void testReadsQueued(const std::vector<TestSpec>& specs, ...@@ -272,15 +277,14 @@ void testReadsQueued(const std::vector<TestSpec>& specs,
} }
} }
void testReads(const std::vector<TestSpec>& specs, void testReads(const std::vector<TestSpec>& specs, AsyncIO::PollMode pollMode) {
AsyncIO::PollMode pollMode) {
testReadsSerially(specs, pollMode); testReadsSerially(specs, pollMode);
testReadsParallel(specs, pollMode, false); testReadsParallel(specs, pollMode, false);
testReadsParallel(specs, pollMode, true); testReadsParallel(specs, pollMode, true);
testReadsQueued(specs, pollMode); testReadsQueued(specs, pollMode);
} }
} // anonymous namespace } // anonymous namespace
TEST(AsyncIO, ZeroAsyncDataNotPollable) { TEST(AsyncIO, ZeroAsyncDataNotPollable) {
testReads({{0, 0}}, AsyncIO::NOT_POLLABLE); testReads({{0, 0}}, AsyncIO::NOT_POLLABLE);
...@@ -302,46 +306,46 @@ TEST(AsyncIO, SingleAsyncDataPollable) { ...@@ -302,46 +306,46 @@ TEST(AsyncIO, SingleAsyncDataPollable) {
TEST(AsyncIO, MultipleAsyncDataNotPollable) { TEST(AsyncIO, MultipleAsyncDataNotPollable) {
testReads( testReads(
{{kAlign, 2*kAlign}, {kAlign, 2*kAlign}, {kAlign, 4*kAlign}}, {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
AsyncIO::NOT_POLLABLE); AsyncIO::NOT_POLLABLE);
testReads( testReads(
{{kAlign, 2*kAlign}, {kAlign, 2*kAlign}, {kAlign, 4*kAlign}}, {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
AsyncIO::NOT_POLLABLE); AsyncIO::NOT_POLLABLE);
testReads({ testReads(
{0, 5*1024*1024}, {{0, 5 * 1024 * 1024}, {kAlign, 5 * 1024 * 1024}}, AsyncIO::NOT_POLLABLE);
{kAlign, 5*1024*1024}
}, AsyncIO::NOT_POLLABLE); testReads(
{
testReads({ {kAlign, 0},
{kAlign, 0}, {kAlign, kAlign},
{kAlign, kAlign}, {kAlign, 2 * kAlign},
{kAlign, 2*kAlign}, {kAlign, 20 * kAlign},
{kAlign, 20*kAlign}, {kAlign, 1024 * 1024},
{kAlign, 1024*1024}, },
}, AsyncIO::NOT_POLLABLE); AsyncIO::NOT_POLLABLE);
} }
TEST(AsyncIO, MultipleAsyncDataPollable) { TEST(AsyncIO, MultipleAsyncDataPollable) {
testReads( testReads(
{{kAlign, 2*kAlign}, {kAlign, 2*kAlign}, {kAlign, 4*kAlign}}, {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
AsyncIO::POLLABLE); AsyncIO::POLLABLE);
testReads( testReads(
{{kAlign, 2*kAlign}, {kAlign, 2*kAlign}, {kAlign, 4*kAlign}}, {{kAlign, 2 * kAlign}, {kAlign, 2 * kAlign}, {kAlign, 4 * kAlign}},
AsyncIO::POLLABLE); AsyncIO::POLLABLE);
testReads({ testReads(
{0, 5*1024*1024}, {{0, 5 * 1024 * 1024}, {kAlign, 5 * 1024 * 1024}}, AsyncIO::NOT_POLLABLE);
{kAlign, 5*1024*1024}
}, AsyncIO::NOT_POLLABLE); testReads(
{
testReads({ {kAlign, 0},
{kAlign, 0}, {kAlign, kAlign},
{kAlign, kAlign}, {kAlign, 2 * kAlign},
{kAlign, 2*kAlign}, {kAlign, 20 * kAlign},
{kAlign, 20*kAlign}, {kAlign, 1024 * 1024},
{kAlign, 1024*1024}, },
}, AsyncIO::NOT_POLLABLE); AsyncIO::NOT_POLLABLE);
} }
TEST(AsyncIO, ManyAsyncDataNotPollable) { TEST(AsyncIO, ManyAsyncDataNotPollable) {
......
...@@ -31,7 +31,7 @@ namespace { ...@@ -31,7 +31,7 @@ namespace {
void expectPathEq(const path& a, const path& b) { void expectPathEq(const path& a, const path& b) {
EXPECT_TRUE(a == b) << "expected path=" << a << "\nactual path=" << b; EXPECT_TRUE(a == b) << "expected path=" << a << "\nactual path=" << b;
} }
} // namespace } // namespace
TEST(Simple, Path) { TEST(Simple, Path) {
path root("/"); path root("/");
...@@ -40,7 +40,7 @@ TEST(Simple, Path) { ...@@ -40,7 +40,7 @@ TEST(Simple, Path) {
EXPECT_TRUE(starts_with(abs1, root)); EXPECT_TRUE(starts_with(abs1, root));
EXPECT_FALSE(starts_with(rel1, root)); EXPECT_FALSE(starts_with(rel1, root));
expectPathEq(path("hello/world"), remove_prefix(abs1, root)); expectPathEq(path("hello/world"), remove_prefix(abs1, root));
EXPECT_THROW({remove_prefix(rel1, root);}, filesystem_error); EXPECT_THROW({ remove_prefix(rel1, root); }, filesystem_error);
path abs2("/hello"); path abs2("/hello");
path abs3("/hello/"); path abs3("/hello/");
...@@ -55,8 +55,8 @@ TEST(Simple, Path) { ...@@ -55,8 +55,8 @@ TEST(Simple, Path) {
expectPathEq(path("world"), remove_prefix(abs1, abs2)); expectPathEq(path("world"), remove_prefix(abs1, abs2));
expectPathEq(path("world"), remove_prefix(abs1, abs3)); expectPathEq(path("world"), remove_prefix(abs1, abs3));
expectPathEq(path(), remove_prefix(abs1, abs4)); expectPathEq(path(), remove_prefix(abs1, abs4));
EXPECT_THROW({remove_prefix(abs1, abs5);}, filesystem_error); EXPECT_THROW({ remove_prefix(abs1, abs5); }, filesystem_error);
EXPECT_THROW({remove_prefix(abs1, abs6);}, filesystem_error); EXPECT_THROW({ remove_prefix(abs1, abs6); }, filesystem_error);
} }
TEST(Simple, CanonicalizeParent) { TEST(Simple, CanonicalizeParent) {
...@@ -69,8 +69,8 @@ TEST(Simple, CanonicalizeParent) { ...@@ -69,8 +69,8 @@ TEST(Simple, CanonicalizeParent) {
expectPathEq(a, canonical_parent(b)); expectPathEq(a, canonical_parent(b));
expectPathEq(a, canonical(b)); expectPathEq(a, canonical(b));
expectPathEq(a, canonical_parent(b)); expectPathEq(a, canonical_parent(b));
EXPECT_THROW({canonical(c);}, filesystem_error); EXPECT_THROW({ canonical(c); }, filesystem_error);
EXPECT_THROW({canonical(d);}, filesystem_error); EXPECT_THROW({ canonical(d); }, filesystem_error);
expectPathEq(c, canonical_parent(c)); expectPathEq(c, canonical_parent(c));
expectPathEq(c, canonical_parent(d)); expectPathEq(c, canonical_parent(d));
} }
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