Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/posix anonymous mappings take2 #17

Merged
merged 9 commits into from
Sep 17, 2024
4 changes: 2 additions & 2 deletions include/psi/vm/allocation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ inline std::uint16_t constexpr page_size{ 4 * 1024 };
static_assert( page_size == PAGE_SIZE );
#endif

inline std::uint16_t constexpr commit_granularity{ 4 * 1024 };
inline std::uint16_t constexpr reserve_granularity{ 4 * 1024 };
inline std::uint16_t constexpr commit_granularity{ page_size };
inline std::uint16_t constexpr reserve_granularity{ page_size };

#endif // platform /////////////////////////////////////////////////////////////

Expand Down
27 changes: 7 additions & 20 deletions include/psi/vm/mappable_objects/file/file.posix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,14 @@ std::uint64_t get_size( file_handle::const_reference


#if __has_include( <unistd.h> )
template <typename Handle>
mapping BOOST_CC_REG create_mapping
mapping create_mapping
(
Handle && file,
flags::access_privileges::object const object_access,
flags::access_privileges::child_process const child_access,
flags::mapping ::share_mode const share_mode,
std::size_t const size
) noexcept
{
// Apple guidelines http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/FileSystem/Articles/MappingFiles.html
(void)child_access; //...mrmlj...figure out what to do with this...
auto view_flags{ flags::viewing::create( object_access, share_mode ) };
if ( !file )
{
// emulate the Windows interface: null file signifies that the user
// wants a temporary/non-persisted 'anonymous'/pagefile-backed mapping
view_flags.flags |= MAP_ANONYMOUS;
}
return { std::forward<Handle>( file ), view_flags, size };
}
handle && file,
flags::access_privileges::object object_access,
flags::access_privileges::child_process child_access,
flags::mapping ::share_mode share_mode,
std::size_t size
) noexcept;
#endif // POSIX impl level

//------------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions include/psi/vm/mappable_objects/file/file.win32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ template <typename> struct is_resizable;
template < > struct is_resizable<file_handle> : std::true_type {};

BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS, BOOST_RESTRICTED_FUNCTION_L1 )
file_handle BOOST_CC_REG create_file( char const * file_name, flags::opening ) noexcept;
file_handle BOOST_CC_REG create_file( wchar_t const * file_name, flags::opening ) noexcept;
bool delete_file( char const * file_name ) noexcept;
bool delete_file( wchar_t const * file_name ) noexcept;
file_handle create_file( char const * file_name, flags::opening ) noexcept;
file_handle create_file( wchar_t const * file_name, flags::opening ) noexcept;
bool delete_file( char const * file_name ) noexcept;
bool delete_file( wchar_t const * file_name ) noexcept;


err::fallible_result<void, error> set_size( file_handle::reference, std::uint64_t desired_size ) noexcept;
std::uint64_t get_size( file_handle::reference ) noexcept;

// https://msdn.microsoft.com/en-us/library/ms810613.aspx Managing Memory-Mapped Files

mapping BOOST_CC_REG create_mapping
mapping create_mapping
(
file_handle &&,
flags::access_privileges::object,
Expand Down
4 changes: 2 additions & 2 deletions include/psi/vm/mapped_view/mapped_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class basic_mapped_view : public std::conditional_t<read_only, read_only_mapped_
}

public: // Factory methods.
static err::fallible_result<basic_mapped_view, error_t> BOOST_CC_REG
static err::fallible_result<basic_mapped_view, error_t>
map
(
mapping & source_mapping,
Expand All @@ -101,7 +101,7 @@ class basic_mapped_view : public std::conditional_t<read_only, read_only_mapped_
return map( source_mapping, source_mapping.view_mapping_flags, offset, desired_size );
}

