Skip to content

Commit

Permalink
Merge pull request #21 from psiha/feature/containers_pt2_btree
Browse files Browse the repository at this point in the history
Feature/containers pt2 btree
  • Loading branch information
psiha authored Oct 28, 2024
2 parents 28fa964 + fedd814 commit e80278e
Show file tree
Hide file tree
Showing 30 changed files with 3,589 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gh-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ jobs:
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: >
cd ${{ steps.strings.outputs.build-output-dir }}/test &&
ctest --build-config ${{ matrix.build_type }}
ctest --progress --output-on-failure --build-config ${{ matrix.build_type }}
17 changes: 15 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ include( ${CMAKE_CURRENT_BINARY_DIR}/cmake/get_cpm.cmake )

# Add packages

set( boost_ver boost-1.85.0 )
set( boost_ver boost-1.86.0 )
CPMAddPackage( "gh:boostorg/static_assert#${boost_ver}" ) # Boost::core dependency
CPMAddPackage( "gh:boostorg/throw_exception#${boost_ver}" ) # Boost::core dependency
CPMAddPackage( "gh:boostorg/config#${boost_ver}" ) # Boost::core dependency
CPMAddPackage( "gh:boostorg/intrusive#${boost_ver}" ) # Boost::container dependency
CPMAddPackage( "gh:boostorg/io#${boost_ver}" ) # Boost::utility dependency
CPMAddPackage( "gh:boostorg/type_traits#${boost_ver}" ) # Boost::utility dependency
CPMAddPackage( "gh:boostorg/predef#${boost_ver}" ) # Boost::winapi dependency
CPMAddPackage( "gh:boostorg/assert#${boost_ver}" )
CPMAddPackage( "gh:boostorg/container#${boost_ver}" ) # used only for comparative benchmarking
CPMAddPackage( "gh:boostorg/core#${boost_ver}" )
CPMAddPackage( "gh:boostorg/integer#${boost_ver}" )
CPMAddPackage( "gh:boostorg/move#${boost_ver}" )
CPMAddPackage( "gh:boostorg/preprocessor#${boost_ver}" )
CPMAddPackage( "gh:boostorg/stl_interfaces#${boost_ver}" )
CPMAddPackage( "gh:boostorg/winapi#${boost_ver}" )
CPMAddPackage( "gh:boostorg/utility#${boost_ver}" )

Expand All @@ -55,7 +60,9 @@ if ( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
PSI_add_link_options( Release -flto ) # lld does not seem to be enough
add_compile_options( -stdlib=libc++ )
# Needed under WSL for some reason?
PSI_add_link_options( Debug -lc++ -lc++abi -lubsan )
PSI_add_link_options( Debug -lc++ -lc++abi -lm -lubsan )
PSI_add_link_options( DevRelease -lc++ -lc++abi -lm -lubsan )
PSI_add_link_options( Release -lc++ -lc++abi -lm )
else()
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE true )
PSI_add_link_options( Release ${PSI_linker_LTO} )
Expand All @@ -69,9 +76,13 @@ endif()
include( vm.cmake )

target_link_libraries( psi_vm PUBLIC
Boost::container
Boost::core
Boost::assert
Boost::integer
Boost::move
Boost::preprocessor
Boost::stl_interfaces
Boost::winapi
Boost::utility
)
Expand All @@ -83,6 +94,8 @@ target_include_directories( psi_vm PUBLIC
"${std_fix_SOURCE_DIR}/include" # vm::vector uses it (in a header)
)

target_precompile_headers( psi_vm PUBLIC src/pch.hpp )


###################
## Testing
Expand Down
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@

### vm - portable, lightweight, powerful, near-zero-overhead memory mapping and virtual memory management.
### vm - portable, lightweight, powerful, near-zero-overhead memory mapping, virtual memory management, containers and utilities.

