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--cmake/headers.cmake4
m---------doc/html8
-rw-r--r--include/llfio/revision.hpp6
-rw-r--r--include/llfio/v2.0/detail/impl/windows/map_handle.ipp83
4 files changed, 59 insertions, 42 deletions
diff --git a/cmake/headers.cmake b/cmake/headers.cmake
index 53a1dfd0..b4a21606 100644
--- a/cmake/headers.cmake
+++ b/cmake/headers.cmake
@@ -3,8 +3,6 @@ set(llfio_HEADERS
"include/llfio/v2.0/deadline.h"
"include/llfio.hpp"
"include/llfio/llfio.hpp"
- "include/llfio/ntkernel-error-category/include/config.hpp"
- "include/llfio/ntkernel-error-category/include/ntkernel_category.hpp"
"include/llfio/revision.hpp"
"include/llfio/v2.0/algorithm/cached_parent_handle_adapter.hpp"
"include/llfio/v2.0/algorithm/shared_fs_mutex/atomic_append.hpp"
@@ -41,8 +39,6 @@ set(llfio_HEADERS
"include/llfio/v2.0/symlink_handle.hpp"
"include/llfio/v2.0/utils.hpp"
"include/llfio/version.hpp"
- "include/llfio/ntkernel-error-category/include/detail/ntkernel-table.ipp"
- "include/llfio/ntkernel-error-category/include/detail/ntkernel_category_impl.ipp"
"include/llfio/v2.0/detail/impl/cached_parent_handle_adapter.ipp"
"include/llfio/v2.0/detail/impl/path_discovery.ipp"
"include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp"
diff --git a/doc/html b/doc/html
-Subproject 5c9ae1aa255f1d41d65eeeb195ecc871c0f1b0b
+Subproject cd89fe053ce730c1ae2e8f0fad34771deafd30a
diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp
index 28c2279f..32c9001f 100644
--- a/include/llfio/revision.hpp
+++ b/include/llfio/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 LLFIO_PREVIOUS_COMMIT_REF 83b7ad9bfda9af36414d8d6acac454288cb90a3a
-#define LLFIO_PREVIOUS_COMMIT_DATE "2018-08-14 19:05:09 +00:00"
-#define LLFIO_PREVIOUS_COMMIT_UNIQUE 83b7ad9b
+#define LLFIO_PREVIOUS_COMMIT_REF d39c3ba6c1510c6692db851288c12ec0d7b60e39
+#define LLFIO_PREVIOUS_COMMIT_DATE "2018-08-16 08:38:26 +00:00"
+#define LLFIO_PREVIOUS_COMMIT_UNIQUE d39c3ba6
diff --git a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
index e1661072..308a10c8 100644
--- a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
+++ b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp
@@ -324,36 +324,57 @@ static inline void win32_map_flags(native_handle_type &nativeh, DWORD &allocatio
prot = PAGE_EXECUTE;
}
}
+
+QUICKCPPLIB_BITFIELD_BEGIN(win32_map_sought)
+{
+ committed = 1U << 0U, freed = 1U << 1U, reserved = 1U << 2U
+}
+QUICKCPPLIB_BITFIELD_END(win32_map_sought)
// Used to apply an operation to all maps within a region
-template <class F> static inline result<void> win32_maps_apply(byte *addr, size_t bytes, F &&f)
+template <class F> static inline result<void> win32_maps_apply(byte *addr, size_t bytes, win32_map_sought sought, F &&f)
{
+ /* Ok, so we have to be super careful here, because calling VirtualQuery()
+ somewhere in the middle of a region causes a linear scan until the beginning
+ or end of the region is found. For a reservation of say 2^42, that takes a
+ LONG time.
+
+ What we do instead is to query the current block, perform F on it, then query
+ it again to get the next point of change, query that, perhaps perform F on it,
+ and so on.
+
+ This causes twice the number of VirtualQuery() calls as ought to be necessary,
+ but such is this API's design.
+ */
+ MEMORY_BASIC_INFORMATION mbi;
while(bytes > 0)
{
- MEMORY_BASIC_INFORMATION mbi;
- byte *thisregion = addr;
- // Need to iterate until AllocationBase changes
- for(;;)
+ if(!VirtualQuery(addr, &mbi, sizeof(mbi)))
{
- if(!VirtualQuery(addr, &mbi, sizeof(mbi)) || mbi.AllocationBase != thisregion)
- {
- break;
- }
- addr += mbi.RegionSize;
- if(mbi.RegionSize < bytes)
- {
- bytes -= mbi.RegionSize;
- }
- else
- {
- bytes = 0;
- }
+ LLFIO_LOG_FATAL(nullptr, "map_handle::win32_maps_apply VirtualQuery() 1 failed");
+ abort();
}
- // Address passed in originally must match an allocation
- if(addr == thisregion)
+ bool doit = false;
+ doit = doit || ((MEM_COMMIT == mbi.State) && (sought & win32_map_sought::committed));
+ doit = doit || ((MEM_FREE == mbi.State) && (sought & win32_map_sought::freed));
+ doit = doit || ((MEM_RESERVE == mbi.State) && (sought & win32_map_sought::reserved));
+ if(doit)
{
- return errc::invalid_argument;
+ OUTCOME_TRYV(f(reinterpret_cast<byte *>(mbi.BaseAddress), mbi.RegionSize));
+ }
+ if(!VirtualQuery(addr, &mbi, sizeof(mbi)))
+ {
+ LLFIO_LOG_FATAL(nullptr, "map_handle::win32_maps_apply VirtualQuery() 2 failed");
+ abort();
+ }
+ addr += mbi.RegionSize;
+ if(mbi.RegionSize < bytes)
+ {
+ bytes -= mbi.RegionSize;
+ }
+ else
+ {
+ bytes = 0;
}
- OUTCOME_TRYV(f(thisregion, addr - thisregion));
}
return success();
}
@@ -406,7 +427,7 @@ result<void> map_handle::close() noexcept
{
OUTCOME_TRYV(barrier({}, true, false));
}
- OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, [](byte *addr, size_t /* unused */) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, win32_map_sought::committed, [](byte *addr, size_t /* unused */) -> result<void> {
NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr);
if(ntstat < 0)
{
@@ -465,7 +486,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::barrier(map_ha
return {reqs.buffers};
}
}
- OUTCOME_TRYV(win32_maps_apply(addr, bytes, [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(addr, bytes, win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
if(FlushViewOfFile(addr, static_cast<SIZE_T>(bytes)) == 0)
{
return win32_error();
@@ -617,7 +638,7 @@ result<map_handle::size_type> 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, [](byte *addr, size_t /* unused */) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(_addr + newsize, _reservation - newsize, win32_map_sought::committed, [](byte *addr, size_t /* unused */) -> result<void> {
NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr);
if(ntstat < 0)
{
@@ -658,7 +679,7 @@ result<map_handle::buffer_type> 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.size(), [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
DWORD _ = 0;
if(VirtualProtect(addr, bytes, PAGE_NOACCESS, &_) == 0)
{
@@ -685,7 +706,7 @@ result<map_handle::buffer_type> 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.size(), [prot](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed | win32_map_sought::freed | win32_map_sought::reserved, [prot](byte *addr, size_t bytes) -> result<void> {
if(VirtualAlloc(addr, bytes, MEM_COMMIT, prot) == nullptr)
{
return win32_error();
@@ -703,7 +724,7 @@ result<map_handle::buffer_type> map_handle::decommit(buffer_type region) noexcep
return errc::invalid_argument;
}
region = utils::round_to_page_size(region);
- OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
if(VirtualFree(addr, bytes, MEM_DECOMMIT) == 0)
{
return win32_error();
@@ -729,7 +750,7 @@ result<void> map_handle::zero_memory(buffer_type region) noexcept
region = utils::round_to_page_size(region);
if(region.size() > 0)
{
- OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
if(DiscardVirtualMemory_(addr, bytes) == 0)
{
return win32_error();
@@ -774,7 +795,7 @@ result<map_handle::buffer_type> 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.size(), [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
if(DiscardVirtualMemory_(addr, bytes) == 0)
{
return win32_error();
@@ -784,7 +805,7 @@ result<map_handle::buffer_type> map_handle::do_not_store(buffer_type region) noe
return region;
}
// Else MEM_RESET will do
- OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), [](byte *addr, size_t bytes) -> result<void> {
+ OUTCOME_TRYV(win32_maps_apply(region.data(), region.size(), win32_map_sought::committed, [](byte *addr, size_t bytes) -> result<void> {
if(VirtualAlloc(addr, bytes, MEM_RESET, 0) == nullptr)
{
return win32_error();