static err::fallible_result<basic_mapped_view, error_t> BOOST_CC_REG
static err::fallible_result<basic_mapped_view, error_t>
map
(
mapping & source_mapping,
Expand Down
2 changes: 1 addition & 1 deletion include/psi/vm/mapped_view/ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void flush_blocking( mapped_span range ) noexcept;
#endif
void flush_async ( mapped_span range ) noexcept;

// these below out to go/get special versions in allocation.hpp
// these below ought to go/get special versions in allocation.hpp
void discard( mapped_span range ) noexcept;

// TODO prefetch/WILL_NEED
Expand Down
1 change: 0 additions & 1 deletion include/psi/vm/mapping/mapping.posix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ struct [[ clang::trivial_abi ]] mapping

static bool constexpr create_mapping_can_set_source_size = false;
static bool constexpr supports_zero_sized_mappings = true ; // simply because there is actually no intermediate mapping object
static bool constexpr supports_zero_sized_views = false;
static bool constexpr views_downsizeable = true ;

constexpr mapping( ) noexcept = default;
Expand Down
1 change: 0 additions & 1 deletion include/psi/vm/mapping/mapping.win32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ struct [[ clang::trivial_abi ]] mapping

static bool constexpr create_mapping_can_set_source_size = true ;
static bool constexpr supports_zero_sized_mappings = false; // Windows does not support zero sized mappings
static bool constexpr supports_zero_sized_views = false;
static bool constexpr views_downsizeable = false;

constexpr mapping( ) noexcept = default;
Expand Down
17 changes: 9 additions & 8 deletions include/psi/vm/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class contiguous_container_storage_base
void flush_async ( std::size_t const beginning, std::size_t const size ) const noexcept { vm::flush_async ( mapped_span({ view_.subspan( beginning, size ) }) ); }
void flush_blocking( std::size_t const beginning, std::size_t const size ) const noexcept { vm::flush_blocking( mapped_span({ view_.subspan( beginning, size ) }), mapping_.underlying_file() ); }

bool file_backed() const noexcept { return mapping_.get() == handle::invalid_value; }
bool file_backed() const noexcept { return mapping_.is_file_based(); }

explicit operator bool() const noexcept { return static_cast<bool>( mapping_ ); }

Expand Down Expand Up @@ -163,9 +163,10 @@ class contiguous_container_storage_base
if ( !mapping_ )
return error{};

view_ = mapped_view::map( mapping_, 0, mapping_size );
if ( !view_.data() && ( mapping::supports_zero_sized_views || mapping_size != 0 ) )
return error{};
auto view{ mapped_view::map( mapping_, 0, mapping_size ).as_result_or_error() };
if ( !view )
return view.error();
view_ = *std::move( view );

return std::size_t{ mapping_size };
}
Expand Down Expand Up @@ -1071,7 +1072,7 @@ class vector
///////////////////////////////////////////////////////////////////////////

auto map_file ( auto const file, flags::named_object_construction_policy const policy ) noexcept { BOOST_ASSERT( !has_attached_storage() ); return storage_.map_file ( file, policy ); }
auto map_memory( size_type const size ) noexcept { BOOST_ASSERT( !has_attached_storage() ); return storage_.map_memory( size ); }
auto map_memory( size_type const size ) noexcept { BOOST_ASSERT( !has_attached_storage() ); return storage_.map_memory( to_byte_sz( size ) ); }

bool has_attached_storage() const noexcept { return static_cast<bool>( storage_ ); }

Expand Down Expand Up @@ -1159,9 +1160,9 @@ class vector
private:
PSI_WARNING_DISABLE_PUSH()
PSI_WARNING_GCC_OR_CLANG_DISABLE( -Wsign-conversion )
static T * to_t_ptr ( mapped_view::value_type * const ptr ) noexcept { return reinterpret_cast< T * >( ptr ); }
static sz_t to_t_sz ( auto const byte_sz ) noexcept { BOOST_ASSUME( byte_sz % sizeof( T ) == 0 ); return static_cast< sz_t >( byte_sz / sizeof( T ) ); }
static sz_t to_byte_sz( auto const sz ) noexcept { return static_cast< sz_t >( sz * sizeof( T ) ); }
static T * to_t_ptr ( mapped_view::value_type * const ptr ) noexcept { return reinterpret_cast<T *>( ptr ); }
static sz_t to_t_sz ( auto const byte_sz ) noexcept { BOOST_ASSUME( byte_sz % sizeof( T ) == 0 ); return static_cast<sz_t>( byte_sz / sizeof( T ) ); }
static sz_t to_byte_sz( auto const sz ) noexcept { return static_cast<sz_t>( sz * sizeof( T ) ); }
PSI_WARNING_DISABLE_POP()

void shrink_storage_to( size_type const target_size ) noexcept
Expand Down
9 changes: 2 additions & 7 deletions src/allocation/allocation.posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@
#include <sys/types.h>
#include <unistd.h>
//------------------------------------------------------------------------------
namespace psi
{
//------------------------------------------------------------------------------
namespace vm
namespace psi::vm
{
//------------------------------------------------------------------------------

Expand Down Expand Up @@ -133,7 +130,5 @@ bool allocate_fixed( void * const address, std::size_t const size, allocation_ty
}

//------------------------------------------------------------------------------
} // namespace vm
//------------------------------------------------------------------------------
} // namespace psi
} // namespace psi::vm
//------------------------------------------------------------------------------
40 changes: 39 additions & 1 deletion src/mappable_objects/file/file.posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
//------------------------------------------------------------------------------
#include <psi/vm/mappable_objects/file/file.hpp>

