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:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2018-04-06 19:13:03 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2018-04-06 19:13:03 +0300
commitd0c561c7d38af021411c41a0161188a241364ac6 (patch)
tree28999afce9243a4c7777e7fbe0037ca92c6c0dd7
parent5b26598774ec4ec67ceea1ed5cad4bcb791471e2 (diff)
Added non-volatile memory support.
Renamed mapped_view to mapped_span. Now using bug fixed Outcome, KernelTest horribly breaks, will fix it up later, but otherwise compiles fine.
-rw-r--r--.ci.cmake2
-rw-r--r--.travis.yml2
-rw-r--r--Readme.md19
-rw-r--r--cmake/headers.cmake2
-rw-r--r--cmake/tests.cmake2
-rw-r--r--include/afio/revision.hpp6
-rw-r--r--include/afio/v2.0/afio.hpp2
-rw-r--r--include/afio/v2.0/algorithm/mapped_span.hpp (renamed from include/afio/v2.0/algorithm/mapped_view.hpp)16
-rw-r--r--include/afio/v2.0/config.hpp7
-rw-r--r--include/afio/v2.0/detail/impl/posix/map_handle.ipp11
-rw-r--r--include/afio/v2.0/detail/impl/posix/path_discovery.ipp4
-rw-r--r--include/afio/v2.0/detail/impl/windows/map_handle.ipp10
-rw-r--r--include/afio/v2.0/io_handle.hpp3
-rw-r--r--include/afio/v2.0/map_handle.hpp56
m---------include/afio/v2.0/outcome0
m---------include/afio/v2.0/quickcpplib0
-rw-r--r--release_notes.md12
m---------test/kerneltest0
-rw-r--r--test/tests/mapped_span.cpp (renamed from test/tests/mapped_view.cpp)28
19 files changed, 138 insertions, 44 deletions
diff --git a/.ci.cmake b/.ci.cmake
index 3b134081..90aa9e1b 100644
--- a/.ci.cmake
+++ b/.ci.cmake
@@ -67,7 +67,7 @@ else()
COMMAND cp -a Readme.md afio/
COMMAND cp -a release_notes.md afio/
COMMAND cp -a --parents prebuilt/lib/libafio_sl-2.0-Darwin-x86_64-Release.a afio/
- COMMAND cp -a --parents prebuilt/lib/libafio_dl-2.0-Darwin-x86_64-Release.so afio/
+ COMMAND cp -a --parents prebuilt/lib/libafio_dl-2.0-Darwin-x86_64-Release.dylib afio/
COMMAND "${CMAKE_COMMAND}" -E tar cfz afio-v2.0-binaries-darwin64.tgz afio
)
get_filename_component(toupload afio-v2.0-binaries-darwin64.tgz ABSOLUTE)
diff --git a/.travis.yml b/.travis.yml
index a7e6cb28..2f648092 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -115,7 +115,7 @@ script:
after_success:
# - bash -x ./update_coveralls.sh `pwd`
# - NEWNAME=afio-v2.0-binaries-linux64-$(date +%Y%m%d%H%M%S).tgz
- - if [ "${TRAVIS_OS_NAME}" = "linux" && "$CXX" = "g++-6" ]; then
+ - if [ "${TRAVIS_OS_NAME}" = "linux" && "$CXX" = "clang++-4.0" ]; then
NEWNAME=afio-v2.0-binaries-linux64-$TRAVIS_COMMIT.tgz;
mv afio-v2.0-binaries-linux64.tgz $NEWNAME;
curl -T $NEWNAME -u jenkins-nedprod:$JENKINS_NEDPROD_PASSWORD https://dedi4.nedprod.com/static/files/upload/; fi;
diff --git a/Readme.md b/Readme.md
index 21b90a46..aeadebb6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -11,10 +11,24 @@ Tarballs of source and prebuilt binaries for Linux x64, MacOS x64 and Windows x6
### Immediate todos in order of priority:
- [x] Implement new custom C++ exception synthesis support from Outcome.
-- [ ] Finish trivial vector, which is unfinished and currently segfaults.
-- [ ] Run clang-tidy fix pass, it's got a bit untidy recently.
+- [x] Finish trivial vector, which is unfinished and currently segfaults.
+- [x] Run clang-tidy fix pass, it's got a bit untidy recently.
+- [ ] Add OS X support to `storage_profile`, this should complete the Mac OS port.
+- [x] Fix all known bugs in Outcome, plus reorg source code in prep for `status_code`.
+- [ ] Implement SG14 `status_code` as a standalone library and test in AFIO.
+- [ ] Single include generation now we're on `status_code` and it's safe.
- [ ] `atomic_append` isn't actually being tested in shared_fs_mutex
- [ ] Implement a non-toy ACID key-value BLOB store and send it to Boost for peer review.
+ - [ ] For this need to implement a file-based B+ tree. And for that, need to
+ implement a page allocator out of a single file. Some notes:
+
+ B+ trees would be based on the 4Kb page for memory mapping, and thus allocate and release whole 4Kb pages.
+
+ A simple page allocator from a file might simply keep some magic at the top, and then a list of offsets to free pages for the remainder of the page. That might be (4096 – 12) / 4 = 1021 slots (remember these are 42 bit offsets, so simply limit to 32 bit offsets << 12).
+
+ Each free page links to its next free page. Freeing a page means modulus its address >> 12 with 1021, and CASing it into its “slot” as its linked list.
+
+ Allocating pages involves iterating a round robin index, pulling free pages off the top. Only if no free pages remain do we atomic append 1021 * 4096 = 4,182,016 bytes and refill the free page index.
- [ ] All time based kernel tests need to use soak test based API and auto adjust to
valgrind.
- [ ] In DEBUG builds, have io_handle always not fill buffers passed to remind
@@ -22,7 +36,6 @@ people to use pointers returned!
- KernelTest needs to be generating each test kernel as a standalone DLL so it can be
fuzzed, coverage calculated, bloat calculated, ABI dumped etc
- Easy coverage is the usual gcov route => coveralls.io or gcovr http://gcovr.com/guide.html
-- [ ] Single include generation
### clang AST parser based todos which await me getting back into the clang AST parser:
diff --git a/cmake/headers.cmake b/cmake/headers.cmake
index 0d323b0b..a5137105 100644
--- a/cmake/headers.cmake
+++ b/cmake/headers.cmake
@@ -8,7 +8,7 @@ set(afio_HEADERS
"include/afio/revision.hpp"
"include/afio/v2.0/afio.hpp"
"include/afio/v2.0/algorithm/cached_parent_handle_adapter.hpp"
- "include/afio/v2.0/algorithm/mapped_view.hpp"
+ "include/afio/v2.0/algorithm/mapped_span.hpp"
"include/afio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp"
"include/afio/v2.0/algorithm/shared_fs_mutex/base.hpp"
"include/afio/v2.0/algorithm/shared_fs_mutex/byte_ranges.hpp"
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 6ae9de9a..57f7d665 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -15,7 +15,7 @@ set(afio_TESTS
"test/tests/file_handle_create_close/runner.cpp"
"test/tests/file_handle_lock_unlock.cpp"
"test/tests/map_handle_create_close/runner.cpp"
- "test/tests/mapped_view.cpp"
+ "test/tests/mapped_span.cpp"
"test/tests/path_discovery.cpp"
"test/tests/path_view.cpp"
"test/tests/section_handle_create_close/runner.cpp"
diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp
index c6a45f07..c2b79996 100644
--- a/include/afio/revision.hpp
+++ b/include/afio/revision.hpp
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
-#define AFIO_PREVIOUS_COMMIT_REF bb01e6e6b3a157a92b8a14481b15afc2f3bd5361
-#define AFIO_PREVIOUS_COMMIT_DATE "2018-02-12 09:55:59 +00:00"
-#define AFIO_PREVIOUS_COMMIT_UNIQUE bb01e6e6
+#define AFIO_PREVIOUS_COMMIT_REF 5b26598774ec4ec67ceea1ed5cad4bcb791471e2
+#define AFIO_PREVIOUS_COMMIT_DATE "2018-02-12 19:10:45 +00:00"
+#define AFIO_PREVIOUS_COMMIT_UNIQUE 5b265987
diff --git a/include/afio/v2.0/afio.hpp b/include/afio/v2.0/afio.hpp
index fe5f4a8f..8c122a46 100644
--- a/include/afio/v2.0/afio.hpp
+++ b/include/afio/v2.0/afio.hpp
@@ -64,7 +64,7 @@ import AFIO_MODULE_NAME;
#include "storage_profile.hpp"
#include "algorithm/cached_parent_handle_adapter.hpp"
-#include "algorithm/mapped_view.hpp"
+#include "algorithm/mapped_span.hpp"
#include "algorithm/shared_fs_mutex/atomic_append.hpp"
#include "algorithm/shared_fs_mutex/byte_ranges.hpp"
#include "algorithm/shared_fs_mutex/lock_files.hpp"
diff --git a/include/afio/v2.0/algorithm/mapped_view.hpp b/include/afio/v2.0/algorithm/mapped_span.hpp
index 887a23dd..29081720 100644
--- a/include/afio/v2.0/algorithm/mapped_view.hpp
+++ b/include/afio/v2.0/algorithm/mapped_span.hpp
@@ -28,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "../mapped_file_handle.hpp"
#include "../utils.hpp"
-//! \file mapped_view.hpp Provides typed view of mapped section.
+//! \file mapped_span.hpp Provides typed view of mapped section.
AFIO_V2_NAMESPACE_BEGIN
@@ -41,7 +41,7 @@ namespace algorithm
`section_handle::flag::barrier_on_close`, thus forcing any changes to data referred to by the view
to storage before the destructor returns.
*/
- template <class T> class mapped_view : public span<T>
+ template <class T> class mapped_span : public span<T>
{
public:
//! The extent type.
@@ -51,7 +51,7 @@ namespace algorithm
private:
map_handle _mapping;
- mapped_view(extent_type page_offset, extent_type offset, section_handle &sh, size_type bytes, section_handle::flag _flag) // NOLINT
+ mapped_span(extent_type page_offset, extent_type offset, section_handle &sh, size_type bytes, section_handle::flag _flag) // NOLINT
: _mapping(map_handle::map(sh, (bytes == 0) ? 0 : bytes + (offset - page_offset), page_offset, _flag).value())
{
offset -= page_offset;
@@ -66,13 +66,13 @@ namespace algorithm
public:
//! Default constructor
- constexpr mapped_view() {} // NOLINT
+ constexpr mapped_span() {} // NOLINT
/*! Create a view of new memory.
\param length The number of items to map.
\param _flag The flags to pass to `map_handle::map()`.
*/
- explicit mapped_view(size_type length, section_handle::flag _flag = section_handle::flag::readwrite)
+ explicit mapped_span(size_type length, section_handle::flag _flag = section_handle::flag::readwrite)
: _mapping(map_handle::map(length * sizeof(T), _flag).value())
{
char *addr = _mapping.address();
@@ -85,8 +85,8 @@ namespace algorithm
\param byteoffset The byte offset into the section handle, this does not need to be a multiple of the page size.
\param _flag The flags to pass to `map_handle::map()`.
*/
- explicit mapped_view(section_handle &sh, size_type length = (size_type) -1, extent_type byteoffset = 0, section_handle::flag _flag = section_handle::flag::readwrite) // NOLINT
- : mapped_view((length == 0) ? mapped_view() : mapped_view(
+ explicit mapped_span(section_handle &sh, size_type length = (size_type) -1, extent_type byteoffset = 0, section_handle::flag _flag = section_handle::flag::readwrite) // NOLINT
+ : mapped_span((length == 0) ? mapped_span() : mapped_span(
#ifdef _WIN32
byteoffset & ~65535,
#else
@@ -101,7 +101,7 @@ namespace algorithm
\param length The number of items to map, use -1 to mean the length of the section handle divided by `sizeof(T)`.
\param byteoffset The byte offset into the mapped file handle, this does not need to be a multiple of the page size.
*/
- explicit mapped_view(mapped_file_handle &mfh, size_type length = (size_type) -1, extent_type byteoffset = 0) // NOLINT
+ explicit mapped_span(mapped_file_handle &mfh, size_type length = (size_type) -1, extent_type byteoffset = 0) // NOLINT
: span<T>(reinterpret_cast<T *>(mfh.address() + byteoffset), (length == (size_type) -1) ? (mfh.length().value() / sizeof(T)) : length) // NOLINT
{
}
diff --git a/include/afio/v2.0/config.hpp b/include/afio/v2.0/config.hpp
index c6ecf37c..fa8589d1 100644
--- a/include/afio/v2.0/config.hpp
+++ b/include/afio/v2.0/config.hpp
@@ -311,6 +311,11 @@ AFIO_V2_NAMESPACE_END
AFIO_V2_NAMESPACE_BEGIN
using namespace QUICKCPPLIB_NAMESPACE::string_view;
AFIO_V2_NAMESPACE_END
+// Bring in a persistent implementation
+#include "quickcpplib/include/persistent.hpp"
+AFIO_V2_NAMESPACE_BEGIN
+using namespace QUICKCPPLIB_NAMESPACE::persistence;
+AFIO_V2_NAMESPACE_END
// Bring in a result implementation
#include "outcome/include/outcome.hpp"
@@ -433,7 +438,7 @@ inline std::error_code make_error_code(error_info ei)
return ei.ec;
}
// Tell Outcome to call error_info::throw_as_exception() on no-value observation
-inline void throw_as_system_error_with_payload(const error_info &ei)
+inline void outcome_throw_as_system_error_with_payload(const error_info &ei)
{
ei.throw_as_exception();
}
diff --git a/include/afio/v2.0/detail/impl/posix/map_handle.ipp b/include/afio/v2.0/detail/impl/posix/map_handle.ipp
index b020f6ca..e5ebfebe 100644
--- a/include/afio/v2.0/detail/impl/posix/map_handle.ipp
+++ b/include/afio/v2.0/detail/impl/posix/map_handle.ipp
@@ -176,6 +176,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
AFIO_LOG_FUNCTION_CALL(this);
char *addr = _addr + reqs.offset;
extent_type bytes = 0;
+ // Check for overflow
for(const auto &req : reqs.buffers)
{
if(bytes + req.len < bytes)
@@ -184,10 +185,20 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
}
bytes += req.len;
}
+ // If empty, do the whole file
if(reqs.buffers.empty())
{
bytes = _length;
}
+ // If nvram and not syncing metadata, use lightweight barrier
+ if(!and_metadata && is_nvram())
+ {
+ auto synced = barrier({addr, bytes});
+ if(synced.len >= bytes)
+ {
+ return {reqs.buffers};
+ }
+ }
int flags = (wait_for_device || and_metadata) ? MS_SYNC : MS_ASYNC;
if(-1 == ::msync(addr, bytes, flags))
{
diff --git a/include/afio/v2.0/detail/impl/posix/path_discovery.ipp b/include/afio/v2.0/detail/impl/posix/path_discovery.ipp
index 5d6c1177..1d630ba8 100644
--- a/include/afio/v2.0/detail/impl/posix/path_discovery.ipp
+++ b/include/afio/v2.0/detail/impl/posix/path_discovery.ipp
@@ -26,7 +26,7 @@ Distributed under the Boost Software License, Version 1.0.
#error Must be included by ../path_discovery.ipp only
#endif
-#include "../../../algorithm/mapped_view.hpp"
+#include "../../../algorithm/mapped_span.hpp"
#include <pwd.h>
@@ -77,7 +77,7 @@ namespace path_discovery
}
else
{
- algorithm::mapped_view<const char> passwd(_passwdh.value());
+ algorithm::mapped_span<const char> passwd(_passwdh.value());
/* This will consist of lines of the form:
jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8910,(234)555-0044,email:/home/jsmith:/bin/sh
diff --git a/include/afio/v2.0/detail/impl/windows/map_handle.ipp b/include/afio/v2.0/detail/impl/windows/map_handle.ipp
index daa64c0d..858d3ec1 100644
--- a/include/afio/v2.0/detail/impl/windows/map_handle.ipp
+++ b/include/afio/v2.0/detail/impl/windows/map_handle.ipp
@@ -427,6 +427,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
AFIO_LOG_FUNCTION_CALL(this);
char *addr = _addr + reqs.offset;
extent_type bytes = 0;
+ // Check for overflow
for(const auto &req : reqs.buffers)
{
if(bytes + req.len < bytes)
@@ -440,6 +441,15 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
{
bytes = _reservation - reqs.offset;
}
+ // If nvram and not syncing metadata, use lightweight barrier
+ if(!and_metadata && is_nvram())
+ {
+ auto synced = barrier({addr, bytes});
+ if(synced.len >= bytes)
+ {
+ return {reqs.buffers};
+ }
+ }
OUTCOME_TRYV(win32_maps_apply(addr, bytes, [](char *addr, size_t bytes) -> result<void> {
if(FlushViewOfFile(addr, static_cast<SIZE_T>(bytes)) == 0)
{
diff --git a/include/afio/v2.0/io_handle.hpp b/include/afio/v2.0/io_handle.hpp
index a9732fac..f1f5d7a4 100644
--- a/include/afio/v2.0/io_handle.hpp
+++ b/include/afio/v2.0/io_handle.hpp
@@ -285,7 +285,8 @@ public:
\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 e2724bdd..2371feb8 100644
--- a/include/afio/v2.0/map_handle.hpp
+++ b/include/afio/v2.0/map_handle.hpp
@@ -1,5 +1,5 @@
/* A handle to a source of mapped memory
-(C) 2016-2017 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
+(C) 2016-2018 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
File Created: August 2016
@@ -67,6 +67,7 @@ public:
singleton = 1U << 11U, //!< A single instance of this section is to be shared by all processes using the same backing file.
barrier_on_close = 1U << 16U, //!< Maps of this section, if writable, issue a `barrier()` when destructed blocking until data (not metadata) reaches physical storage.
+ nvram = 1U << 17U, //!< This section is of non-volatile RAM
// NOTE: IF UPDATING THIS UPDATE THE std::ostream PRINTER BELOW!!!
@@ -148,6 +149,8 @@ public:
//! Returns the memory section's flags
flag section_flags() const noexcept { return _flag; }
+ //! True if the section reflects non-volatile RAM
+ bool is_nvram() const noexcept { return !!(_flag & flag::nvram); }
//! Returns the borrowed handle backing this section, if any
file_handle *backing() const noexcept { return _backing; }
//! Sets the borrowed handle backing this section, if any
@@ -206,6 +209,10 @@ inline std::ostream &operator<<(std::ostream &s, const section_handle::flag &v)
{
temp.append("barrier_on_close|");
}
+ if(!!(v & section_handle::flag::nvram))
+ {
+ temp.append("nvram|");
+ }
if(!temp.empty())
{
temp.resize(temp.size() - 1);
@@ -254,7 +261,21 @@ does not close that of the backing storage, nor does releasing this handle relea
Locking byte ranges of this handle is therefore equal to locking byte ranges in the original backing storage,
which can be very useful.
-\sa `mapped_file_handle`, `algorithm::mapped_view`
+## Barriers:
+
+`map_handle`, because it implements `io_handle`, implements `barrier()` in a very conservative way
+to account for OS differences i.e. it calls `msync()`, and then the `barrier()` implementation for the backing file
+(probably `fsync()` or equivalent on most platforms, which synchronises the entire file).
+
+This is vast overkill if you are using non-volatile RAM, so a special *inlined* `barrier()` implementation
+taking a single buffer and no other arguments is also provided. This calls the appropriate architecture-specific
+instructions to cause the CPU to write all preceding writes out of the write buffers and CPU caches to main
+memory, so for Intel CPUs this would be `CLWB <each cache line>; SFENCE;`. As this is inlined, it ought to
+produce optimal code. If your CPU does not support the requisite instructions (or AFIO has not added support),
+and empty buffer will be returned to indicate that nothing was barriered, same as the normal `barrier()`
+function.
+
+\sa `mapped_file_handle`, `algorithm::mapped_span`
*/
class AFIO_DECL map_handle : public io_handle
{
@@ -328,7 +349,33 @@ public:
AFIO_HEADERS_ONLY_VIRTUAL_SPEC native_handle_type release() noexcept override;
AFIO_MAKE_FREE_FUNCTION
AFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> barrier(io_request<const_buffers_type> reqs = io_request<const_buffers_type>(), bool wait_for_device = false, bool and_metadata = false, deadline d = deadline()) noexcept override;
-
+ /*! 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 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.
+ */
+ AFIO_MAKE_FREE_FUNCTION
+ const_buffer_type barrier(const_buffer_type req, bool evict = false) noexcept
+ {
+ const_buffer_type ret{(const char *) (((uintptr_t) req.data) & 31), 0};
+ ret.len = req.data + req.len - ret.data;
+ for(const char *addr = ret.data; addr < ret.data + ret.len; addr += 32)
+ {
+ // Slightly UB ...
+ auto *p = reinterpret_cast<const persistent<char> *>(addr);
+ if(memory_flush_none == p->flush(evict ? memory_flush_evict : memory_flush_retain))
+ {
+ req.len = 0;
+ break;
+ }
+ }
+ return ret;
+ }
/*! Create new memory and map it into view.
\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.
@@ -373,6 +420,9 @@ public:
AFIO_MAKE_FREE_FUNCTION
size_type length() const noexcept { return _length; }
+ //! True if the map is of non-volatile RAM
+ bool is_nvram() const noexcept { return !!(_flag & section_handle::flag::nvram); }
+
//! Update the size of the memory map to that of any backing section, up to the reservation limit.
result<size_type> update_map() noexcept
{
diff --git a/include/afio/v2.0/outcome b/include/afio/v2.0/outcome
-Subproject 9e3f92f71bfe90b76ab78911ea66e9d6516bfca
+Subproject 5188e87c55b19b58eb94a52b6119ddd39837597
diff --git a/include/afio/v2.0/quickcpplib b/include/afio/v2.0/quickcpplib
-Subproject 4587483051c58c3b2f5fb2814d7c78c39567b06
+Subproject a36840f8f104773efaaa50737c81294071d0439
diff --git a/release_notes.md b/release_notes.md
index 714996a9..5e606132 100644
--- a/release_notes.md
+++ b/release_notes.md
@@ -30,7 +30,7 @@ source code repository lives at https://github.com/ned14/boost.afio.
- Original error code is always preserved, even down to the original NT kernel error code if a NT kernel API was used.
- Race free filesystem design used throughout (i.e. no TOCTOU).
- Zero malloc, zero exception throw and zero whole system memory copy design used throughout, even down to paths (which can hit 64Kb!).
-- Works very well with the C++ standard library, and is intended to be proposed for standardisation into C++ in 2020 or thereabouts.
+- Works very well with the C++ standard library, and is intended to be proposed for standardisation into C++ in Summer 2018.
\note Note that this code is of late alpha quality. It's quite reliable on Windows and Linux, but be careful when using it!
@@ -190,9 +190,13 @@ Todo thereafter in order of priority:
| NEW in v2 | Windows | POSIX | |
| --------- | --------| ----- | --- |
-| ✔ | | | Reliable directory hierarchy deletion algorithm.
-| ✔ | | | Reliable directory hierarchy copy algorithm.
-| ✔ | | | Reliable directory hierarchy update (two and three way) algorithm.
+| ✔ | | | Page allocator based on an index of linked list of free pages. See notes.
+| ✔ | | | Optionally concurrent B+ tree index based on page allocator for key-value store.
+| ✔ | | | Attributes extending `span<buffers_type>` with DMA colouring.
+| ✔ | | | Coroutine generator for iterating a file's contents in DMA friendly way.
+| ✔ | | | Ranges & Concurrency based reliable directory hierarchy deletion algorithm.
+| ✔ | | | Ranges & Concurrency based reliable directory hierarchy copy algorithm.
+| ✔ | | | Ranges & Concurrency based reliable directory hierarchy update (two and three way) algorithm.
| ✔ | | | Linux KAIO support for native non-blocking `O_DIRECT` i/o
| ✔ | | | `std::pmr::memory_resource` adapting a file backing if on C++ 17.
| ✔ | | | Extended attributes support.
diff --git a/test/kerneltest b/test/kerneltest
-Subproject 42749ba88177a26c7090b7b3a12b0cbe1feed83
+Subproject f83c8e716d068db825204f2ded46ba1395556fa
diff --git a/test/tests/mapped_view.cpp b/test/tests/mapped_span.cpp
index 2813c625..cd776425 100644
--- a/test/tests/mapped_view.cpp
+++ b/test/tests/mapped_span.cpp
@@ -31,9 +31,9 @@ static inline void TestMappedView1()
file_handle fh = file_handle::file({}, "testfile", file_handle::mode::write, file_handle::creation::if_needed, file_handle::caching::all, file_handle::flag::unlink_on_close).value();
fh.truncate(10000 * sizeof(int)).value();
section_handle sh(section_handle::section(fh).value());
- algorithm::mapped_view<int> v1(sh, 5);
- algorithm::mapped_view<int> v2(sh);
- algorithm::mapped_view<int> v3(50);
+ algorithm::mapped_span<int> v1(sh, 5);
+ algorithm::mapped_span<int> v2(sh);
+ algorithm::mapped_span<int> v3(50);
BOOST_CHECK(v1.size() == 5);
BOOST_CHECK(v2.size() == 10000);
BOOST_CHECK(v3.size() == 50);
@@ -46,7 +46,7 @@ static inline void TestMappedView1()
try
{
// Overly large views must not extend the file until written to
- algorithm::mapped_view<int> v4(sh, 20000);
+ algorithm::mapped_span<int> v4(sh, 20000);
BOOST_CHECK(fh.length().value() == 10000 * sizeof(int));
}
catch(...)
@@ -74,7 +74,7 @@ static inline void TestMappedView2()
char *addr = mfh.address();
BOOST_CHECK(addr != nullptr);
- algorithm::mapped_view<int> v1(mfh);
+ algorithm::mapped_span<int> v1(mfh);
BOOST_CHECK(v1.size() == 10000);
v1[0] = 78;
v1[9999] = 79;
@@ -82,38 +82,38 @@ static inline void TestMappedView2()
BOOST_CHECK(addr == mfh.address());
BOOST_CHECK(mfh.length().value() == 20000 * sizeof(int));
BOOST_CHECK(mfh.underlying_file_length().value() == 20000 * sizeof(int));
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_CHECK(v1.size() == 20000);
BOOST_CHECK(v1[0] == 78);
BOOST_CHECK(v1[9999] == 79);
mfh.truncate(2 * 1024 * 1024).value(); // exceed reservation, cause hidden reserve
BOOST_CHECK(addr != nullptr);
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_CHECK(v1.size() == 2 * 1024 * 1024 / sizeof(int));
BOOST_CHECK(v1[0] == 78);
BOOST_CHECK(v1[9999] == 79);
mfh.reserve(2 * 1024 * 1024).value();
BOOST_CHECK(mfh.address() != nullptr);
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_CHECK(v1.size() == 2 * 1024 * 1024 / sizeof(int));
BOOST_CHECK(v1[0] == 78);
BOOST_CHECK(v1[9999] == 79);
mfh.truncate(1 * sizeof(int)).value();
BOOST_CHECK(mfh.address() != nullptr);
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_CHECK(v1.size() == 1);
BOOST_CHECK(v1[0] == 78);
// Use a different handle to extend the file
mapped_file_handle mfh2 = mapped_file_handle::mapped_file(1024 * 1024, {}, "testfile", file_handle::mode::write, file_handle::creation::open_existing, file_handle::caching::all, file_handle::flag::unlink_on_close).value();
mfh2.truncate(10000 * sizeof(int)).value();
- v1 = algorithm::mapped_view<int>(mfh2);
+ v1 = algorithm::mapped_span<int>(mfh2);
BOOST_CHECK(v1.size() == 10000);
v1[0] = 78;
v1[9999] = 79;
// On Windows this will have updated the mapping, on POSIX it will not, so prod POSIX
mfh.update_map().value();
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_CHECK(v1.size() == 10000);
BOOST_CHECK(v1[0] == 78);
BOOST_CHECK(v1[9999] == 79);
@@ -126,7 +126,7 @@ static inline void TestMappedView2()
fh.truncate(10000 * sizeof(int)).value();
// On POSIX this will have updated the mapping, on Windows it will not, so prod Windows
mfh.update_map().value();
- v1 = algorithm::mapped_view<int>(mfh);
+ v1 = algorithm::mapped_span<int>(mfh);
BOOST_REQUIRE(v1.size() == 10000);
BOOST_CHECK(v1[0] == 78);
BOOST_CHECK(v1[9999] == 0);
@@ -135,5 +135,5 @@ static inline void TestMappedView2()
BOOST_CHECK(mfh.address() == nullptr);
}
-KERNELTEST_TEST_KERNEL(integration, afio, algorithm, mapped_view1, "Tests that afio::algorithm::mapped_view works as expected", TestMappedView1())
-KERNELTEST_TEST_KERNEL(integration, afio, algorithm, mapped_view2, "Tests that afio::algorithm::mapped_view works as expected", TestMappedView2())
+KERNELTEST_TEST_KERNEL(integration, afio, algorithm, mapped_span1, "Tests that afio::algorithm::mapped_span works as expected", TestMappedView1())
+KERNELTEST_TEST_KERNEL(integration, afio, algorithm, mapped_span2, "Tests that afio::algorithm::mapped_span works as expected", TestMappedView2())