On 6/4/21 6:17 PM, Niall Douglas via Boost wrote:
On 04/06/2021 15:54, Peter Dimov via Boost wrote:
Niall Douglas wrote:
On 04/06/2021 13:04, Andrey Semashev via Boost wrote:
I could add a runtime check, but I definitely don't want that check to happen on every call. This means the result must be stored globally in a thread-safe manner.
At work we've got llfio::stat_t::fill() being called in some places millions of times per second.
It is implemented by attempting statx first, and if it is not supported, then stat or other syscalls to emulate the same.
You cannot cache statx support/non-support because only some filing systems support statx, and others do not. So depending on the path used, it may work, but at other times, not.
Right now at work we're on kernels which don't support statx, so we are always getting back ENOSYS and then falling back to emulation. We have not found any performance issues.
A kernel call is infinitely more expensive than checking a number against ENOSYS. It's absolutely impossible for the test to ever be a performance issue.
Well, that depends.
If you're on a kernel that has no statx syscall, then the userspace syscall dispatcher will spot the unknown syscall number, and you'll get back ENOSYS very quickly, as you point out.
But if you're on a kernel with statx syscall, and instead it is the filing system which doesn't support statx, then that's a full fat syscall just to get back ENOSYS.
Kernel should not return ENOSYS for a syscall that is implemented. This error code is reserved for this specific purpose. What you should get is probably ENOTSUP or EINVAL. Are you sure you're getting specifically ENOSYS?
I don't personally think anyone who cares about metadata retrieval performance would ever use Filesystem or std::filesystem because both tend to do dynamic memory allocations, which easily swamp a statx call. So, in that sense, even many syscalls can be done and it'll be unmeasurable compared to say a filesystem path construction.
If this were Windows, because Filesystem calls many Win32 functions to build a stat, that is a very different situation. But not on POSIX.
Boost.Filesystem doesn't implement stat, it uses it as a means to implement other, more fine grained operations. On Windows, these operations tend to be implemented with a single WinAPI call, in some cases with a pair open/close file handle calls.