#if __has_include( <unistd.h> )
#include <psi/vm/align.hpp>
#include <psi/vm/allocation.hpp> // for reserve_granularity
#endif
#include <psi/vm/detail/posix.hpp>
#include <psi/vm/flags/opening.posix.hpp>
#include <psi/vm/mapping/mapping.posix.hpp>
Expand Down Expand Up @@ -79,12 +83,46 @@ std::uint64_t get_size( file_handle::const_reference const file_handle ) noexcep
#endif
struct stat file_info{ .st_size = 0 }; // ensure zero is returned for invalid handles (in unchecked/release builds)
BOOST_VERIFY( ( ::fstat( file_handle.value, &file_info ) == 0 ) || ( file_handle == handle_traits::invalid_value ) );
return static_cast< std::uint64_t >( file_info.st_size );
return static_cast<std::uint64_t>( file_info.st_size );
#ifdef __clang__
# pragma clang diagnostic pop
#endif
}

#if __has_include( <unistd.h> )
mapping create_mapping
(
handle && file,
flags::access_privileges::object const object_access,
flags::access_privileges::child_process const child_access,
flags::mapping ::share_mode const share_mode,
std::size_t size
) noexcept
{
// Apple guidelines http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/FileSystem/Articles/MappingFiles.html
(void)child_access; //...mrmlj...figure out what to do with this...
auto view_flags{ flags::viewing::create( object_access, share_mode ) };
if ( !file )
{
// emulate the Windows interface: null file signifies that the user
// wants a temporary/non-persisted 'anonymous'/pagefile-backed mapping
// TODO a separate function for this purpose
# if defined( MAP_SHARED_VALIDATE )
// mmap fails with EINVAL (under WSL kernel 5.15 w/ ArchLinux) when
// MAP_SHARED_VALIDATE is combined with MAP_ANONYMOUS
if ( ( std::to_underlying( flags::mapping::share_mode::shared ) == MAP_SHARED_VALIDATE ) && ( view_flags.flags & MAP_SHARED_VALIDATE ) )
{
view_flags.flags &= ~MAP_SHARED_VALIDATE;
view_flags.flags |= MAP_SHARED;
}
# endif
view_flags.flags |= MAP_ANONYMOUS;
size = align_up( size, reserve_granularity );
}
return { std::move( file ), view_flags, size };
}
#endif // POSIX impl level

//------------------------------------------------------------------------------
} // posix
//------------------------------------------------------------------------------
Expand Down
14 changes: 7 additions & 7 deletions src/mappable_objects/file/file.win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace detail
static BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS, BOOST_RESTRICTED_FUNCTION_L1 ) BOOST_FORCEINLINE HANDLE call_create( wchar_t const * __restrict const file_name, auto const ... args ) { return CreateFileW( file_name, args... ); }

BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS, BOOST_RESTRICTED_FUNCTION_L1 ) BOOST_FORCEINLINE
static HANDLE BOOST_CC_REG do_create( auto const * __restrict const file_name, flags::opening const & __restrict flags ) noexcept
static HANDLE do_create( auto const * __restrict const file_name, flags::opening const & __restrict flags ) noexcept
{
::SECURITY_ATTRIBUTES sa;
auto const p_security_attributes( flags::detail::make_sa_ptr( sa, flags.ap.system_access.p_sd, reinterpret_cast<bool const &>/*static_cast<bool>*/( flags.ap.child_access ) ) );
Expand All @@ -58,8 +58,8 @@ namespace detail
} // namespace detail

BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS, BOOST_RESTRICTED_FUNCTION_L1 )
file_handle BOOST_CC_REG create_file( char const * const file_name, flags::opening const flags ) noexcept { return file_handle{ detail::create_file::do_create( file_name, flags ) }; }
file_handle BOOST_CC_REG create_file( wchar_t const * const file_name, flags::opening const flags ) noexcept { return file_handle{ detail::create_file::do_create( file_name, flags ) }; }
file_handle create_file( char const * const file_name, flags::opening const flags ) noexcept { return file_handle{ detail::create_file::do_create( file_name, flags ) }; }
file_handle create_file( wchar_t const * const file_name, flags::opening const flags ) noexcept { return file_handle{ detail::create_file::do_create( file_name, flags ) }; }


bool delete_file( char const * const file_name ) noexcept { return ::DeleteFileA( file_name ) != false; }
Expand Down Expand Up @@ -142,7 +142,7 @@ namespace detail
}

BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS, BOOST_RESTRICTED_FUNCTION_L1 ) BOOST_FORCEINLINE
mapping BOOST_CC_REG do_map( file_handle::reference file, flags::mapping const flags, std::uint64_t const maximum_size, auto const * __restrict const name ) noexcept
mapping do_map( file_handle::reference file, flags::mapping const flags, std::uint64_t const maximum_size, auto const * __restrict const name ) noexcept
{
if ( file == file_handle::invalid_value )
file.value = INVALID_HANDLE_VALUE; // CreateFileMapping wants this instead of null
Expand Down Expand Up @@ -186,13 +186,13 @@ namespace detail
} // namepsace create_mapping_impl
} // namespace detail

