forked from Alepha/Alepha
Get it building again.
This commit is contained in:
@ -227,11 +227,8 @@ namespace Alepha::Hydrogen ::detail:: Blob_m
|
|||||||
* possible extra space, due to alignment).
|
* possible extra space, due to alignment).
|
||||||
*/
|
*/
|
||||||
Blob
|
Blob
|
||||||
carveHead( const std::size_t unalignedAmount, Alignment alignment= Alignment{ 1 } )
|
carveHead( const std::size_t amount )
|
||||||
{
|
{
|
||||||
assert( std::popcount( alignment.amt ) == 1 );
|
|
||||||
// TODO: Consider arithmetic overflow, here.
|
|
||||||
const std::size_t amount= alignTo( ( reinterpret_cast< std::uintptr_t >( data() ) % alignment.amt ) + unalignedAmount, alignment );
|
|
||||||
if( amount > size() ) throw DataCarveTooLargeError( data(), amount, size() );
|
if( amount > size() ) throw DataCarveTooLargeError( data(), amount, size() );
|
||||||
if( not storage )
|
if( not storage )
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
add_subdirectory( Blob.test )
|
add_subdirectory( Blob.test )
|
||||||
add_subdirectory( ThreadSlab.test )
|
add_subdirectory( ThreadSlab.test )
|
||||||
add_subdirectory( Blob.test )
|
|
||||||
|
|||||||
@ -21,6 +21,11 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
namespace C
|
namespace C
|
||||||
{
|
{
|
||||||
const std::size_t slabSize= 64 * 1024 * 1024;
|
const std::size_t slabSize= 64 * 1024 * 1024;
|
||||||
|
|
||||||
|
const bool debug= false;
|
||||||
|
const bool debugLifecycle= false or C::debug;
|
||||||
|
const bool debugAllocation= false or C::debug;
|
||||||
|
const bool debugDeallocations= false or C::debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
@ -48,28 +53,42 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
ThreadSlab( ThreadSlab &&other ) : ThreadSlab( std::as_const( other ) ) {}
|
ThreadSlab( ThreadSlab &&other ) : ThreadSlab( std::as_const( other ) ) {}
|
||||||
|
|
||||||
~ThreadSlab()
|
~ThreadSlab()
|
||||||
|
{
|
||||||
|
if( C::debugLifecycle )
|
||||||
{
|
{
|
||||||
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
||||||
<< (void *) this << " is retired." << std::endl;
|
<< (void *) this << " is retired." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] T *
|
[[nodiscard]] T *
|
||||||
allocate( const std::size_t amt )
|
allocate( const std::size_t amt )
|
||||||
{
|
{
|
||||||
// TODO: Alignment?
|
// TODO: Alignment needs to be handled.
|
||||||
const std::size_t req= amt + sizeof( Blob::StorageReservation );
|
const std::size_t req= amt + sizeof( Blob::StorageReservation );
|
||||||
|
|
||||||
|
// TODO: Larger allocations may be worth bespoke allocations, if they're rare one-off cases
|
||||||
if( req > C::slabSize ) throw std::bad_alloc{}; //{ "Unable to allocate larger than the slab size." };
|
if( req > C::slabSize ) throw std::bad_alloc{}; //{ "Unable to allocate larger than the slab size." };
|
||||||
if( slab.size() < req ) slab.reset( std::max( req, C::slabSize ) );
|
if( slab.size() < req ) slab.reset( std::max( req, C::slabSize ) );
|
||||||
|
|
||||||
|
if( C::debugAllocation )
|
||||||
|
{
|
||||||
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
||||||
<< (void *) this << " made an allocation." << std::endl;
|
<< (void *) this << " made an allocation." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
auto next= slab.carveHead( req, Alignment{ sizeof( Blob::StorageReservation ) } );
|
auto next= slab.carveHead( req + sizeof( Blob::StorageReservation ) );
|
||||||
const auto rv= reinterpret_cast< T * >( &next.template as< Blob::StorageReservation >() + 1 );
|
const auto rv= reinterpret_cast< T * >( &next.template as< Blob::StorageReservation >() + 1 );
|
||||||
|
|
||||||
|
// FIXME: The placement new here is potentially unaligned -- this may significantly impact
|
||||||
|
// performance.
|
||||||
new ( &next.template as< Blob::StorageReservation >() ) Blob::StorageReservation{ std::move( next.reservation() ) };
|
new ( &next.template as< Blob::StorageReservation >() ) Blob::StorageReservation{ std::move( next.reservation() ) };
|
||||||
|
|
||||||
|
if( C::debugAllocation )
|
||||||
|
{
|
||||||
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
||||||
<< (void *) this << " made an allocation." << std::endl;
|
<< (void *) this << " made an allocation." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -83,15 +102,22 @@ namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m
|
|||||||
|
|
||||||
void
|
void
|
||||||
deallocate( T *const p, const std::size_t /* ignored */ ) noexcept
|
deallocate( T *const p, const std::size_t /* ignored */ ) noexcept
|
||||||
|
{
|
||||||
|
if( C::debugDeallocation )
|
||||||
{
|
{
|
||||||
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
||||||
<< (void *) this << " made a deallocation." << std::endl;
|
<< (void *) this << " made a deallocation." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
auto *const hidden= reinterpret_cast< Blob::StorageReservation * >( p ) - 1;
|
auto *const hidden= reinterpret_cast< Blob::StorageReservation * >( p ) - 1;
|
||||||
destroy( hidden );
|
destroy( hidden );
|
||||||
|
|
||||||
|
if( C::debugDeallocation )
|
||||||
|
{
|
||||||
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
std::cerr << "Reporting " << slab.reservation().use_count() << " living allocations when "
|
||||||
<< (void *) this << " made a deallocation." << std::endl;
|
<< (void *) this << " made a deallocation." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
friend constexpr bool operator == ( const ThreadSlab &, const ThreadSlab & ) noexcept { return true; }
|
friend constexpr bool operator == ( const ThreadSlab &, const ThreadSlab & ) noexcept { return true; }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user