Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/use_cases.cpp5
-rw-r--r--include/afio/v2.0/async_file_handle.hpp79
-rw-r--r--include/afio/v2.0/directory_handle.hpp11
-rw-r--r--include/afio/v2.0/file_handle.hpp14
-rw-r--r--include/afio/v2.0/fs_handle.hpp8
-rw-r--r--include/afio/v2.0/io_handle.hpp13
-rw-r--r--include/afio/v2.0/map_handle.hpp94
-rw-r--r--include/afio/v2.0/mapped_file_handle.hpp15
-rw-r--r--include/afio/v2.0/path_handle.hpp4
-rw-r--r--scripts/make_free_functions.py12
10 files changed, 213 insertions, 42 deletions
diff --git a/example/use_cases.cpp b/example/use_cases.cpp
index e9647d5c..a2779256 100644
--- a/example/use_cases.cpp
+++ b/example/use_cases.cpp
@@ -73,3 +73,8 @@ std::future<void> coroutine_write()
//! [coroutine_write]
}
#endif
+
+int main()
+{
+ return 0;
+} \ No newline at end of file
diff --git a/include/afio/v2.0/async_file_handle.hpp b/include/afio/v2.0/async_file_handle.hpp
index 6f9c26b1..3785e6d3 100644
--- a/include/afio/v2.0/async_file_handle.hpp
+++ b/include/afio/v2.0/async_file_handle.hpp
@@ -689,6 +689,75 @@ inline async_file_handle::io_result<async_file_handle::const_buffers_type> barri
{
return self.barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(d)>(d));
}
+/*! \brief Schedule a barrier to occur asynchronously.
+
+\note All the caveats and exclusions which apply to `barrier()` also apply here. Note that Microsoft Windows
+does not support asynchronously executed barriers, and this call will fail on that operating system.
+
+\return Either an io_state_ptr to the i/o in progress, or an error code.
+\param self The object whose member function to call.
+\param reqs A scatter-gather and offset request for what range to barrier. May be ignored on some platforms
+which always write barrier the entire file. Supplying a default initialised reqs write barriers the entire file.
+\param completion A callable to call upon i/o completion. Spec is `void(async_file_handle *, io_result<const_buffers_type> &)`.
+Note that buffers returned may not be buffers input, see documentation for `barrier()`.
+\param wait_for_device True if you want the call to wait until data reaches storage and that storage
+has acknowledged the data is physically written. Slow.
+\param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
+barrier after a sudden power loss event. Slow.
+\param mem Optional span of memory to use to avoid using `calloc()`. Note span MUST be all bits zero on entry.
+\errors As for `barrier()`, plus `ENOMEM`.
+\mallocs If mem is not set, one calloc, one free. The allocation is unavoidable due to the need to store a type
+erased completion handler of unknown type and state per buffers input.
+*/
+template <class CompletionRoutine> inline result<async_file_handle::io_state_ptr> async_barrier(async_file_handle &self, async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, CompletionRoutine &&completion, bool wait_for_device = false, bool and_metadata = false, span<char> mem = {}) noexcept
+{
+ return self.async_barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(completion)>(completion), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(mem)>(mem));
+}
+/*! \brief Schedule a read to occur asynchronously.
+
+Note that some OS kernels can only process a limited number async i/o
+operations at a time. You should therefore check for the error `std::errc::resource_unavailable_try_again`
+and gracefully reschedule the i/o for a later time. This temporary
+failure may be returned immediately, or to the completion handler
+and hence you ought to handle both situations.
+
+\return Either an io_state_ptr to the i/o in progress, or an error code.
+\param self The object whose member function to call.
+\param reqs A scatter-gather and offset request.
+\param completion A callable to call upon i/o completion. Spec is `void(async_file_handle *, io_result<buffers_type> &)`.
+Note that buffers returned may not be buffers input, see documentation for `read()`.
+\param mem Optional span of memory to use to avoid using `calloc()`. Note span MUST be all bits zero on entry.
+\errors As for `read()`, plus `ENOMEM`.
+\mallocs If mem is not set, one calloc, one free. The allocation is unavoidable due to the need to store a type
+erased completion handler of unknown type and state per buffers input.
+*/
+template <class CompletionRoutine> inline result<async_file_handle::io_state_ptr> async_read(async_file_handle &self, async_file_handle::io_request<async_file_handle::buffers_type> reqs, CompletionRoutine &&completion, span<char> mem = {}) noexcept
+{
+ return self.async_read(std::forward<decltype(reqs)>(reqs), std::forward<decltype(completion)>(completion), std::forward<decltype(mem)>(mem));
+}
+/*! \brief Schedule a write to occur asynchronously.
+
+Note that some OS kernels can only process a limited number async i/o
+operations at a time. You should therefore check for the error `std::errc::resource_unavailable_try_again`
+and gracefully reschedule the i/o for a later time. This temporary
+failure may be returned immediately, or to the completion handler
+and hence you ought to handle both situations.
+
+
+\return Either an io_state_ptr to the i/o in progress, or an error code.
+\param self The object whose member function to call.
+\param reqs A scatter-gather and offset request.
+\param completion A callable to call upon i/o completion. Spec is `void(async_file_handle *, io_result<const_buffers_type> &)`.
+Note that buffers returned may not be buffers input, see documentation for `write()`.
+\param mem Optional span of memory to use to avoid using `calloc()`. Note span MUST be all bits zero on entry.
+\errors As for `write()`, plus `ENOMEM`.
+\mallocs If mem in not set, one calloc, one free. The allocation is unavoidable due to the need to store a type
+erased completion handler of unknown type and state per buffers input.
+*/
+template <class CompletionRoutine> inline result<async_file_handle::io_state_ptr> async_write(async_file_handle &self, async_file_handle::io_request<async_file_handle::const_buffers_type> reqs, CompletionRoutine &&completion, span<char> mem = {}) noexcept
+{
+ return self.async_write(std::forward<decltype(reqs)>(reqs), std::forward<decltype(completion)>(completion), std::forward<decltype(mem)>(mem));
+}
#if defined(__cpp_coroutines) || defined(DOXYGEN_IS_IN_THE_HOUSE)
/*! \brief Schedule a read to occur asynchronously.
@@ -706,6 +775,11 @@ inline result<async_file_handle::awaitable<async_file_handle::buffers_type>> co_
{
return self.co_read(std::forward<decltype(reqs)>(reqs));
}
+//! \overload
+inline result<async_file_handle::awaitable<async_file_handle::buffers_type>> co_read(async_file_handle &self, async_file_handle::extent_type offset, std::initializer_list<async_file_handle::buffer_type> lst) noexcept
+{
+ return self.co_read(std::forward<decltype(offset)>(offset), std::forward<decltype(lst)>(lst));
+}
/*! \brief Schedule a write to occur asynchronously
\return An awaitable, which when `co_await`ed upon, suspends execution of the coroutine
@@ -721,6 +795,11 @@ inline result<async_file_handle::awaitable<async_file_handle::const_buffers_type
{
return self.co_write(std::forward<decltype(reqs)>(reqs));
}
+//! \overload
+inline result<async_file_handle::awaitable<async_file_handle::const_buffers_type>> co_write(async_file_handle &self, async_file_handle::extent_type offset, std::initializer_list<async_file_handle::const_buffer_type> lst) noexcept
+{
+ return self.co_write(std::forward<decltype(offset)>(offset), std::forward<decltype(lst)>(lst));
+}
#endif
// END make_free_functions.py
diff --git a/include/afio/v2.0/directory_handle.hpp b/include/afio/v2.0/directory_handle.hpp
index 4c9d03be..8b3c14b8 100644
--- a/include/afio/v2.0/directory_handle.hpp
+++ b/include/afio/v2.0/directory_handle.hpp
@@ -322,10 +322,9 @@ inline void swap(directory_handle &self, directory_handle &o) noexcept
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<directory_handle> directory(const path_handle &base, directory_handle::path_view_type _path, directory_handle::mode _mode = directory_handle::mode::read, directory_handle::creation _creation = directory_handle::creation::open_existing, directory_handle::caching _caching = directory_handle::caching::all,
- directory_handle::flag flags = directory_handle::flag::none) noexcept
+inline result<directory_handle> directory(const path_handle &base, directory_handle::path_view_type path, directory_handle::mode _mode = directory_handle::mode::read, directory_handle::creation _creation = directory_handle::creation::open_existing, directory_handle::caching _caching = directory_handle::caching::all, directory_handle::flag flags = directory_handle::flag::none) noexcept
{
- return directory_handle::directory(std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
+ return directory_handle::directory(std::forward<decltype(base)>(base), std::forward<decltype(path)>(path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
/*! Create a directory handle creating a randomly named file on a path.
The file is opened exclusively with `creation::only_if_not_exist` so it
@@ -345,8 +344,7 @@ parameter is ignored.
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<directory_handle> temp_directory(directory_handle::path_view_type name = directory_handle::path_view_type(), directory_handle::mode _mode = directory_handle::mode::write, directory_handle::creation _creation = directory_handle::creation::if_needed,
- directory_handle::caching _caching = directory_handle::caching::all, directory_handle::flag flags = directory_handle::flag::none) noexcept
+inline result<directory_handle> temp_directory(directory_handle::path_view_type name = directory_handle::path_view_type(), directory_handle::mode _mode = directory_handle::mode::write, directory_handle::creation _creation = directory_handle::creation::if_needed, directory_handle::caching _caching = directory_handle::caching::all, directory_handle::flag flags = directory_handle::flag::none) noexcept
{
return directory_handle::temp_directory(std::forward<decltype(name)>(name), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
@@ -365,8 +363,7 @@ is no longer using any items within (leafnames are views onto the original kerne
\mallocs If the `kernelbuffer` parameter is set on entry, no memory allocations.
If unset, at least one memory allocation, possibly more is performed.
*/
-inline result<directory_handle::enumerate_info> enumerate(const directory_handle &self, directory_handle::buffers_type &&tofill, directory_handle::path_view_type glob = directory_handle::path_view_type(), directory_handle::filter filtering = directory_handle::filter::fastdeleted,
- span<char> kernelbuffer = span<char>()) noexcept
+inline result<directory_handle::enumerate_info> enumerate(const directory_handle &self, directory_handle::buffers_type &&tofill, directory_handle::path_view_type glob = directory_handle::path_view_type(), directory_handle::filter filtering = directory_handle::filter::fastdeleted, span<char> kernelbuffer = span<char>()) noexcept
{
return self.enumerate(std::forward<decltype(tofill)>(tofill), std::forward<decltype(glob)>(glob), std::forward<decltype(filtering)>(filtering), std::forward<decltype(kernelbuffer)>(kernelbuffer));
}
diff --git a/include/afio/v2.0/file_handle.hpp b/include/afio/v2.0/file_handle.hpp
index b0ee10cc..aee52b61 100644
--- a/include/afio/v2.0/file_handle.hpp
+++ b/include/afio/v2.0/file_handle.hpp
@@ -296,7 +296,7 @@ inline void swap(file_handle &self, file_handle &o) noexcept
}
/*! Create a file handle opening access to a file on path
\param base Handle to a base location on the filing system. Pass `{}` to indicate that path will be absolute.
-\param _path The path relative to base to open.
+\param path The path relative to base to open.
\param _mode How to open the file.
\param _creation How to create the file.
\param _caching How to ask the kernel to cache the file.
@@ -304,10 +304,9 @@ inline void swap(file_handle &self, file_handle &o) noexcept
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<file_handle> file(const path_handle &base, file_handle::path_view_type _path, file_handle::mode _mode = file_handle::mode::read, file_handle::creation _creation = file_handle::creation::open_existing, file_handle::caching _caching = file_handle::caching::all,
- file_handle::flag flags = file_handle::flag::none) noexcept
+inline result<file_handle> file(const path_handle &base, file_handle::path_view_type path, file_handle::mode _mode = file_handle::mode::read, file_handle::creation _creation = file_handle::creation::open_existing, file_handle::caching _caching = file_handle::caching::all, file_handle::flag flags = file_handle::flag::none) noexcept
{
- return file_handle::file(std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
+ return file_handle::file(std::forward<decltype(base)>(base), std::forward<decltype(path)>(path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
/*! Create a file handle creating a randomly named file on a path.
The file is opened exclusively with `creation::only_if_not_exist` so it
@@ -336,8 +335,7 @@ to use. Use `temp_inode()` instead, it is far more secure.
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<file_handle> temp_file(file_handle::path_view_type name = file_handle::path_view_type(), file_handle::mode _mode = file_handle::mode::write, file_handle::creation _creation = file_handle::creation::if_needed, file_handle::caching _caching = file_handle::caching::temporary,
- file_handle::flag flags = file_handle::flag::unlink_on_close) noexcept
+inline result<file_handle> temp_file(file_handle::path_view_type name = file_handle::path_view_type(), file_handle::mode _mode = file_handle::mode::write, file_handle::creation _creation = file_handle::creation::if_needed, file_handle::caching _caching = file_handle::caching::temporary, file_handle::flag flags = file_handle::flag::unlink_on_close) noexcept
{
return file_handle::temp_file(std::forward<decltype(name)>(name), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
@@ -351,9 +349,9 @@ is for backing shared memory maps).
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<file_handle> temp_inode(const path_handle &dir = path_discovery::storage_backed_temporary_files_directory(), file_handle::mode _mode = file_handle::mode::write, file_handle::flag flags = file_handle::flag::none) noexcept
+inline result<file_handle> temp_inode(const path_handle &dirh = path_discovery::storage_backed_temporary_files_directory(), file_handle::mode _mode = file_handle::mode::write, file_handle::flag flags = file_handle::flag::none) noexcept
{
- return file_handle::temp_inode(std::forward<decltype(dir)>(dir), std::forward<decltype(_mode)>(_mode), std::forward<decltype(flags)>(flags));
+ return file_handle::temp_inode(std::forward<decltype(dirh)>(dirh), std::forward<decltype(_mode)>(_mode), std::forward<decltype(flags)>(flags));
}
/*! Return the current maximum permitted extent of the file.
diff --git a/include/afio/v2.0/fs_handle.hpp b/include/afio/v2.0/fs_handle.hpp
index 3be37dcc..a9659647 100644
--- a/include/afio/v2.0/fs_handle.hpp
+++ b/include/afio/v2.0/fs_handle.hpp
@@ -192,7 +192,7 @@ success until the deadline given. This should prevent most unmalicious accidenta
\param self The object whose member function to call.
\param base Base for any relative path.
-\param newpath The relative or absolute new path to relink to.
+\param path The relative or absolute new path to relink to.
\param atomic_replace Atomically replace the destination if a file entry already is present there.
Choosing false for this will fail if a file entry is already present at the destination, and may
not be an atomic operation on some platforms (i.e. both the old and new names may be linked to the
@@ -200,11 +200,11 @@ same inode for a very short period of time). Windows and recent Linuxes are alwa
\param d The deadline by which the matching of the containing directory to the open handle's inode
must succeed, else `std::errc::timed_out` will be returned.
\mallocs Except on platforms with race free syscalls for renaming open handles (Windows), calls
-`current_path()` and thus is both expensive and calls malloc many times.
+`current_path()` via `parent_path_handle()` and thus is both expensive and calls malloc many times.
*/
-inline result<void> relink(fs_handle &self, const path_handle &base, fs_handle::path_view_type newpath, bool atomic_replace = true, deadline d = std::chrono::seconds(30)) noexcept
+inline result<void> relink(fs_handle &self, const path_handle &base, fs_handle::path_view_type path, bool atomic_replace = true, deadline d = std::chrono::seconds(30)) noexcept
{
- return self.relink(std::forward<decltype(base)>(base), std::forward<decltype(newpath)>(newpath), std::forward<decltype(atomic_replace)>(atomic_replace), std::forward<decltype(d)>(d));
+ return self.relink(std::forward<decltype(base)>(base), std::forward<decltype(path)>(path), std::forward<decltype(atomic_replace)>(atomic_replace), std::forward<decltype(d)>(d));
}
/*! Unlinks the current path of this open handle, causing its entry to immediately disappear from the filing system.
On Windows unless `flag::win_disable_unlink_emulation` is set, this behaviour is
diff --git a/include/afio/v2.0/io_handle.hpp b/include/afio/v2.0/io_handle.hpp
index 182fdd70..e9ba0bdb 100644
--- a/include/afio/v2.0/io_handle.hpp
+++ b/include/afio/v2.0/io_handle.hpp
@@ -474,6 +474,11 @@ inline io_handle::io_result<io_handle::buffers_type> read(io_handle &self, io_ha
{
return self.read(std::forward<decltype(reqs)>(reqs), std::forward<decltype(d)>(d));
}
+//! \overload
+inline io_handle::io_result<io_handle::buffers_type> read(io_handle &self, io_handle::extent_type offset, std::initializer_list<io_handle::buffer_type> lst, deadline d = deadline()) noexcept
+{
+ return self.read(std::forward<decltype(offset)>(offset), std::forward<decltype(lst)>(lst), std::forward<decltype(d)>(d));
+}
/*! \brief Write data to the open handle.
\warning Depending on the implementation backend, not all of the buffers input may be written and
@@ -500,6 +505,11 @@ inline io_handle::io_result<io_handle::const_buffers_type> write(io_handle &self
{
return self.write(std::forward<decltype(reqs)>(reqs), std::forward<decltype(d)>(d));
}
+//! \overload
+inline io_handle::io_result<io_handle::const_buffers_type> write(io_handle &self, io_handle::extent_type offset, std::initializer_list<io_handle::const_buffer_type> lst, deadline d = deadline()) noexcept
+{
+ return self.write(std::forward<decltype(offset)>(offset), std::forward<decltype(lst)>(lst), std::forward<decltype(d)>(d));
+}
/*! \brief Issue a write reordering barrier such that writes preceding the barrier will reach storage
before writes after this barrier.
@@ -525,7 +535,8 @@ which always write barrier the entire file. Supplying a default initialised reqs
\param wait_for_device True if you want the call to wait until data reaches storage and that storage
has acknowledged the data is physically written. Slow.
\param and_metadata True if you want the call to sync the metadata for retrieving the writes before the
-barrier after a sudden power loss event. Slow.
+barrier after a sudden power loss event. Slow. Setting this to false enables much faster performance,
+especially on non-volatile memory.
\param d An optional deadline by which the i/o must complete, else it is cancelled.
Note function may return significantly after this deadline if the i/o takes long to cancel.
\errors Any of the values POSIX fdatasync() or Windows NtFlushBuffersFileEx() can return.
diff --git a/include/afio/v2.0/map_handle.hpp b/include/afio/v2.0/map_handle.hpp
index 2371feb8..e9b350c5 100644
--- a/include/afio/v2.0/map_handle.hpp
+++ b/include/afio/v2.0/map_handle.hpp
@@ -547,7 +547,40 @@ inline void swap(section_handle &self, section_handle &o) noexcept
{
return self.swap(std::forward<decltype(o)>(o));
}
+/*! \brief Create a memory section backed by a file.
+\param backing The handle to use as backing storage.
+\param maximum_size The initial size of this section, which cannot be larger than any backing file. Zero means to use `backing.length()`.
+\param _flag How to create the section.
+\errors Any of the values POSIX dup(), open() or NtCreateSection() can return.
+*/
+inline result<section_handle> section(file_handle &backing, section_handle::extent_type maximum_size, section_handle::flag _flag) noexcept
+{
+ return section_handle::section(std::forward<decltype(backing)>(backing), std::forward<decltype(maximum_size)>(maximum_size), std::forward<decltype(_flag)>(_flag));
+}
+/*! \brief Create a memory section backed by a file.
+\param backing The handle to use as backing storage.
+\param bytes The initial size of this section, which cannot be larger than any backing file. Zero means to use `backing.length()`.
+
+This convenience overload create a writable section if the backing file is writable, otherwise a read-only section.
+
+\errors Any of the values POSIX dup(), open() or NtCreateSection() can return.
+*/
+inline result<section_handle> section(file_handle &backing, section_handle::extent_type bytes = 0) noexcept
+{
+ return section_handle::section(std::forward<decltype(backing)>(backing), std::forward<decltype(bytes)>(bytes));
+}
+/*! \brief Create a memory section backed by an anonymous, managed file.
+\param bytes The initial size of this section. Cannot be zero.
+\param dirh Where to create the anonymous, managed file.
+\param _flag How to create the section.
+
+\errors Any of the values POSIX dup(), open() or NtCreateSection() can return.
+*/
+inline result<section_handle> section(section_handle::extent_type bytes, const path_handle &dirh = path_discovery::storage_backed_temporary_files_directory(), section_handle::flag _flag = section_handle::flag::read | section_handle::flag::write) noexcept
+{
+ return section_handle::section(std::forward<decltype(bytes)>(bytes), std::forward<decltype(dirh)>(dirh), std::forward<decltype(_flag)>(_flag));
+}
//! Return the current maximum permitted extent of the memory section.
inline result<section_handle::extent_type> length(const section_handle &self) noexcept
{
@@ -555,10 +588,10 @@ inline result<section_handle::extent_type> length(const section_handle &self) no
}
/*! Resize the current maximum permitted extent of the memory section to the given extent.
\param self The object whose member function to call.
-\param newsize The new size of the memory section. Specify zero to use `backing.length()`.
-This cannot exceed the size of any backing file used.
+\param newsize The new size of the memory section, which cannot be zero. Specify zero to use `backing.length()`.
+This cannot exceed the size of any backing file used if that file is not writable.
-\errors Any of the values NtExtendSection() can return. On POSIX this is a no op.
+\errors Any of the values `NtExtendSection()` or `ftruncate()` can return.
*/
inline result<section_handle::extent_type> truncate(section_handle &self, section_handle::extent_type newsize = 0) noexcept
{
@@ -578,9 +611,24 @@ inline map_handle::io_result<map_handle::const_buffers_type> barrier(map_handle
{
return self.barrier(std::forward<decltype(reqs)>(reqs), std::forward<decltype(wait_for_device)>(wait_for_device), std::forward<decltype(and_metadata)>(and_metadata), std::forward<decltype(d)>(d));
}
+/*! Lightweight inlined barrier which causes the CPU to write out all buffered writes and dirty cache lines
+in the request to main memory.
+\return The cache lines actually barriered. This may be empty. This function does not return an error.
+\param self The object whose member function to call.
+\param req The range of cache lines to write barrier.
+\param evict Whether to also evict the cache lines from CPU caches, useful if they will not be used again.
+
+Upon return, one knows that memory in the returned buffer has been barriered
+(it may be empty if there is no support for this operation in AFIO, or if the current CPU does not
+support this operation). You may find the `is_nvram()` observer of particular use here.
+*/
+inline map_handle::const_buffer_type barrier(map_handle &self, map_handle::const_buffer_type req, bool evict = false) noexcept
+{
+ return self.barrier(std::forward<decltype(req)>(req), std::forward<decltype(evict)>(evict));
+}
/*! Create new memory and map it into view.
-\param bytes How many bytes to create and map. Typically will be rounded to a multiple of the page size (see utils::page_sizes()).
-\param _flag The permissions with which to map the view which are constrained by the permissions of the memory section. `flag::none` can be useful for reserving virtual address space without committing system resources, use commit() to later change availability of memory.
+\param bytes How many bytes to create and map. Typically will be rounded up to a multiple of the page size (see `utils::page_sizes()`) on POSIX, 64Kb on Windows.
+\param _flag The permissions with which to map the view. `flag::none` can be useful for reserving virtual address space without committing system resources, use commit() to later change availability of memory.
\note On Microsoft Windows this constructor uses the faster VirtualAlloc() which creates less versatile page backed memory. If you want anonymous memory
allocated from a paging file backed section instead, create a page file backed section and then a mapped view from that using
@@ -593,9 +641,9 @@ inline result<map_handle> map(map_handle::size_type bytes, section_handle::flag
{
return map_handle::map(std::forward<decltype(bytes)>(bytes), std::forward<decltype(_flag)>(_flag));
}
-/*! Create a memory mapped view of a backing storage.
+/*! Create a memory mapped view of a backing storage, optionally reserving additional address space for later growth.
\param section A memory section handle specifying the backing storage to use.
-\param bytes How many bytes to map (0 = the size of the memory section). Typically will be rounded to a multiple of the page size (see utils::page_sizes()).
+\param bytes How many bytes to reserve (0 = the size of the section). Rounded up to nearest 64Kb on Windows.
\param offset The offset into the backing storage to map from. Typically needs to be at least a multiple of the page size (see utils::page_sizes()), on Windows it needs to be a multiple of the kernel memory allocation granularity (typically 64Kb).
\param _flag The permissions with which to map the view which are constrained by the permissions of the memory section. `flag::none` can be useful for reserving virtual address space without committing system resources, use commit() to later change availability of memory.
@@ -605,11 +653,41 @@ inline result<map_handle> map(section_handle &section, map_handle::size_type byt
{
return map_handle::map(std::forward<decltype(section)>(section), std::forward<decltype(bytes)>(bytes), std::forward<decltype(offset)>(offset), std::forward<decltype(_flag)>(_flag));
}
-//! The size of the memory map.
+//! The size of the memory map. This is the accessible size, NOT the reservation size.
inline map_handle::size_type length(const map_handle &self) noexcept
{
return self.length();
}
+/*! Resize the reservation of the memory map without changing the address (unless the map
+was zero sized, in which case a new address will be chosen).
+
+If shrinking, address space is released on POSIX, and on Windows if the new size is zero.
+If the new size is zero, the address is set to null to prevent surprises.
+Windows does not support modifying existing mapped regions, so if the new size is not
+zero, the call will probably fail. Windows should let you truncate a previous extension
+however, if it is exact.
+
+If expanding, an attempt is made to map in new reservation immediately after the current address
+reservation, thus extending the reservation. If anything else is mapped in after
+the current reservation, the function fails.
+
+\note On all supported platforms apart from OS X, proprietary flags exist to avoid
+performing a map if a map extension cannot be immediately placed after the current map. On OS X,
+we hint where we'd like the new map to go, but if something is already there OS X will
+place the map elsewhere. In this situation, we delete the new map and return failure,
+which is inefficient, but there is nothing else we can do.
+
+\return The bytes actually reserved.
+\param self The object whose member function to call.
+\param newsize The bytes to truncate the map reservation to. Rounded up to the nearest page size (POSIX) or 64Kb on Windows.
+\param permit_relocation Permit the address to change (some OSs provide a syscall for resizing
+a memory map).
+\errors Any of the values POSIX `mremap()`, `mmap(addr)` or `VirtualAlloc(addr)` can return.
+*/
+inline result<map_handle::size_type> truncate(map_handle &self, map_handle::size_type newsize, bool permit_relocation = false) noexcept
+{
+ return self.truncate(std::forward<decltype(newsize)>(newsize), std::forward<decltype(permit_relocation)>(permit_relocation));
+}
/*! \brief Read data from the mapped view.
\note Because this implementation never copies memory, you can pass in buffers with a null address.
diff --git a/include/afio/v2.0/mapped_file_handle.hpp b/include/afio/v2.0/mapped_file_handle.hpp
index 11746d98..a56b7688 100644
--- a/include/afio/v2.0/mapped_file_handle.hpp
+++ b/include/afio/v2.0/mapped_file_handle.hpp
@@ -431,15 +431,12 @@ later when `truncate()` or `update_map()` is called.
\errors Any of the values which the constructors for `file_handle`, `section_handle` and `map_handle` can return.
*/
-inline result<mapped_file_handle> mapped_file(mapped_file_handle::size_type reservation, const path_handle &base, mapped_file_handle::path_view_type _path, mapped_file_handle::mode _mode = mapped_file_handle::mode::read, mapped_file_handle::creation _creation = mapped_file_handle::creation::open_existing,
- mapped_file_handle::caching _caching = mapped_file_handle::caching::all, mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
+inline result<mapped_file_handle> mapped_file(mapped_file_handle::size_type reservation, const path_handle &base, mapped_file_handle::path_view_type _path, mapped_file_handle::mode _mode = mapped_file_handle::mode::read, mapped_file_handle::creation _creation = mapped_file_handle::creation::open_existing, mapped_file_handle::caching _caching = mapped_file_handle::caching::all, mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
{
- return mapped_file_handle::mapped_file(std::forward<decltype(reservation)>(reservation), std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching),
- std::forward<decltype(flags)>(flags));
+ return mapped_file_handle::mapped_file(std::forward<decltype(reservation)>(reservation), std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
//! \overload
-inline result<mapped_file_handle> mapped_file(const path_handle &base, mapped_file_handle::path_view_type _path, mapped_file_handle::mode _mode = mapped_file_handle::mode::read, mapped_file_handle::creation _creation = mapped_file_handle::creation::open_existing,
- mapped_file_handle::caching _caching = mapped_file_handle::caching::all, mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
+inline result<mapped_file_handle> mapped_file(const path_handle &base, mapped_file_handle::path_view_type _path, mapped_file_handle::mode _mode = mapped_file_handle::mode::read, mapped_file_handle::creation _creation = mapped_file_handle::creation::open_existing, mapped_file_handle::caching _caching = mapped_file_handle::caching::all, mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
{
return mapped_file_handle::mapped_file(std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
@@ -451,8 +448,7 @@ flush changes to physical storage as lately as possible.
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<mapped_file_handle> mapped_random_file(mapped_file_handle::size_type reservation, const path_handle &dirpath, mapped_file_handle::mode _mode = mapped_file_handle::mode::write, mapped_file_handle::caching _caching = mapped_file_handle::caching::temporary,
- mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
+inline result<mapped_file_handle> mapped_random_file(mapped_file_handle::size_type reservation, const path_handle &dirpath, mapped_file_handle::mode _mode = mapped_file_handle::mode::write, mapped_file_handle::caching _caching = mapped_file_handle::caching::temporary, mapped_file_handle::flag flags = mapped_file_handle::flag::none) noexcept
{
return mapped_file_handle::mapped_random_file(std::forward<decltype(reservation)>(reservation), std::forward<decltype(dirpath)>(dirpath), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
@@ -471,8 +467,7 @@ to use. Use `temp_inode()` instead, it is far more secure.
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<mapped_file_handle> mapped_temp_file(mapped_file_handle::size_type reservation, mapped_file_handle::path_view_type name = mapped_file_handle::path_view_type(), mapped_file_handle::mode _mode = mapped_file_handle::mode::write,
- mapped_file_handle::creation _creation = mapped_file_handle::creation::if_needed, mapped_file_handle::caching _caching = mapped_file_handle::caching::temporary, mapped_file_handle::flag flags = mapped_file_handle::flag::unlink_on_close) noexcept
+inline result<mapped_file_handle> mapped_temp_file(mapped_file_handle::size_type reservation, mapped_file_handle::path_view_type name = mapped_file_handle::path_view_type(), mapped_file_handle::mode _mode = mapped_file_handle::mode::write, mapped_file_handle::creation _creation = mapped_file_handle::creation::if_needed, mapped_file_handle::caching _caching = mapped_file_handle::caching::temporary, mapped_file_handle::flag flags = mapped_file_handle::flag::unlink_on_close) noexcept
{
return mapped_file_handle::mapped_temp_file(std::forward<decltype(reservation)>(reservation), std::forward<decltype(name)>(name), std::forward<decltype(_mode)>(_mode), std::forward<decltype(_creation)>(_creation), std::forward<decltype(_caching)>(_caching), std::forward<decltype(flags)>(flags));
}
diff --git a/include/afio/v2.0/path_handle.hpp b/include/afio/v2.0/path_handle.hpp
index 25229f91..b759fb1d 100644
--- a/include/afio/v2.0/path_handle.hpp
+++ b/include/afio/v2.0/path_handle.hpp
@@ -111,9 +111,9 @@ a directory. For other systems, we open a directory with read only permissions.
\errors Any of the values POSIX open() or CreateFile() can return.
*/
-inline result<path_handle> path(const path_handle &base, path_handle::path_view_type _path) noexcept
+inline result<path_handle> path(const path_handle &base, path_handle::path_view_type path) noexcept
{
- return path_handle::path(std::forward<decltype(base)>(base), std::forward<decltype(_path)>(_path));
+ return path_handle::path(std::forward<decltype(base)>(base), std::forward<decltype(path)>(path));
}
//! \overload
inline result<path_handle> path(path_handle::path_view_type _path) noexcept
diff --git a/scripts/make_free_functions.py b/scripts/make_free_functions.py
index 9cb1f38a..6b2d6f1f 100644
--- a/scripts/make_free_functions.py
+++ b/scripts/make_free_functions.py
@@ -19,12 +19,17 @@ for header in glob.glob("../include/afio/*/*.hpp"):
if 'AFIO_MAKE_FREE_FUNCTION' in lines[lineidx] and re.match('\s*AFIO_MAKE_FREE_FUNCTION', lines[lineidx]):
function = ''
for n in range(1, 100):
+ if 'AFIO_REQUIRES' in lines[lineidx+n]:
+ continue
function += lines[lineidx+n]
if lineidx+n+1 >= len(lines):
print(lines[lineidx:])
raise Exception()
if '{' in lines[lineidx+n+1] or ';' in lines[lineidx+n]:
break
+ function = function.replace('//\n', '')
+ function = function.replace('\n', '')
+ function = function.replace(';', '')
docs = ''
if '*/' in lines[lineidx-1] or '//!' in lines[lineidx-1]:
for n in range(1, 100):
@@ -50,7 +55,7 @@ for header in glob.glob("../include/afio/*/*.hpp"):
lines.insert(functions_to_be_freed_begin, '// BEGIN make_free_functions.py\n')
idx = functions_to_be_freed_begin + 1
for classname, function, docs in functions_to_be_freed:
- #print((classname, function))
+ print((classname, function))
function = function.replace('virtual ', '')
function = function.replace('override', '')
function = function.replace('AFIO_HEADERS_ONLY_MEMFUNC_SPEC ', '')
@@ -74,9 +79,12 @@ for header in glob.glob("../include/afio/*/*.hpp"):
function = replace(function, 'path_view_type')
function = replace(function, 'extent_type')
function = replace(function, 'size_type')
+ function = replace(function, 'buffer_type')
+ function = replace(function, 'const_buffer_type')
+ function = replace(function, 'enumerate_info')
function = replace(function, 'buffers_type')
function = replace(function, 'const_buffers_type')
- function = replace(function, 'enumerate_info')
+ function = replace(function, 'io_state_ptr')
function = function.replace('path_view_type()', classname+'::path_view_type()')
function = function.replace(' io_result<', ' '+classname+'::io_result<')
function = function.replace(' io_request<', ' '+classname+'::io_request<')