mapping BOOST_CC_REG create_mapping( file_handle::reference const file, flags::mapping const flags, std::uint64_t const maximum_size, char const * const name ) noexcept
mapping create_mapping( file_handle::reference const file, flags::mapping const flags, std::uint64_t const maximum_size, char const * const name ) noexcept
{
return detail::create_mapping_impl::do_map( file, flags, maximum_size, name );
}

#if 0
mapping BOOST_CC_REG create_mapping( handle::reference const file, flags::mapping const flags ) noexcept
mapping create_mapping( handle::reference const file, flags::mapping const flags ) noexcept
{
auto const mapping_handle
(
Expand All @@ -202,7 +202,7 @@ mapping BOOST_CC_REG create_mapping( handle::reference const file, flags::mappin
}
#endif

mapping BOOST_CC_REG create_mapping
mapping create_mapping
(
file_handle && file,
flags::access_privileges::object const object_access,
Expand Down
4 changes: 2 additions & 2 deletions src/mapped_view/mapped_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace psi::vm
//------------------------------------------------------------------------------
// implemented in impl cpps
BOOST_ATTRIBUTES( BOOST_EXCEPTIONLESS )
mapped_span BOOST_CC_REG
mapped_span
map
(
mapping::handle source_mapping,
Expand All @@ -39,7 +39,7 @@ void unmap_partial( mapped_span range ) noexcept;

template <bool read_only>
BOOST_ATTRIBUTES( BOOST_MINSIZE, BOOST_EXCEPTIONLESS )
err::fallible_result<basic_mapped_view<read_only>, error> BOOST_CC_REG
err::fallible_result<basic_mapped_view<read_only>, error>
basic_mapped_view<read_only>::map
(
mapping & source_mapping,
Expand Down
12 changes: 5 additions & 7 deletions src/mapped_view/mapped_view.posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ inline namespace posix

namespace
{
#if !defined( MAP_UNINITIALIZED )
auto constexpr MAP_UNINITIALIZED{ 0 };
#endif // MAP_UNINITIALIZED
#if !defined( MAP_ALIGNED_SUPER )
auto constexpr MAP_ALIGNED_SUPER{ 0 }; // FreeBSD specific hint for large pages https://man.freebsd.org/cgi/man.cgi?sektion=2&query=mmap
#endif // MAP_ALIGNED_SUPER
Expand All @@ -41,7 +38,8 @@ BOOST_ATTRIBUTES( BOOST_MINSIZE, BOOST_EXCEPTIONLESS )
void * mmap( void * const target_address, std::size_t const size, int const protection, int const flags, int const file_handle, std::uint64_t const offset ) noexcept
{
BOOST_ASSUME( is_aligned( target_address, reserve_granularity ) );
BOOST_ASSUME( is_aligned( size , reserve_granularity ) || file_handle != -1 );
//BOOST_ASSUME( is_aligned( size , reserve_granularity ) || file_handle != -1 ); // Linux allows seems to allow nonaligned size even for anonymous mappings
BOOST_ASSUME( is_aligned( offset , page_size ) ); // BSD does not impose this requirement but Linux and POSIX in general do

auto const actual_address{ ::mmap( target_address, size, protection,
# if defined( __linux__ ) && !defined( __ANDROID__ ) && 0 // investigate whether always wired
Expand All @@ -50,9 +48,9 @@ void * mmap( void * const target_address, std::size_t const size, int const prot
# if defined( MAP_NOSYNC ) && 0 // TODO reconsider
MAP_NOSYNC |
# endif
MAP_UNINITIALIZED | MAP_ALIGNED_SUPER | flags,
MAP_ALIGNED_SUPER | flags, // reconsider unconditional ALIGNED_SUPER: can cause mmap to fail https://man.freebsd.org/cgi/man.cgi?sektion=2&query=mmap
file_handle,
static_cast< off_t >( offset )
static_cast<off_t>( offset )
) };
auto const succeeded{ actual_address != MAP_FAILED };
if ( succeeded ) [[ likely ]]
Expand All @@ -70,7 +68,7 @@ void * mmap( void * const target_address, std::size_t const size, int const prot
//------------------------------------------------------------------------------

BOOST_ATTRIBUTES( BOOST_MINSIZE, BOOST_EXCEPTIONLESS )
mapped_span BOOST_CC_REG
mapped_span
map
(
handle::reference const source_mapping,
Expand Down
2 changes: 1 addition & 1 deletion src/mapped_view/mapped_view.win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace psi::vm
//------------------------------------------------------------------------------

BOOST_ATTRIBUTES( BOOST_MINSIZE, BOOST_EXCEPTIONLESS )
mapped_span BOOST_CC_REG
mapped_span
map
(
mapping::handle const source_mapping,
Expand Down
Loading