From 2e729a6c6d6d6fef94c6c9fa48826ec313a46fd9 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Mon, 21 Dec 2020 16:26:54 +0000 Subject: Add statfs_t::f_iosinprogress and statfs_t::f_ioswaittime which can be used to monitor how congested the underlying hardware device for a handle is. --- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 491 ++++++++++++++++-------- 1 file changed, 334 insertions(+), 157 deletions(-) (limited to 'include/llfio/v2.0/detail/impl/posix/statfs.ipp') diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index a853a418..8b2ebcf3 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -25,10 +25,15 @@ Distributed under the Boost Software License, Version 1.0. #include "../../../handle.hpp" #include "../../../statfs.hpp" +#include +#include +#include + #include #ifdef __linux__ #include #include +#include #endif LLFIO_V2_NAMESPACE_BEGIN @@ -37,186 +42,189 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s { size_t ret = 0; #ifdef __linux__ - struct statfs64 s - { - }; - memset(&s, 0, sizeof(s)); - if(-1 == fstatfs64(h.native_handle().fd, &s)) - { - return posix_error(); - } - if(!!(wanted & want::bsize)) + if(!!(wanted & ~(want::iosinprogress | want::ioswaittime))) { - f_bsize = s.f_bsize; - ++ret; - } - if(!!(wanted & want::iosize)) - { - f_iosize = s.f_frsize; - ++ret; - } - if(!!(wanted & want::blocks)) - { - f_blocks = s.f_blocks; - ++ret; - } - if(!!(wanted & want::bfree)) - { - f_bfree = s.f_bfree; - ++ret; - } - if(!!(wanted & want::bavail)) - { - f_bavail = s.f_bavail; - ++ret; - } - if(!!(wanted & want::files)) - { - f_files = s.f_files; - ++ret; - } - if(!!(wanted & want::ffree)) - { - f_ffree = s.f_ffree; - ++ret; - } - if(!!(wanted & want::namemax)) - { - f_namemax = s.f_namelen; - ++ret; - } - // if(!!(wanted&&want::owner)) { f_owner =s.f_owner; ++ret; } - if(!!(wanted & want::fsid)) - { - f_fsid[0] = static_cast(s.f_fsid.__val[0]); - f_fsid[1] = static_cast(s.f_fsid.__val[1]); - ++ret; - } - if(!!(wanted & want::flags) || !!(wanted & want::fstypename) || !!(wanted & want::mntfromname) || !!(wanted & want::mntonname)) - { - try + struct statfs64 s { - struct mountentry - { - std::string mnt_fsname, mnt_dir, mnt_type, mnt_opts; - mountentry(const char *a, const char *b, const char *c, const char *d) - : mnt_fsname(a) - , mnt_dir(b) - , mnt_type(c) - , mnt_opts(d) - { - } - }; - std::vector> mountentries; + }; + memset(&s, 0, sizeof(s)); + if(-1 == fstatfs64(h.native_handle().fd, &s)) + { + return posix_error(); + } + if(!!(wanted & want::bsize)) + { + f_bsize = s.f_bsize; + ++ret; + } + if(!!(wanted & want::iosize)) + { + f_iosize = s.f_frsize; + ++ret; + } + if(!!(wanted & want::blocks)) + { + f_blocks = s.f_blocks; + ++ret; + } + if(!!(wanted & want::bfree)) + { + f_bfree = s.f_bfree; + ++ret; + } + if(!!(wanted & want::bavail)) + { + f_bavail = s.f_bavail; + ++ret; + } + if(!!(wanted & want::files)) + { + f_files = s.f_files; + ++ret; + } + if(!!(wanted & want::ffree)) + { + f_ffree = s.f_ffree; + ++ret; + } + if(!!(wanted & want::namemax)) + { + f_namemax = s.f_namelen; + ++ret; + } + // if(!!(wanted&&want::owner)) { f_owner =s.f_owner; ++ret; } + if(!!(wanted & want::fsid)) + { + f_fsid[0] = static_cast(s.f_fsid.__val[0]); + f_fsid[1] = static_cast(s.f_fsid.__val[1]); + ++ret; + } + if(!!(wanted & want::flags) || !!(wanted & want::fstypename) || !!(wanted & want::mntfromname) || !!(wanted & want::mntonname)) + { + try { - // Need to parse mount options on Linux - FILE *mtab = setmntent("/etc/mtab", "r"); - if(mtab == nullptr) - { - mtab = setmntent("/proc/mounts", "r"); - } - if(mtab == nullptr) - { - return posix_error(); - } - auto unmtab = make_scope_exit([mtab]() noexcept { endmntent(mtab); }); - struct mntent m + struct mountentry { + std::string mnt_fsname, mnt_dir, mnt_type, mnt_opts; + mountentry(const char *a, const char *b, const char *c, const char *d) + : mnt_fsname(a) + , mnt_dir(b) + , mnt_type(c) + , mnt_opts(d) + { + } }; - char buffer[32768]; - while(getmntent_r(mtab, &m, buffer, sizeof(buffer)) != nullptr) + std::vector> mountentries; { - struct statfs64 temp + // Need to parse mount options on Linux + FILE *mtab = setmntent("/etc/mtab", "r"); + if(mtab == nullptr) + { + mtab = setmntent("/proc/mounts", "r"); + } + if(mtab == nullptr) + { + return posix_error(); + } + auto unmtab = make_scope_exit([mtab]() noexcept { endmntent(mtab); }); + struct mntent m { }; - memset(&temp, 0, sizeof(temp)); - // std::cout << m.mnt_fsname << "," << m.mnt_dir << "," << m.mnt_type << "," << m.mnt_opts << std::endl; - if(0 == statfs64(m.mnt_dir, &temp)) + char buffer[32768]; + while(getmntent_r(mtab, &m, buffer, sizeof(buffer)) != nullptr) { - // std::cout << " " << temp.f_fsid.__val[0] << temp.f_fsid.__val[1] << " =? " << s.f_fsid.__val[0] << s.f_fsid.__val[1] << std::endl; - if(temp.f_type == s.f_type && (memcmp(&temp.f_fsid, &s.f_fsid, sizeof(s.f_fsid)) == 0)) + struct statfs64 temp + { + }; + memset(&temp, 0, sizeof(temp)); + // std::cout << m.mnt_fsname << "," << m.mnt_dir << "," << m.mnt_type << "," << m.mnt_opts << std::endl; + if(0 == statfs64(m.mnt_dir, &temp)) { - mountentries.emplace_back(mountentry(m.mnt_fsname, m.mnt_dir, m.mnt_type, m.mnt_opts), temp); + // std::cout << " " << temp.f_fsid.__val[0] << temp.f_fsid.__val[1] << " =? " << s.f_fsid.__val[0] << s.f_fsid.__val[1] << std::endl; + if(temp.f_type == s.f_type && (memcmp(&temp.f_fsid, &s.f_fsid, sizeof(s.f_fsid)) == 0)) + { + mountentries.emplace_back(mountentry(m.mnt_fsname, m.mnt_dir, m.mnt_type, m.mnt_opts), temp); + } } } } - } #ifndef LLFIO_COMPILING_FOR_GCOV - if(mountentries.empty()) - { - return errc::no_such_file_or_directory; - } - /* Choose the mount entry with the most closely matching statfs. You can't choose - exclusively based on mount point because of bind mounts. Note that we have a - particular problem in Docker: + if(mountentries.empty()) + { + return errc::no_such_file_or_directory; + } + /* Choose the mount entry with the most closely matching statfs. You can't choose + exclusively based on mount point because of bind mounts. Note that we have a + particular problem in Docker: - rootfs / rootfs rw 0 0 - overlay / overlay rw,relatime,lowerdir=... 0 0 - /dev/sda3 /etc xfs rw,relatime,... 0 0 - tmpfs /dev tmpfs rw,nosuid,... 0 0 - tmpfs /proc/acpi tmpfs rw,nosuid,... 0 0 - ... + rootfs / rootfs rw 0 0 + overlay / overlay rw,relatime,lowerdir=... 0 0 + /dev/sda3 /etc xfs rw,relatime,... 0 0 + tmpfs /dev tmpfs rw,nosuid,... 0 0 + tmpfs /proc/acpi tmpfs rw,nosuid,... 0 0 + ... - If f_type and f_fsid are identical for the statfs for the mount as for our file, - then you will get multiple mountentries, and there is no obvious way of - disambiguating them. What we do is match mount based on the longest match - of the mount point with the current path of our file. - */ - if(mountentries.size() > 1) - { - OUTCOME_TRY(auto &¤tfilepath_, h.current_path()); - string_view currentfilepath(currentfilepath_.native()); - std::vector> scores(mountentries.size()); - //std::cout << "*** For matching mount entries to file with path " << currentfilepath << ":\n"; - for(size_t n = 0; n < mountentries.size(); n++) + If f_type and f_fsid are identical for the statfs for the mount as for our file, + then you will get multiple mountentries, and there is no obvious way of + disambiguating them. What we do is match mount based on the longest match + of the mount point with the current path of our file. + */ + if(mountentries.size() > 1) { - scores[n].first = - (currentfilepath.substr(0, mountentries[n].first.mnt_dir.size()) == mountentries[n].first.mnt_dir) ? mountentries[n].first.mnt_dir.size() : 0; - //std::cout << "*** Mount entry " << mountentries[n].first.mnt_dir << " get score " << scores[n].first << std::endl; - scores[n].second = n; + OUTCOME_TRY(auto currentfilepath_, h.current_path()); + string_view currentfilepath(currentfilepath_.native()); + std::vector> scores(mountentries.size()); + // std::cout << "*** For matching mount entries to file with path " << currentfilepath << ":\n"; + for(size_t n = 0; n < mountentries.size(); n++) + { + scores[n].first = + (currentfilepath.substr(0, mountentries[n].first.mnt_dir.size()) == mountentries[n].first.mnt_dir) ? mountentries[n].first.mnt_dir.size() : 0; + // std::cout << "*** Mount entry " << mountentries[n].first.mnt_dir << " get score " << scores[n].first << std::endl; + scores[n].second = n; + } + std::sort(scores.begin(), scores.end()); + // Choose the item whose mnt_dir most matched the current path for our file. + auto temp(std::move(mountentries[scores.back().second])); + mountentries.clear(); + mountentries.push_back(std::move(temp)); } - std::sort(scores.begin(), scores.end()); - // Choose the item whose mnt_dir most matched the current path for our file. - auto temp(std::move(mountentries[scores.back().second])); - mountentries.clear(); - mountentries.push_back(std::move(temp)); - } #endif - if(!!(wanted & want::flags)) - { - f_flags.rdonly = static_cast((s.f_flags & MS_RDONLY) != 0); - f_flags.noexec = static_cast((s.f_flags & MS_NOEXEC) != 0); - f_flags.nosuid = static_cast((s.f_flags & MS_NOSUID) != 0); - f_flags.acls = static_cast(std::string::npos != mountentries.front().first.mnt_opts.find("acl") && - std::string::npos == mountentries.front().first.mnt_opts.find("noacl")); - f_flags.xattr = static_cast(std::string::npos != mountentries.front().first.mnt_opts.find("xattr") && - std::string::npos == mountentries.front().first.mnt_opts.find("nouser_xattr")); - // out.f_flags.compression=0; - // Those filing systems supporting FALLOC_FL_PUNCH_HOLE - f_flags.extents = static_cast(mountentries.front().first.mnt_type == "btrfs" || mountentries.front().first.mnt_type == "ext4" || - mountentries.front().first.mnt_type == "xfs" || mountentries.front().first.mnt_type == "tmpfs"); - ++ret; - } - if(!!(wanted & want::fstypename)) - { - f_fstypename = mountentries.front().first.mnt_type; - ++ret; - } - if(!!(wanted & want::mntfromname)) - { - f_mntfromname = mountentries.front().first.mnt_fsname; - ++ret; + if(!!(wanted & want::flags)) + { + f_flags.rdonly = static_cast((s.f_flags & MS_RDONLY) != 0); + f_flags.noexec = static_cast((s.f_flags & MS_NOEXEC) != 0); + f_flags.nosuid = static_cast((s.f_flags & MS_NOSUID) != 0); + f_flags.acls = static_cast(std::string::npos != mountentries.front().first.mnt_opts.find("acl") && + std::string::npos == mountentries.front().first.mnt_opts.find("noacl")); + f_flags.xattr = static_cast(std::string::npos != mountentries.front().first.mnt_opts.find("xattr") && + std::string::npos == mountentries.front().first.mnt_opts.find("nouser_xattr")); + // out.f_flags.compression=0; + // Those filing systems supporting FALLOC_FL_PUNCH_HOLE + f_flags.extents = static_cast(mountentries.front().first.mnt_type == "btrfs" || mountentries.front().first.mnt_type == "ext4" || + mountentries.front().first.mnt_type == "xfs" || mountentries.front().first.mnt_type == "tmpfs"); + ++ret; + } + if(!!(wanted & want::fstypename)) + { + f_fstypename = mountentries.front().first.mnt_type; + ++ret; + } + if(!!(wanted & want::mntfromname)) + { + f_mntfromname = mountentries.front().first.mnt_fsname; + ++ret; + } + if(!!(wanted & want::mntonname)) + { + f_mntonname = mountentries.front().first.mnt_dir; + ++ret; + } } - if(!!(wanted & want::mntonname)) + catch(...) { - f_mntonname = mountentries.front().first.mnt_dir; - ++ret; + return error_from_exception(); } } - catch(...) - { - return error_from_exception(); - } } #else struct statfs s; @@ -311,7 +319,176 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s ++ret; } #endif + if(!!(wanted & want::iosinprogress) || !!(wanted & want::ioswaittime)) + { + OUTCOME_TRY(auto ios, _fill_ios(h, f_mntfromname)); + if(!!(wanted & want::iosinprogress)) + { + f_iosinprogress = ios.first; + ++ret; + } + if(!!(wanted & want::ioswaittime)) + { + f_ioswaittime = ios.second; + ++ret; + } + } return ret; } +/******************************************* statfs_t ************************************************/ + +LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fill_ios(const handle &h, const std::string & /*unused*/) noexcept +{ + try + { +#ifdef __linux__ + struct stat s + { + }; + memset(&s, 0, sizeof(s)); + + if(-1 == ::fstat(h.native_handle().fd, &s)) + { + if(!h.is_symlink() || EBADF != errno) + { + return posix_error(); + } + // This is a hack, but symlink_handle includes this first so there is a chicken and egg dependency problem + OUTCOME_TRY(detail::stat_from_symlink(s, h)); + } + + static struct last_reading_t + { + struct item + { + dev_t st_dev; + size_t millis{0}; + std::chrono::steady_clock::time_point last_updated; + + uint32_t f_iosinprogress{0}; + float f_ioswaittime{0}; + }; + std::mutex lock; + std::vector items; + } last_reading; + auto now = std::chrono::steady_clock::now(); + { + std::lock_guard g(last_reading.lock); + for(auto &i : last_reading.items) + { + if(i.st_dev == s.st_dev) + { + if(std::chrono::duration_cast(now - i.last_updated) < std::chrono::milliseconds(100)) + { + return {i.f_iosinprogress, i.f_ioswaittime}; // exit with old readings + } + break; + } + } + } + try + { + int fd = ::open("/proc/diskstats", O_RDONLY); + if(fd >= 0) + { + std::string diskstats; + diskstats.resize(4096); + for(;;) + { + auto read = ::read(fd, (char *) diskstats.data(), diskstats.size()); + if(read < 0) + { + return posix_error(); + } + if(read < (ssize_t) diskstats.size()) + { + ::close(fd); + diskstats.resize(read); + break; + } + try + { + diskstats.resize(diskstats.size() << 1); + } + catch(...) + { + ::close(fd); + throw; + } + } + /* Format is (https://www.kernel.org/doc/Documentation/iostats.txt): + 01 02 03 04 05 06 07 08 09 10 ... + + Field 9 is i/o's currently in progress. + Field 10 is milliseconds spent doing i/o (cumulative). + */ + auto match_line = [&](string_view sv) { + int major = 0, minor = 0; + sscanf(sv.data(), "%d %d", &major, &minor); + // printf("Does %d,%d match %d,%d?\n", major, minor, major(s.st_dev), minor(s.st_dev)); + return (makedev(major, minor) == s.st_dev); + }; + for(size_t is = 0, ie = diskstats.find(10); ie != diskstats.npos; is = ie + 1, ie = diskstats.find(10, is)) + { + auto sv = string_view(diskstats).substr(is, ie - is); + if(match_line(sv)) + { + int major = 0, minor = 0; + char devicename[64]; + size_t fields[12]; + sscanf(sv.data(), "%d %d %s %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu", &major, &minor, devicename, fields + 0, fields + 1, fields + 2, fields + 3, + fields + 4, fields + 5, fields + 6, fields + 7, fields + 8, fields + 9); + std::lock_guard g(last_reading.lock); + auto it = last_reading.items.begin(); + for(; it != last_reading.items.end(); ++it) + { + if(it->st_dev == s.st_dev) + { + break; + } + } + if(it == last_reading.items.end()) + { + last_reading.items.emplace_back(); + it = --last_reading.items.end(); + it->st_dev = s.st_dev; + it->millis = fields[9]; + } + else + { + auto timediff = std::chrono::duration_cast(now - it->last_updated); + it->f_ioswaittime = std::min((float) ((double) (fields[9] - it->millis) / timediff.count()), 1.0f); + it->millis = fields[9]; + } + it->f_iosinprogress = (uint32_t) fields[8]; + it->last_updated = now; + return {it->f_iosinprogress, it->f_ioswaittime}; + } + } + // It's totally possible that the dev_t reported by stat() + // does not appear in /proc/diskstats, if this occurs then + // return all bits one to indicate soft failure. + } + } + catch(...) + { + return error_from_exception(); + } +#else + /* On FreeBSD, want::iosinprogress and want::ioswaittime could be implemented + using libdevstat. See https://www.freebsd.org/cgi/man.cgi?query=devstat&sektion=3. + Code donations welcome! + + On Mac OS, getting the current i/o wait time appears to be privileged only? + */ +#endif + return {-1, _allbits1_float}; + } + catch(...) + { + return error_from_exception(); + } +} + LLFIO_V2_NAMESPACE_END -- cgit v1.2.3 From 7eeb88fccc7e7071a8065afbbffc36379e8b7091 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Tue, 29 Dec 2020 14:41:08 +0000 Subject: Implement dynamic_thread_pool_group::io_aware_work_item. --- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'include/llfio/v2.0/detail/impl/posix/statfs.ipp') diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index 8b2ebcf3..97aff0f0 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -42,7 +42,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s { size_t ret = 0; #ifdef __linux__ - if(!!(wanted & ~(want::iosinprogress | want::ioswaittime))) + if(!!(wanted & ~(want::iosinprogress | want::iosbusytime))) { struct statfs64 s { @@ -319,7 +319,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s ++ret; } #endif - if(!!(wanted & want::iosinprogress) || !!(wanted & want::ioswaittime)) + if(!!(wanted & want::iosinprogress) || !!(wanted & want::iosbusytime)) { OUTCOME_TRY(auto ios, _fill_ios(h, f_mntfromname)); if(!!(wanted & want::iosinprogress)) @@ -327,9 +327,9 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s f_iosinprogress = ios.first; ++ret; } - if(!!(wanted & want::ioswaittime)) + if(!!(wanted & want::iosbusytime)) { - f_ioswaittime = ios.second; + f_iosbusytime = ios.second; ++ret; } } @@ -367,7 +367,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fi std::chrono::steady_clock::time_point last_updated; uint32_t f_iosinprogress{0}; - float f_ioswaittime{0}; + float f_iosbusytime{0}; }; std::mutex lock; std::vector items; @@ -381,7 +381,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fi { if(std::chrono::duration_cast(now - i.last_updated) < std::chrono::milliseconds(100)) { - return {i.f_iosinprogress, i.f_ioswaittime}; // exit with old readings + return {i.f_iosinprogress, i.f_iosbusytime}; // exit with old readings } break; } @@ -458,12 +458,12 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fi else { auto timediff = std::chrono::duration_cast(now - it->last_updated); - it->f_ioswaittime = std::min((float) ((double) (fields[9] - it->millis) / timediff.count()), 1.0f); + it->f_iosbusytime = std::min((float) ((double) (fields[9] - it->millis) / timediff.count()), 1.0f); it->millis = fields[9]; } it->f_iosinprogress = (uint32_t) fields[8]; it->last_updated = now; - return {it->f_iosinprogress, it->f_ioswaittime}; + return {it->f_iosinprogress, it->f_iosbusytime}; } } // It's totally possible that the dev_t reported by stat() @@ -476,7 +476,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fi return error_from_exception(); } #else - /* On FreeBSD, want::iosinprogress and want::ioswaittime could be implemented + /* On FreeBSD, want::iosinprogress and want::iosbusytime could be implemented using libdevstat. See https://www.freebsd.org/cgi/man.cgi?query=devstat&sektion=3. Code donations welcome! -- cgit v1.2.3 From 476b74799c4504a248d2fe63ae060f8eead21c47 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Wed, 13 Jan 2021 12:32:41 +0000 Subject: wip native linux threadpool implementation for dynamic_thread_pool_group. --- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/llfio/v2.0/detail/impl/posix/statfs.ipp') diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index 97aff0f0..092ca9f2 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -1,5 +1,5 @@ /* Information about the volume storing a file -(C) 2016-2017 Niall Douglas (5 commits) +(C) 2016-2020 Niall Douglas (5 commits) File Created: Jan 2016 @@ -483,7 +483,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fi On Mac OS, getting the current i/o wait time appears to be privileged only? */ #endif - return {-1, _allbits1_float}; + return {-1, detail::constexpr_float_allbits_set_nan()}; } catch(...) { -- cgit v1.2.3 From 5558cb7bc5f3a74589e579e8504f76cde117bb03 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Wed, 17 Feb 2021 11:54:44 +0000 Subject: more wip --- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/llfio/v2.0/detail/impl/posix/statfs.ipp') diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index 092ca9f2..c8455ef6 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -171,7 +171,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s */ if(mountentries.size() > 1) { - OUTCOME_TRY(auto currentfilepath_, h.current_path()); + OUTCOME_TRY(auto &¤tfilepath_, h.current_path()); string_view currentfilepath(currentfilepath_.native()); std::vector> scores(mountentries.size()); // std::cout << "*** For matching mount entries to file with path " << currentfilepath << ":\n"; @@ -321,7 +321,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s #endif if(!!(wanted & want::iosinprogress) || !!(wanted & want::iosbusytime)) { - OUTCOME_TRY(auto ios, _fill_ios(h, f_mntfromname)); + OUTCOME_TRY(auto &&ios, _fill_ios(h, f_mntfromname)); if(!!(wanted & want::iosinprogress)) { f_iosinprogress = ios.first; -- cgit v1.2.3 From d18a3b15a7f2201fc6e175f5a23d2426c4cea5c7 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Tue, 23 Feb 2021 12:58:10 +0000 Subject: Begin dynamic_thread_pool_group benchmark program. --- include/llfio/v2.0/detail/impl/posix/statfs.ipp | 1 + 1 file changed, 1 insertion(+) (limited to 'include/llfio/v2.0/detail/impl/posix/statfs.ipp') diff --git a/include/llfio/v2.0/detail/impl/posix/statfs.ipp b/include/llfio/v2.0/detail/impl/posix/statfs.ipp index c8455ef6..2e3b0859 100644 --- a/include/llfio/v2.0/detail/impl/posix/statfs.ipp +++ b/include/llfio/v2.0/detail/impl/posix/statfs.ipp @@ -340,6 +340,7 @@ LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result statfs_t::fill(const handle &h, s LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result> statfs_t::_fill_ios(const handle &h, const std::string & /*unused*/) noexcept { + (void) h; try { #ifdef __linux__ -- cgit v1.2.3