(TODO: sync with https://github.com/ned14/llfio)

https://svn.boost.org/trac/boost/ticket/4827
http://boost.2283326.n4.nabble.com/interprocess-shared-memory-lifetime-td2603982.html
http://lists.boost.org/Archives/boost/2010/10/172227.php
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html
##### Sponsored by (at one point or another)

##### Submodule requirements
* config_ex
* err
* std_fix
https://farseer.com
https://microblink.com


##### Some ancient discussions

https://svn.boost.org/trac/boost/ticket/4827
http://boost.2283326.n4.nabble.com/interprocess-shared-memory-lifetime-td2603982.html
http://lists.boost.org/Archives/boost/2010/10/172227.php
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html

##### Dependencies
* Boost
* Psi.Build
* Psi.Err
* Psi.StdFix

##### C++ In-The-Kernel Now!
##### Copyright © 2011 - 2024. Domagoj Šarić. All rights reserved.
20 changes: 10 additions & 10 deletions include/psi/vm/align.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace align_detail
{
[[ gnu::const ]] constexpr auto generic_divide_up( auto const numerator, auto const denominator ) noexcept
{
return static_cast< decltype( numerator ) >( ( numerator + denominator - 1 ) / denominator );
return static_cast<decltype( numerator )>( ( numerator + denominator - 1 ) / denominator );
}
} // namespace detail

Expand All @@ -36,10 +36,10 @@ namespace align_detail
return __builtin_align_down( value, alignment );
else
#endif
if constexpr ( std::is_pointer_v< T > )
return std::bit_cast< T >( align_down( std::bit_cast< std::uintptr_t >( value ), alignment ) );
if constexpr ( std::is_pointer_v<T> )
return std::bit_cast<T>( align_down( std::bit_cast<std::uintptr_t>( value ), alignment ) );
else
return static_cast< T >( value / alignment * alignment );
return static_cast<T>( value / alignment * alignment );
}
[[ using gnu: const, always_inline ]] constexpr auto align_up( auto const value, auto const alignment ) noexcept
{
Expand All @@ -49,21 +49,21 @@ namespace align_detail
return __builtin_align_up( value, alignment );
else
#endif
if constexpr ( std::is_pointer_v< T > )
return std::bit_cast< T >( align_up( std::bit_cast< std::uintptr_t >( value ), alignment ) );
if constexpr ( std::is_pointer_v<T> )
return std::bit_cast<T>( align_up( std::bit_cast<std::uintptr_t>( value ), alignment ) );
else
return static_cast< T >( align_detail::generic_divide_up( value, alignment ) * alignment );
return static_cast<T>( align_detail::generic_divide_up( value, alignment ) * alignment );
}

template < unsigned alignment > [[ using gnu: const, always_inline ]] constexpr auto align_down( auto const value ) noexcept { return align_down( value, alignment ); }
template < unsigned alignment > [[ using gnu: const, always_inline ]] constexpr auto align_up ( auto const value ) noexcept { return align_up ( value, alignment ); }
template <unsigned alignment> [[ using gnu: const, always_inline ]] constexpr auto align_down( auto const value ) noexcept { return align_down( value, alignment ); }
template <unsigned alignment> [[ using gnu: const, always_inline ]] constexpr auto align_up ( auto const value ) noexcept { return align_up ( value, alignment ); }

