From 487b9a266f9a2d5e81902fde842c41cbd53f1ce4 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Wed, 11 Apr 2018 12:09:48 +0100 Subject: Convert AFIO over to use std::byte for buffers instead of char. --- Readme.md | 1 + example/use_cases.cpp | 27 ++++++++------- include/afio/revision.hpp | 6 ++-- include/afio/v2.0/algorithm/mapped_span.hpp | 14 ++++---- .../algorithm/shared_fs_mutex/atomic_append.hpp | 18 +++++----- .../v2.0/algorithm/shared_fs_mutex/memory_map.hpp | 4 +-- include/afio/v2.0/config.hpp | 6 ++++ .../v2.0/detail/impl/posix/async_file_handle.ipp | 2 +- .../afio/v2.0/detail/impl/posix/file_handle.ipp | 6 ++-- include/afio/v2.0/detail/impl/posix/map_handle.ipp | 18 +++++----- .../v2.0/detail/impl/posix/mapped_file_handle.ipp | 4 +-- include/afio/v2.0/detail/impl/storage_profile.ipp | 20 +++++------ .../v2.0/detail/impl/windows/async_file_handle.ipp | 2 +- .../afio/v2.0/detail/impl/windows/map_handle.ipp | 38 ++++++++++----------- include/afio/v2.0/io_handle.hpp | 18 +++++++--- include/afio/v2.0/map_handle.hpp | 12 +++---- include/afio/v2.0/mapped_file_handle.hpp | 17 ++++++---- include/afio/v2.0/quickcpplib | 2 +- include/afio/v2.0/utils.hpp | 2 +- release_notes.md | 4 +-- test/tests/async_io.cpp | 39 +++++++++++----------- test/tests/coroutines.cpp | 4 +-- test/tests/map_handle_create_close/runner.cpp | 8 ++--- test/tests/mapped_span.cpp | 3 +- test/tests/section_handle_create_close/runner.cpp | 2 +- 25 files changed, 152 insertions(+), 125 deletions(-) diff --git a/Readme.md b/Readme.md index aeadebb6..5b0e4581 100644 --- a/Readme.md +++ b/Readme.md @@ -15,6 +15,7 @@ Tarballs of source and prebuilt binaries for Linux x64, MacOS x64 and Windows x6 - [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`. +- [ ] Scatter-gather buffers to use https://github.com/martinmoene/byte-lite - [ ] 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 diff --git a/example/use_cases.cpp b/example/use_cases.cpp index 3f8d277f..c3b7ab0e 100644 --- a/example/use_cases.cpp +++ b/example/use_cases.cpp @@ -28,6 +28,9 @@ Distributed under the Boost Software License, Version 1.0. #include // clang-format off +#ifdef _MSC_VER +#pragma warning(disable: 4706) // assignment within conditional +#endif void read_entire_file1() { @@ -45,7 +48,7 @@ void read_entire_file1() ).value(); // If failed, throw a filesystem_error exception // Make a vector sized the current length of the file - std::vector buffer(fh.length().value()); + std::vector buffer(fh.length().value()); // Synchronous scatter read from file afio::file_handle::buffers_type filled = afio::read( @@ -86,11 +89,11 @@ void scatter_write() const char d[] = "orld"; fh.write(0, // offset - { // gather list - { a, sizeof(a) - 1 }, - { b, sizeof(b) - 1 }, - { c, sizeof(c) - 1 }, - { d, sizeof(d) - 1 }, + { // gather list, buffers use std::byte + { reinterpret_cast(a), sizeof(a) - 1 }, + { reinterpret_cast(b), sizeof(b) - 1 }, + { reinterpret_cast(c), sizeof(c) - 1 }, + { reinterpret_cast(d), sizeof(d) - 1 }, } // default deadline is infinite ).value(); // If failed, throw a filesystem_error exception @@ -133,9 +136,9 @@ void map_file() // Append stuff to append only handle afio::write(afh, - 0, // offset is ignored for atomic append only handles - {{ "hello" }} // single gather buffer - // default deadline is infinite + 0, // offset is ignored for atomic append only handles + {{ reinterpret_cast("hello"), 6 }} // single gather buffer + // default deadline is infinite ).value(); // Poke map to update itself into its reservation if necessary to match its backing @@ -143,7 +146,7 @@ void map_file() size_t length = mh.update_map().value(); // Find my appended text - for (char *p = mh.address(); (p = (char *) memchr(p, 'h', mh.address() + length - p)); p++) + for (char *p = reinterpret_cast(mh.address()); (p = (char *) memchr(p, 'h', reinterpret_cast(mh.address()) + length - p)); p++) { if (strcmp(p, "hello")) { @@ -171,7 +174,7 @@ void mapped_file() auto length = mh.length().value(); // Find my text - for (char *p = mh.address(); (p = (char *)memchr(p, 'h', mh.address() + length - p)); p++) + for (char *p = reinterpret_cast(mh.address()); (p = (char *)memchr(p, 'h', reinterpret_cast(mh.address()) + length - p)); p++) { if (strcmp(p, "hello")) { @@ -222,7 +225,7 @@ std::future coroutine_write() // suspending execution of this coroutine until completion and then resuming // execution. Requires the Coroutines TS. alignas(4096) char buffer[] = "hello world"; - co_await co_write(fh, 0, { { buffer, sizeof(buffer) } }).value(); + co_await co_write(fh, 0, { { reinterpret_cast(buffer), sizeof(buffer) } }).value(); //! [coroutine_write] } #endif diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp index babc0a38..2989e199 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 59bddf7442aacad75a729dbfa22167fbf7adaefd -#define AFIO_PREVIOUS_COMMIT_DATE "2018-04-07 23:18:09 +00:00" -#define AFIO_PREVIOUS_COMMIT_UNIQUE 59bddf74 +#define AFIO_PREVIOUS_COMMIT_REF ed04b40b799d1cb2b4c1787b9a1089050e3c89ae +#define AFIO_PREVIOUS_COMMIT_DATE "2018-04-08 01:51:32 +00:00" +#define AFIO_PREVIOUS_COMMIT_UNIQUE ed04b40b diff --git a/include/afio/v2.0/algorithm/mapped_span.hpp b/include/afio/v2.0/algorithm/mapped_span.hpp index 29081720..52ada81e 100644 --- a/include/afio/v2.0/algorithm/mapped_span.hpp +++ b/include/afio/v2.0/algorithm/mapped_span.hpp @@ -55,7 +55,7 @@ namespace algorithm : _mapping(map_handle::map(sh, (bytes == 0) ? 0 : bytes + (offset - page_offset), page_offset, _flag).value()) { offset -= page_offset; - char *addr = _mapping.address() + offset; + byte *addr = _mapping.address() + offset; size_t len = sh.length().value() - offset; // use section length, not mapped length as mapped length is rounded up to page size if(bytes != 0 && bytes < len) { @@ -67,15 +67,15 @@ namespace algorithm public: //! Default constructor 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()`. - */ + /*! 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_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(); + byte *addr = _mapping.address(); static_cast &>(*this) = span(reinterpret_cast(addr), length); // NOLINT } /*! Construct a mapped view of the given section handle. diff --git a/include/afio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp b/include/afio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp index deed9320..8fdfdfe4 100644 --- a/include/afio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp +++ b/include/afio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp @@ -138,8 +138,8 @@ namespace algorithm bool first = true; do { - OUTCOME_TRY(_, _h.read(0, {{reinterpret_cast(&_header), 48}})); - if(_[0].data != reinterpret_cast(&_header)) + OUTCOME_TRY(_, _h.read(0, {{reinterpret_cast(&_header), 48}})); + if(_[0].data != reinterpret_cast(&_header)) { memcpy(&_header, _[0].data, _[0].len); } @@ -220,7 +220,7 @@ namespace algorithm { header.hash = QUICKCPPLIB_NAMESPACE::algorithm::hash::fast_hash::hash((reinterpret_cast(&header)) + 16, sizeof(header) - 16); } - OUTCOME_TRYV(ret.write(0, {{reinterpret_cast(&header), sizeof(header)}})); + OUTCOME_TRYV(ret.write(0, {{reinterpret_cast(&header), sizeof(header)}})); } // Open a shared lock on last byte in header to prevent other users zomping the file OUTCOME_TRY(guard, ret.lock(sizeof(header) - 1, 1, false)); @@ -287,11 +287,11 @@ namespace algorithm OUTCOME_TRY(append_guard_, _h.lock(my_lock_request_offset, lastbyte, true)); append_guard = std::move(append_guard_); } - OUTCOME_TRYV(_h.write(0, {{reinterpret_cast(&lock_request), sizeof(lock_request)}})); + OUTCOME_TRYV(_h.write(0, {{reinterpret_cast(&lock_request), sizeof(lock_request)}})); } // Find the record I just wrote - alignas(64) char _buffer[4096 + 2048]; // 6Kb cache line aligned buffer + alignas(64) byte _buffer[4096 + 2048]; // 6Kb cache line aligned buffer // Read onwards from length as reported before I wrote my lock request // until I find my lock request. This loop should never actually iterate // except under extreme load conditions. @@ -473,7 +473,7 @@ namespace algorithm { atomic_append_detail::lock_request record; #ifdef _DEBUG - (void) _h.read(my_lock_request_offset, {{(char *) &record, sizeof(record)}}); + (void) _h.read(my_lock_request_offset, {{(byte *) &record, sizeof(record)}}); if(!record.unique_id) { AFIO_LOG_FATAL(this, "atomic_append::unlock() I have been previously unlocked!"); @@ -487,7 +487,7 @@ namespace algorithm } #endif memset(&record, 0, sizeof(record)); - (void) _h.write(my_lock_request_offset, {{reinterpret_cast(&record), sizeof(record)}}); + (void) _h.write(my_lock_request_offset, {{reinterpret_cast(&record), sizeof(record)}}); } // Every 32 records or so, bump _header.first_known_good @@ -497,7 +497,7 @@ namespace algorithm // Forward scan records until first non-zero record is found // and update header with new info - alignas(64) char _buffer[4096 + 2048]; + alignas(64) byte _buffer[4096 + 2048]; bool done = false; while(!done) { @@ -543,7 +543,7 @@ namespace algorithm _header.hash = QUICKCPPLIB_NAMESPACE::algorithm::hash::fast_hash::hash((reinterpret_cast(&_header)) + 16, sizeof(_header) - 16); } // Rewrite the first part of the header only - (void) _h.write(0, {{reinterpret_cast(&_header), 48}}); + (void) _h.write(0, {{reinterpret_cast(&_header), 48}}); } } }; diff --git a/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp b/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp index 8f9b0287..18f57834 100644 --- a/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp +++ b/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp @@ -208,7 +208,7 @@ namespace algorithm { return lockinuse.error(); } - char buffer[65536]; + byte buffer[65536]; memset(buffer, 0, sizeof(buffer)); OUTCOME_TRYV(ret.read(0, {{buffer, 65535}})); path_view temphpath(reinterpret_cast(buffer)); @@ -244,7 +244,7 @@ namespace algorithm char buffer[4096]; memset(buffer, 0, sizeof(buffer)); size_t bytes = temppath.native().size() * sizeof(*temppath.c_str()); - file_handle::const_buffer_type buffers[] = {{reinterpret_cast(temppath.c_str()), bytes}, {static_cast(buffer), 4096 - (bytes % 4096)}}; + file_handle::const_buffer_type buffers[] = {{reinterpret_cast(temppath.c_str()), bytes}, {reinterpret_cast(buffer), 4096 - (bytes % 4096)}}; OUTCOME_TRYV(ret.truncate(65536)); OUTCOME_TRYV(ret.write({buffers, 0})); // Map for read the maximum possible path file size, again to avoid race problems diff --git a/include/afio/v2.0/config.hpp b/include/afio/v2.0/config.hpp index fa8589d1..ff1817d7 100644 --- a/include/afio/v2.0/config.hpp +++ b/include/afio/v2.0/config.hpp @@ -306,6 +306,12 @@ AFIO_V2_NAMESPACE_END AFIO_V2_NAMESPACE_BEGIN using namespace QUICKCPPLIB_NAMESPACE::optional; AFIO_V2_NAMESPACE_END +// Bring in a byte implementation +#include "quickcpplib/include/byte.hpp" +AFIO_V2_NAMESPACE_BEGIN +using QUICKCPPLIB_NAMESPACE::byte::byte; +using QUICKCPPLIB_NAMESPACE::byte::to_byte; +AFIO_V2_NAMESPACE_END // Bring in a string_view implementation #include "quickcpplib/include/string_view.hpp" AFIO_V2_NAMESPACE_BEGIN diff --git a/include/afio/v2.0/detail/impl/posix/async_file_handle.ipp b/include/afio/v2.0/detail/impl/posix/async_file_handle.ipp index 7f259a3d..e6bc0ba2 100644 --- a/include/afio/v2.0/detail/impl/posix/async_file_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/async_file_handle.ipp @@ -235,7 +235,7 @@ template resultaiocbs + n; aiocb->aio_fildes = _v.fd; aiocb->aio_offset = offset; - aiocb->aio_buf = reinterpret_cast(const_cast(out[n].data)); + aiocb->aio_buf = reinterpret_cast(const_cast(out[n].data)); aiocb->aio_nbytes = out[n].len; aiocb->aio_sigevent.sigev_notify = SIGEV_NONE; aiocb->aio_sigevent.sigev_value.sival_ptr = reinterpret_cast(state); diff --git a/include/afio/v2.0/detail/impl/posix/file_handle.ipp b/include/afio/v2.0/detail/impl/posix/file_handle.ipp index 13e0e779..3b3afa98 100644 --- a/include/afio/v2.0/detail/impl/posix/file_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/file_handle.ipp @@ -462,7 +462,7 @@ result file_handle::zero(file_handle::extent_type offs // Fall back onto a write of zeros if(bytes < utils::page_size()) { - auto *buffer = static_cast(alloca(bytes)); + auto *buffer = static_cast(alloca(bytes)); memset(buffer, 0, bytes); OUTCOME_TRY(written, write(offset, {{buffer, bytes}}, d)); return written[0].len; @@ -471,8 +471,8 @@ result file_handle::zero(file_handle::extent_type offs { extent_type ret = 0; auto blocksize = utils::file_buffer_default_size(); - char *buffer = utils::page_allocator().allocate(blocksize); - auto unbufferh = undoer([buffer, blocksize] { utils::page_allocator().deallocate(buffer, blocksize); }); + byte *buffer = utils::page_allocator().allocate(blocksize); + auto unbufferh = undoer([buffer, blocksize] { utils::page_allocator().deallocate(buffer, blocksize); }); (void) unbufferh; while(bytes > 0) { 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 e5ebfebe..f4b3443a 100644 --- a/include/afio/v2.0/detail/impl/posix/map_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/map_handle.ipp @@ -174,7 +174,7 @@ native_handle_type map_handle::release() noexcept map_handle::io_result map_handle::barrier(map_handle::io_request reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; extent_type bytes = 0; // Check for overflow for(const auto &req : reqs.buffers) @@ -293,7 +293,7 @@ result map_handle::map(size_type bytes, section_handle::flag _flag) result ret(map_handle(nullptr)); native_handle_type &nativeh = ret.value()._v; OUTCOME_TRY(addr, do_mmap(nativeh, nullptr, 0, nullptr, bytes, 0, _flag)); - ret.value()._addr = static_cast(addr); + ret.value()._addr = static_cast(addr); ret.value()._reservation = bytes; ret.value()._length = bytes; AFIO_LOG_FUNCTION_CALL(&ret); @@ -310,7 +310,7 @@ result map_handle::map(section_handle §ion, size_type bytes, ext result ret{map_handle(§ion)}; native_handle_type &nativeh = ret.value()._v; OUTCOME_TRY(addr, do_mmap(nativeh, nullptr, 0, §ion, bytes, offset, _flag)); - ret.value()._addr = static_cast(addr); + ret.value()._addr = static_cast(addr); ret.value()._offset = offset; ret.value()._reservation = bytes; ret.value()._length = (length - offset < bytes) ? (length - offset) : bytes; // length of backing, not reservation @@ -348,7 +348,7 @@ result map_handle::truncate(size_type newsize, bool permi if(_addr == nullptr) { OUTCOME_TRY(addr, do_mmap(_v, nullptr, 0, _section, newsize, _offset, _flag)); - _addr = static_cast(addr); + _addr = static_cast(addr); _reservation = newsize; _length = (length - _offset < newsize) ? (length - _offset) : newsize; // length of backing, not reservation return newsize; @@ -360,7 +360,7 @@ result map_handle::truncate(size_type newsize, bool permi { return {errno, std::system_category()}; } - _addr = static_cast(newaddr); + _addr = static_cast(newaddr); _reservation = newsize; _length = (length - _offset < newsize) ? (length - _offset) : newsize; // length of backing, not reservation return newsize; @@ -368,7 +368,7 @@ result map_handle::truncate(size_type newsize, bool permi if(newsize > _length) { #if defined(MAP_EXCL) // BSD type systems - char *addrafter = _addr + _reservation; + byte *addrafter = _addr + _reservation; size_type bytes = newsize - _reservation; extent_type offset = _offset + _reservation; OUTCOME_TRY(addr, do_mmap(_v, addrafter, MAP_FIXED | MAP_EXCL, _section, bytes, offset, _flag)); @@ -376,7 +376,7 @@ result map_handle::truncate(size_type newsize, bool permi _length = (length - _offset < newsize) ? (length - _offset) : newsize; // length of backing, not reservation return newsize; #else // generic POSIX, inefficient - char *addrafter = _addr + _reservation; + byte *addrafter = _addr + _reservation; size_type bytes = newsize - _reservation; extent_type offset = _offset + _reservation; OUTCOME_TRY(addr, do_mmap(_v, addrafter, 0, _section, bytes, offset, _flag)); @@ -505,7 +505,7 @@ result map_handle::do_not_store(buffer_type region) noe map_handle::io_result map_handle::read(io_request reqs, deadline /*d*/) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; size_type togo = reqs.offset < _length ? static_cast(_length - reqs.offset) : 0; for(buffer_type &req : reqs.buffers) { @@ -530,7 +530,7 @@ map_handle::io_result map_handle::read(io_request map_handle::write(io_request reqs, deadline /*d*/) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; size_type togo = reqs.offset < _length ? static_cast(_length - reqs.offset) : 0; for(const_buffer_type &req : reqs.buffers) { diff --git a/include/afio/v2.0/detail/impl/posix/mapped_file_handle.ipp b/include/afio/v2.0/detail/impl/posix/mapped_file_handle.ipp index e5c10062..8999a655 100644 --- a/include/afio/v2.0/detail/impl/posix/mapped_file_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/mapped_file_handle.ipp @@ -116,8 +116,8 @@ result mapped_file_handle::truncate(extent_type // otherwise some kernels keep them around until last fd close, effectively leaking them if(newsize < size) { - char *start = utils::round_up_to_page_size(_mh.address() + newsize); - char *end = utils::round_up_to_page_size(_mh.address() + size); + byte *start = utils::round_up_to_page_size(_mh.address() + newsize); + byte *end = utils::round_up_to_page_size(_mh.address() + size); (void) _mh.do_not_store({start, static_cast(end - start)}); } // Resize the file, on unified page cache kernels it'll map any new pages into the reserved map diff --git a/include/afio/v2.0/detail/impl/storage_profile.ipp b/include/afio/v2.0/detail/impl/storage_profile.ipp index 8dbb5329..034b8dcc 100644 --- a/include/afio/v2.0/detail/impl/storage_profile.ipp +++ b/include/afio/v2.0/detail/impl/storage_profile.ipp @@ -425,7 +425,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, no); + std::vector> buffer(size, to_byte(no)); file_handle::const_buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, 0); --done; @@ -464,7 +464,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, 0), tocmp(size, 0); + std::vector> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); file_handle::buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, 0); while(done == 0u) @@ -570,7 +570,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, no); + std::vector> buffer(size, to_byte(no)); file_handle::const_buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, offset); --done; @@ -610,7 +610,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, 0), tocmp(size, 0); + std::vector> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); file_handle::buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, offset); while(done == 0u) @@ -731,7 +731,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, no); + std::vector> buffer(size, to_byte(no)); file_handle::const_buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, offset); --done; @@ -771,7 +771,7 @@ namespace storage_profile _h.error().message()); } file_handle h(std::move(_h.value())); - std::vector> buffer(size, 0), tocmp(size, 0); + std::vector> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); file_handle::buffer_type _reqs[1] = {{buffer.data(), size}}; file_handle::io_request reqs(_reqs, offset); while(done == 0u) @@ -867,7 +867,7 @@ namespace storage_profile path_handle base = srch.parent_path_handle().value(); if(ownfiles) { - std::vector> buffer(1024 * 1024 * 1024); + std::vector> buffer(1024 * 1024 * 1024); for(size_t n = 0; n < noreaders + nowriters; n++) { auto fh = file_handle::file(base, std::to_string(n), file_handle::mode::write, file_handle::creation::open_existing, srch.kernel_caching(), srch.flags()); @@ -899,7 +899,7 @@ namespace storage_profile SetThreadAffinityMask(GetCurrentThread(), 1ULL << (no * 2)); #endif file_handle &h = *workfiles[no]; - alignas(4096) char buffer[4096]; + alignas(4096) byte buffer[4096]; memset(buffer, static_cast(no), 4096); file_handle::const_buffer_type _reqs[1] = {{buffer, 4096}}; file_handle::io_request reqs(_reqs, 0); @@ -938,7 +938,7 @@ namespace storage_profile SetThreadAffinityMask(GetCurrentThread(), 1ULL << (no * 2)); #endif file_handle &h = *workfiles[no]; - alignas(4096) char buffer[4096]; + alignas(4096) byte buffer[4096]; memset(buffer, static_cast(no), 4096); file_handle::buffer_type _reqs[1] = {{buffer, 4096}}; file_handle::io_request reqs(_reqs, 0); @@ -1189,7 +1189,7 @@ namespace storage_profile std::string filename; filename.reserve(16); std::chrono::high_resolution_clock::time_point begin, end; - alignas(4096) char buffer[4096]; + alignas(4096) byte buffer[4096]; memset(buffer, 78, sizeof(buffer)); if(!race_free) { diff --git a/include/afio/v2.0/detail/impl/windows/async_file_handle.ipp b/include/afio/v2.0/detail/impl/windows/async_file_handle.ipp index 6b8b5de7..55f4ddf7 100644 --- a/include/afio/v2.0/detail/impl/windows/async_file_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/async_file_handle.ipp @@ -186,7 +186,7 @@ template result(out[n].data), static_cast(out[n].len), ol, handle_completion::Do)) + if(!ioroutine(_v.h, const_cast(out[n].data), static_cast(out[n].len), ol, handle_completion::Do)) { --state->items_to_go; state->result.write = {GetLastError(), std::system_category()}; 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 858d3ec1..0b8b2999 100644 --- a/include/afio/v2.0/detail/impl/windows/map_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/map_handle.ipp @@ -310,12 +310,12 @@ static inline void win32_map_flags(native_handle_type &nativeh, DWORD &allocatio } } // Used to apply an operation to all maps within a region -template static inline result win32_maps_apply(char *addr, size_t bytes, F &&f) +template static inline result win32_maps_apply(byte *addr, size_t bytes, F &&f) { while(bytes > 0) { MEMORY_BASIC_INFORMATION mbi; - char *thisregion = addr; + byte *thisregion = addr; // Need to iterate until AllocationBase changes for(;;) { @@ -344,7 +344,7 @@ template static inline result win32_maps_apply(char *addr, size_ } // Only for memory allocated with VirtualAlloc. We can special case decommitting or releasing // memory because NtFreeVirtualMemory() tells us how much it freed. -static inline result win32_release_allocations(char *addr, size_t bytes, ULONG op) +static inline result win32_release_allocations(byte *addr, size_t bytes, ULONG op) { windows_nt_kernel::init(); using namespace windows_nt_kernel; @@ -391,7 +391,7 @@ result map_handle::close() noexcept { OUTCOME_TRYV(barrier({}, true, false)); } - OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, [](char *addr, size_t /* unused */) -> result { + OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, [](byte *addr, size_t /* unused */) -> result { NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr); if(ntstat < 0) { @@ -425,7 +425,7 @@ native_handle_type map_handle::release() noexcept map_handle::io_result map_handle::barrier(map_handle::io_request reqs, bool wait_for_device, bool and_metadata, deadline d) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; extent_type bytes = 0; // Check for overflow for(const auto &req : reqs.buffers) @@ -450,7 +450,7 @@ map_handle::io_result map_handle::barrier(map_ha return {reqs.buffers}; } } - OUTCOME_TRYV(win32_maps_apply(addr, bytes, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(addr, bytes, [](byte *addr, size_t bytes) -> result { if(FlushViewOfFile(addr, static_cast(bytes)) == 0) { return {GetLastError(), std::system_category()}; @@ -483,7 +483,7 @@ result map_handle::map(size_type bytes, section_handle::flag _flag) { return {GetLastError(), std::system_category()}; } - ret.value()._addr = static_cast(addr); + ret.value()._addr = static_cast(addr); ret.value()._reservation = bytes; ret.value()._length = bytes; @@ -492,7 +492,7 @@ result map_handle::map(size_type bytes, section_handle::flag _flag) { using namespace windows_nt_kernel; // Start an asynchronous prefetch - buffer_type b{static_cast(addr), bytes}; + buffer_type b{static_cast(addr), bytes}; (void) prefetch(span(&b, 1)); // If this kernel doesn't support that API, manually poke every page in the new map if(PrefetchVirtualMemory_ == nullptr) @@ -527,7 +527,7 @@ result map_handle::map(section_handle §ion, size_type bytes, ext { return {static_cast(ntstat), ntkernel_category()}; } - ret.value()._addr = static_cast(addr); + ret.value()._addr = static_cast(addr); ret.value()._offset = offset; ret.value()._reservation = _bytes; ret.value()._length = section.length().value() - offset; @@ -538,7 +538,7 @@ result map_handle::map(section_handle §ion, size_type bytes, ext if(_flag & section_handle::flag::prefault) { // Start an asynchronous prefetch - buffer_type b{static_cast(addr), _bytes}; + buffer_type b{static_cast(addr), _bytes}; (void) prefetch(span(&b, 1)); // If this kernel doesn't support that API, manually poke every page in the new map if(PrefetchVirtualMemory_ == nullptr) @@ -601,7 +601,7 @@ result map_handle::truncate(size_type newsize, bool /* un if(newsize < _reservation) { // If newsize isn't exactly a previous extension, this will fail, same as for the VirtualAlloc case - OUTCOME_TRYV(win32_maps_apply(_addr + newsize, _reservation - newsize, [](char *addr, size_t /* unused */) -> result { + OUTCOME_TRYV(win32_maps_apply(_addr + newsize, _reservation - newsize, [](byte *addr, size_t /* unused */) -> result { NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr); if(ntstat < 0) { @@ -642,7 +642,7 @@ result map_handle::commit(buffer_type region, section_h DWORD prot = 0; if(flag == section_handle::flag::none) { - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](byte *addr, size_t bytes) -> result { DWORD _ = 0; if(VirtualProtect(addr, bytes, PAGE_NOACCESS, &_) == 0) { @@ -669,7 +669,7 @@ result map_handle::commit(buffer_type region, section_h prot = PAGE_EXECUTE; } region = utils::round_to_page_size(region); - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [prot](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [prot](byte *addr, size_t bytes) -> result { if(VirtualAlloc(addr, bytes, MEM_COMMIT, prot) == nullptr) { return {GetLastError(), std::system_category()}; @@ -687,7 +687,7 @@ result map_handle::decommit(buffer_type region) noexcep return std::errc::invalid_argument; } region = utils::round_to_page_size(region); - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](byte *addr, size_t bytes) -> result { if(VirtualFree(addr, bytes, MEM_DECOMMIT) == 0) { return {GetLastError(), std::system_category()}; @@ -713,7 +713,7 @@ result map_handle::zero_memory(buffer_type region) noexcept region = utils::round_to_page_size(region); if(region.len > 0) { - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](byte *addr, size_t bytes) -> result { if(DiscardVirtualMemory_(addr, bytes) == 0) { return {GetLastError(), std::system_category()}; @@ -758,7 +758,7 @@ result map_handle::do_not_store(buffer_type region) noe // Win8's DiscardVirtualMemory is much faster if it's available if(DiscardVirtualMemory_ != nullptr) { - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](byte *addr, size_t bytes) -> result { if(DiscardVirtualMemory_(addr, bytes) == 0) { return {GetLastError(), std::system_category()}; @@ -768,7 +768,7 @@ result map_handle::do_not_store(buffer_type region) noe return region; } // Else MEM_RESET will do - OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](char *addr, size_t bytes) -> result { + OUTCOME_TRYV(win32_maps_apply(region.data, region.len, [](byte *addr, size_t bytes) -> result { if(VirtualAlloc(addr, bytes, MEM_RESET, 0) == nullptr) { return {GetLastError(), std::system_category()}; @@ -785,7 +785,7 @@ result map_handle::do_not_store(buffer_type region) noe map_handle::io_result map_handle::read(io_request reqs, deadline /*d*/) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; size_type togo = reqs.offset < _length ? static_cast(_length - reqs.offset) : 0; for(buffer_type &req : reqs.buffers) { @@ -810,7 +810,7 @@ map_handle::io_result map_handle::read(io_request map_handle::write(io_request reqs, deadline /*d*/) noexcept { AFIO_LOG_FUNCTION_CALL(this); - char *addr = _addr + reqs.offset; + byte *addr = _addr + reqs.offset; size_type togo = reqs.offset < _length ? static_cast(_length - reqs.offset) : 0; for(const_buffer_type &req : reqs.buffers) { diff --git a/include/afio/v2.0/io_handle.hpp b/include/afio/v2.0/io_handle.hpp index e9ba0bdb..7248a94d 100644 --- a/include/afio/v2.0/io_handle.hpp +++ b/include/afio/v2.0/io_handle.hpp @@ -53,18 +53,28 @@ public: //! The scatter buffer type used by this handle. Guaranteed to be `TrivialType` and `StandardLayoutType`. struct buffer_type { + //! Type of the pointer to memory. + using pointer = byte *; + //! Type of the length of memory. + using size_type = size_t; + //! Pointer to memory to be filled by a read. Try to make this 64 byte, or ideally, `page_size()` aligned where possible. - char *data; + pointer data; //! The number of bytes to fill into this address. Try to make this a 64 byte multiple, or ideally, a whole multiple of `page_size()`. - size_t len; + size_type len; }; //! The gather buffer type used by this handle. Guaranteed to be `TrivialType` and `StandardLayoutType`. struct const_buffer_type { + //! Type of the pointer to memory. + using pointer = const byte *; + //! Type of the length of memory. + using size_type = size_t; + //! Pointer to memory to be written. Try to make this 64 byte, or ideally, `page_size()` aligned where possible. - const char *data; + pointer data; //! The number of bytes to write from this address. Try to make this a 64 byte multiple, or ideally, a whole multiple of `page_size()`. - size_t len; + size_type len; }; #ifndef NDEBUG static_assert(std::is_trivial::value, "buffer_type is not a trivial type!"); diff --git a/include/afio/v2.0/map_handle.hpp b/include/afio/v2.0/map_handle.hpp index e9b350c5..bceac389 100644 --- a/include/afio/v2.0/map_handle.hpp +++ b/include/afio/v2.0/map_handle.hpp @@ -297,7 +297,7 @@ public: protected: section_handle *_section{nullptr}; - char *_addr{nullptr}; + byte *_addr{nullptr}; extent_type _offset{0}; size_type _reservation{0}, _length{0}; section_handle::flag _flag{section_handle::flag::none}; @@ -360,14 +360,14 @@ public: 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 + static const_buffer_type barrier(const_buffer_type req, bool evict = false) noexcept { - const_buffer_type ret{(const char *) (((uintptr_t) req.data) & 31), 0}; + const_buffer_type ret{(const_buffer_type::pointer)(((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) + for(const_buffer_type::pointer addr = ret.data; addr < ret.data + ret.len; addr += 32) { // Slightly UB ... - auto *p = reinterpret_cast *>(addr); + auto *p = reinterpret_cast *>(addr); if(memory_flush_none == p->flush(evict ? memory_flush_evict : memory_flush_retain)) { req.len = 0; @@ -408,7 +408,7 @@ public: void set_section(section_handle *s) noexcept { _section = s; } //! The address in memory where this mapped view resides - char *address() const noexcept { return _addr; } + byte *address() const noexcept { return _addr; } //! The offset of the memory map. extent_type offset() const noexcept { return _offset; } diff --git a/include/afio/v2.0/mapped_file_handle.hpp b/include/afio/v2.0/mapped_file_handle.hpp index a56b7688..21ead25c 100644 --- a/include/afio/v2.0/mapped_file_handle.hpp +++ b/include/afio/v2.0/mapped_file_handle.hpp @@ -294,7 +294,7 @@ public: map_handle &map() noexcept { return _mh; } //! The address in memory where this mapped file resides - char *address() const noexcept { return _mh.address(); } + byte *address() const noexcept { return _mh.address(); } //! The length of the underlying file result underlying_file_length() const noexcept { return file_handle::length(); } @@ -431,12 +431,15 @@ 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(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(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(reservation), std::forward(base), std::forward(_path), std::forward(_mode), std::forward(_creation), std::forward(_caching), std::forward(flags)); + return mapped_file_handle::mapped_file(std::forward(reservation), std::forward(base), std::forward(_path), std::forward(_mode), std::forward(_creation), std::forward(_caching), + std::forward(flags)); } //! \overload -inline result 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(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(base), std::forward(_path), std::forward(_mode), std::forward(_creation), std::forward(_caching), std::forward(flags)); } @@ -448,7 +451,8 @@ flush changes to physical storage as lately as possible. \errors Any of the values POSIX open() or CreateFile() can return. */ -inline result 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_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(reservation), std::forward(dirpath), std::forward(_mode), std::forward(_caching), std::forward(flags)); } @@ -467,7 +471,8 @@ 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_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_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(reservation), std::forward(name), std::forward(_mode), std::forward(_creation), std::forward(_caching), std::forward(flags)); } diff --git a/include/afio/v2.0/quickcpplib b/include/afio/v2.0/quickcpplib index a36840f8..fae98228 160000 --- a/include/afio/v2.0/quickcpplib +++ b/include/afio/v2.0/quickcpplib @@ -1 +1 @@ -Subproject commit a36840f8f104773efaaa50737c81294071d0439b +Subproject commit fae982283648633c89790c42cd4e661cc895dfde diff --git a/include/afio/v2.0/utils.hpp b/include/afio/v2.0/utils.hpp index f854be5e..5869bf2a 100644 --- a/include/afio/v2.0/utils.hpp +++ b/include/afio/v2.0/utils.hpp @@ -68,7 +68,7 @@ namespace utils template inline T round_to_page_size(T i) noexcept { const size_t pagesize = page_size(); - i.data = reinterpret_cast((AFIO_V2_NAMESPACE::detail::unsigned_integer_cast(i.data)) & ~(pagesize - 1)); + i.data = reinterpret_cast((AFIO_V2_NAMESPACE::detail::unsigned_integer_cast(i.data)) & ~(pagesize - 1)); i.len = (i.len + pagesize - 1) & ~(pagesize - 1); return i; } diff --git a/release_notes.md b/release_notes.md index a45ebbb9..7c88f0d9 100644 --- a/release_notes.md +++ b/release_notes.md @@ -38,10 +38,10 @@ Examples of use:
-\snippet sparse_array +\snippet use_cases.cpp sparse_array -\snippet coroutine_write +\snippet use_cases.cpp coroutine_write
diff --git a/test/tests/async_io.cpp b/test/tests/async_io.cpp index ed202d11..bb4be9fa 100644 --- a/test/tests/async_io.cpp +++ b/test/tests/async_io.cpp @@ -34,7 +34,7 @@ static inline void TestAsyncFileHandle() std::vector, afio::async_file_handle::io_state_ptr>> futures; futures.reserve(1024); h.truncate(1024 * 4096).value(); - alignas(4096) char buffer[4096]; + alignas(4096) afio::byte buffer[4096]; memset(buffer, 78, 4096); // NOLINT afio::async_file_handle::const_buffer_type bt{buffer, sizeof(buffer)}; // NOLINT for(size_t n = 0; n < 1024; n++) @@ -42,24 +42,25 @@ static inline void TestAsyncFileHandle() retry: std::promise p; auto f(p.get_future()); - auto schedule_io = [&]{ return h - .async_write({bt, n * 4096}, [ p = std::move(p), n ](afio::async_file_handle *, afio::async_file_handle::io_result & result) mutable { - (void) n; - if(!result && result.error() == std::errc::resource_unavailable_try_again) - { - std::cout << "*** Completion handler saw error " << result.error() << std::endl; - } - try - { - p.set_value(result.value()); - // std::cout << "Written block " << n << " successfully" << std::endl; - } - catch(...) - { - p.set_exception(std::current_exception()); - // std::cout << "Written block " << n << " unsuccessfully" << std::endl; - } - }); }; + auto schedule_io = [&] { + return h.async_write({bt, n * 4096}, [ p = std::move(p), n ](afio::async_file_handle *, afio::async_file_handle::io_result & result) mutable { + (void) n; + if(!result && result.error() == std::errc::resource_unavailable_try_again) + { + std::cout << "*** Completion handler saw error " << result.error() << std::endl; + } + try + { + p.set_value(result.value()); + // std::cout << "Written block " << n << " successfully" << std::endl; + } + catch(...) + { + p.set_exception(std::current_exception()); + // std::cout << "Written block " << n << " unsuccessfully" << std::endl; + } + }); + }; auto g(schedule_io()); if(!g && g.error() == std::errc::resource_unavailable_try_again) { diff --git a/test/tests/coroutines.cpp b/test/tests/coroutines.cpp index 35c89291..ec534793 100644 --- a/test/tests/coroutines.cpp +++ b/test/tests/coroutines.cpp @@ -43,7 +43,7 @@ static inline void TestAsyncFileHandleCoroutines() // Launch 8 coroutines, each writing 4Kb of chars 0-8 to every 32Kb block auto coroutine = [&h](size_t no) -> std::future { - std::vector> buffer(4096); + std::vector> buffer(4096); memset(buffer.data(), (int) ('0' + no), 4096); afio::async_file_handle::const_buffer_type bt{buffer.data(), buffer.size()}; for(size_t n = 0; n < 128; n++) @@ -71,7 +71,7 @@ static inline void TestAsyncFileHandleCoroutines() //! [coroutines_example] // Check that the file has the right contents - alignas(4096) char buffer1[4096], buffer2[4096]; + alignas(4096) afio::byte buffer1[4096], buffer2[4096]; afio::async_file_handle::extent_type offset = 0; for(size_t n = 0; n < 128; n++) { diff --git a/test/tests/map_handle_create_close/runner.cpp b/test/tests/map_handle_create_close/runner.cpp index f9eabbc7..b0e4abfd 100644 --- a/test/tests/map_handle_create_close/runner.cpp +++ b/test/tests/map_handle_create_close/runner.cpp @@ -72,7 +72,7 @@ template inline void map_handle_create_close_(U &&f) { // Create a temporary backing file temph = file_handle::file({}, "tempfile", file_handle::mode::write, file_handle::creation::if_needed).value(); - temph.write(0, { {"I am some file data", 19} }).value(); + temph.write(0, { {reinterpret_cast("I am some file data"), 19} }).value(); } else { @@ -100,13 +100,13 @@ template inline void map_handle_create_close_(U &&f) //#define KERNELTEST_CHECK(a, ...) BOOST_CHECK(__VA_ARGS__) if (testreturn) { - char *addr = maph.address(); + AFIO_V2_NAMESPACE::byte *addr = maph.address(); section_handle::flag flags = std::get<1>(std::get<1>(permuter[idx])); KERNELTEST_CHECK(testreturn, maph.length() > 0); KERNELTEST_CHECK(testreturn, addr != nullptr); if (!(flags & section_handle::flag::nocommit) && addr != nullptr) { - char buffer[64]; + AFIO_V2_NAMESPACE::byte buffer[64]; // Make sure the backing file is appearing in the map if (use_file_backing && maph.is_readable()) { @@ -130,7 +130,7 @@ template inline void map_handle_create_close_(U &&f) { memcpy(addr, "NIALL was here", 14); // Make sure maph's write() works - maph.write(1, { {"iall", 4} }); + maph.write(1, { {reinterpret_cast("iall"), 4} }); // Make sure data written to the map turns up in the file if (use_file_backing) { diff --git a/test/tests/mapped_span.cpp b/test/tests/mapped_span.cpp index cd776425..469a1453 100644 --- a/test/tests/mapped_span.cpp +++ b/test/tests/mapped_span.cpp @@ -64,6 +64,7 @@ static inline void TestMappedView2() { using namespace AFIO_V2_NAMESPACE; using AFIO_V2_NAMESPACE::file_handle; + using AFIO_V2_NAMESPACE::byte; { std::error_code ec; filesystem::remove("testfile", ec); @@ -71,7 +72,7 @@ static inline void TestMappedView2() mapped_file_handle mfh = mapped_file_handle::mapped_file(1024 * 1024, {}, "testfile", file_handle::mode::write, file_handle::creation::if_needed, file_handle::caching::all, file_handle::flag::unlink_on_close).value(); BOOST_CHECK(mfh.address() == nullptr); mfh.truncate(10000 * sizeof(int)).value(); - char *addr = mfh.address(); + byte *addr = mfh.address(); BOOST_CHECK(addr != nullptr); algorithm::mapped_span v1(mfh); diff --git a/test/tests/section_handle_create_close/runner.cpp b/test/tests/section_handle_create_close/runner.cpp index 2df9bc87..9b5d63f3 100644 --- a/test/tests/section_handle_create_close/runner.cpp +++ b/test/tests/section_handle_create_close/runner.cpp @@ -70,7 +70,7 @@ template inline void section_handle_create_close_(U &&f) if (use_file_backing) { temph = file_handle::file({}, "tempfile", file_handle::mode::write, file_handle::creation::if_needed).value(); - temph.write(0, { {"niall is not here", 17} }).value(); + temph.write(0, { {reinterpret_cast("niall is not here"), 17} }).value(); } else { -- cgit v1.2.3