[[ using gnu: const, always_inline ]]
constexpr auto divide_up( auto const numerator, auto const denominator ) noexcept
{
#ifdef __GNUC__
if ( __builtin_constant_p( denominator ) && /*is power of 2*/std::has_single_bit( unsigned( denominator ) ) )
return static_cast< decltype( numerator ) >( align_up( numerator, denominator ) / denominator );
return static_cast<decltype( numerator )>( align_up( numerator, denominator ) / denominator );
else
#endif // GCC&co.
return align_detail::generic_divide_up( numerator, denominator );
Expand Down
107 changes: 107 additions & 0 deletions include/psi/vm/containers/abi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#pragma once

#include <psi/build/disable_warnings.hpp>

#include <boost/config.hpp>

#include <ranges>
#include <span>
#include <string>
#include <string_view>
#include <type_traits>
//------------------------------------------------------------------------------
namespace psi::vm
{
//------------------------------------------------------------------------------

PSI_WARNING_DISABLE_PUSH()
PSI_WARNING_MSVC_DISABLE( 5030 ) // unrecognized attribute

////////////////////////////////////////////////////////////////////////////////
// Modern(ized) attempt at 'automatized' boost::call_traits primarily to support
// efficient transparent comparators & non-inlined generic lookup functions
// which cause neither unnecessary copies of non-trivial types nor pass-by-ref
// of trivial ones.
// Largely still WiP...
// Essentially this is 'explicit IPA SROA'.
// https://gcc.gnu.org/onlinedocs/gccint/passes-and-files-of-the-compiler/inter-procedural-optimization-passes.html
////////////////////////////////////////////////////////////////////////////////

template <typename T>
bool constexpr can_be_passed_in_reg
{
(
std::is_trivial_v<T> &&
( sizeof( T ) <= 2 * sizeof( void * ) ) // assuming a sane ABI like SysV (ignoring the MS x64 disaster)
)
#if defined( __GNUC__ ) || defined( __clang__ )
|| // detect SIMD types (this could also produce false positives for large compiler-native vectors that do not fit into the register file)
requires{ __builtin_convertvector( T{}, T ); }
#endif
// This is certainly not an exhaustive list/'trait' - certain types that can
// be passed in reg cannot be detected as such by existing compiler
// functionality, e.g. Homogeneous Vector Aggregates
// https://devblogs.microsoft.com/cppblog/introducing-vector-calling-convention
// users are encouraged to provide specializations for such types.
}; // can_be_passed_in_reg

template <typename T>
struct optimal_const_ref { using type = T const &; };

template <typename Char>
struct optimal_const_ref<std::basic_string<Char>> { using type = std::basic_string_view<Char>; };

template <std::ranges::contiguous_range Rng>
struct optimal_const_ref<Rng> { using type = std::span<std::ranges::range_value_t<Rng> const>; };

template <typename T>
struct [[ clang::trivial_abi ]] pass_in_reg
{
static auto constexpr pass_by_val{ can_be_passed_in_reg<T> };

using value_type = T;
using stored_type = std::conditional_t<pass_by_val, T, typename optimal_const_ref<T>::type>;
BOOST_FORCEINLINE
constexpr pass_in_reg( auto const &... args ) noexcept requires requires { stored_type{ args... }; } : value{ args... } {}
constexpr pass_in_reg( pass_in_reg const & ) noexcept = default;
constexpr pass_in_reg( pass_in_reg && ) noexcept = default;

stored_type value;

[[ gnu::pure ]] BOOST_FORCEINLINE
constexpr operator stored_type const &() const noexcept { return value; }
}; // pass_in_reg
template <typename T>
pass_in_reg( T ) -> pass_in_reg<T>;

template <typename T>
struct [[ clang::trivial_abi ]] pass_rv_in_reg
{
static auto constexpr pass_by_val{ can_be_passed_in_reg<T> };

using value_type = T;
using stored_type = std::conditional_t<pass_by_val, T, T &&>;

constexpr pass_rv_in_reg( T && u ) noexcept : value{ std::move( u ) } {} // move for not-trivially-moveable yet trivial_abi types (that can be passed in reg)

stored_type value;

[[ gnu::pure ]] BOOST_FORCEINLINE constexpr operator stored_type const & () const & noexcept { return value ; }
[[ gnu::pure ]] BOOST_FORCEINLINE constexpr operator stored_type &&() && noexcept { return std::move( value ); }
}; // pass_rv_in_reg

template <typename T> bool constexpr reg { can_be_passed_in_reg<T> };
template <typename T> bool constexpr reg<pass_in_reg <T>>{ true };
template <typename T> bool constexpr reg<pass_rv_in_reg<T>>{ true };

template <typename T>
concept Reg = reg<T>;

// 'Explicit IPA SROA' / pass-in-reg helper end
////////////////////////////////////////////////////////////////////////////////

PSI_WARNING_DISABLE_POP()

//------------------------------------------------------------------------------
} // namespace psi::vm
//------------------------------------------------------------------------------
Loading

0 comments on commit e80278e

Please sign in to comment.