@@ -64,9 +64,9 @@ class SimpleBlockBasedAllocator
6464 struct SCreationParams
6565 {
6666 inline SCreationParams (const size_type _blockSize, const extra_params_t & extraArgs) : addrCreationArgs(extraArgs), blockSize(_blockSize),
67- reservedSize(std::apply([blockSize ]<typename ... Args>(const Args&... args)->size_type
67+ reservedSize(std::apply([_blockSize ]<typename ... Args>(const Args&... args)->size_type
6868 {
69- return addr_alloc_traits::reserved_size (meta_alignment,blockSize ,args...);
69+ return addr_alloc_traits::reserved_size (meta_alignment,_blockSize ,args...);
7070 },addrCreationArgs)
7171 ), totalSize(core::alignUp(sizeof (Block)+reservedSize,meta_alignment)+blockSize) {}
7272
@@ -78,7 +78,7 @@ class SimpleBlockBasedAllocator
7878 //
7979 inline Block (const SCreationParams& params) : addrAlloc (AddressAllocator ())
8080 {
81- std::apply ([¶ms ]<typename ... Args>(const Args&... args)->void
81+ std::apply ([&]<typename ... Args>(const Args&... args)->void
8282 {
8383 addrAlloc = AddressAllocator (this +1 ,/* no address offset*/ 0u ,/* no alignment offset needed*/ 0u ,meta_alignment,params.blockSize ,args...);
8484 },params.addrCreationArgs
@@ -88,11 +88,12 @@ class SimpleBlockBasedAllocator
8888 }
8989
9090 inline uint8_t * data (const SCreationParams& params) {return reinterpret_cast <uint8_t *>(this )+params.totalSize -params.blockSize ;}
91- inline const uint8_t * data () const
91+ inline const uint8_t * data (const SCreationParams& params ) const
9292 {
93- return const_cast <Block*>(this )->data ();
93+ return const_cast <const uint8_t *>( const_cast < Block*>(this )->data (params) );
9494 }
9595
96+ AddressAllocator& getAllocator () {return addrAlloc;}
9697 const AddressAllocator& getAllocator () const {return addrAlloc;}
9798
9899 size_type alloc (size_type bytes, size_type alignment)
@@ -118,10 +119,10 @@ class SimpleBlockBasedAllocator
118119 {
119120 smart_refctd_ptr<refctd_memory_resource> mem_resource = nullptr ;
120121 extra_params_t addrAllocCtorExtraParams;
121- size_type blockSize = 128u << 10 ;
122- size_type initBlockCount = 1 ;
122+ uint16_t blockSizeKBLog2 : 5 = 7 ;
123+ uint16_t initBlockCount : 11 = 1 ;
123124 };
124- inline SimpleBlockBasedAllocator (SCreationParams&& params) : m_blockCreationParams(params.blockSize ,std::move(params.addrAllocCtorExtraParams)),
125+ inline SimpleBlockBasedAllocator (SCreationParams&& params) : m_blockCreationParams(1024u << params.blockSizeKBLog2 ,std::move(params.addrAllocCtorExtraParams)),
125126 m_initBlockCount(std::max<size_type>(params.initBlockCount,1 )), m_mem_resource(params.mem_resource ? std::move(params.mem_resource):core::getDefaultMemoryResource())
126127 {
127128 for (auto i=0u ; i<m_initBlockCount; i++)
@@ -130,6 +131,9 @@ class SimpleBlockBasedAllocator
130131 SimpleBlockBasedAllocator (const SimpleBlockBasedAllocator&) = delete ;
131132 SimpleBlockBasedAllocator (SimpleBlockBasedAllocator&&) = delete ;
132133
134+ //
135+ inline const Block::SCreationParams getBlockCreationParams () const {return m_blockCreationParams;}
136+
133137 // deallocates everything
134138 inline void reset ()
135139 {
@@ -149,34 +153,49 @@ class SimpleBlockBasedAllocator
149153 }
150154
151155 //
152- inline void * allocate (const size_type bytes, const size_type alignment) noexcept
156+ struct SAllocResult
157+ {
158+ explicit inline operator bool () const {return blockData;}
159+ inline operator void *() const
160+ {
161+ if (blockData)
162+ return blockData+addr;
163+ return nullptr ;
164+ }
165+
166+ uint8_t * blockData = nullptr ;
167+ size_type addr : (sizeof (size_type)*8 -1 );
168+ size_type newBlock : 1 = false ;
169+ };
170+ inline SAllocResult allocate (const size_type bytes, const size_type alignment) noexcept
153171 {
154172 constexpr auto invalid_address = AddressAllocator::invalid_address;
155173 // TODO: better allocation strategies like tlsf
156174 for (auto & entry : m_blocks)
157175 {
158- auto * block = entry;
176+ Block * block = const_cast <Block*>( entry) ;
159177 if (const auto addr=block->alloc (bytes,alignment); addr!=invalid_address)
160- return block->data ()+ addr;
178+ return {. blockData = block->data (m_blockCreationParams),. addr =addr} ;
161179 }
162- auto * block = createBlock ();
180+ Block * block = createBlock ();
163181 if (const auto addr=block->alloc (bytes,alignment); addr!=invalid_address)
164182 {
165183 m_blocks.insert (block);
166- return block->data ()+ addr;
184+ return {. blockData = block->data (m_blockCreationParams),. addr =addr,. newBlock = true } ;
167185 }
168186 else
169187 deleteBlock (block);
170- return nullptr ;
188+ return {} ;
171189 }
172190 inline void deallocate (void * p, const size_type bytes) noexcept
173191 {
174192 assert (m_blocks.size ()>=m_initBlockCount);
175193 auto found = m_blocks.lower_bound (reinterpret_cast <Block*>(p));
176194 assert (found!=m_blocks.end ());
177195 auto * block = *found;
178- assert (block->data ()<=p && p<block->data ()+m_blockCreationParams.blockSize );
179- const size_type addr = reinterpret_cast <uint8_t *>(p)-block->data ();
196+ uint8_t * blockData = block->data (m_blockCreationParams);
197+ assert (blockData<=p && p<blockData+m_blockCreationParams.blockSize );
198+ const size_type addr = reinterpret_cast <uint8_t *>(p)-blockData;
180199 block->free (addr,bytes);
181200 if (m_blocks.size ()>m_initBlockCount && addr_alloc_traits::get_allocated_size (block->getAllocator ())==size_type (0u ))
182201 {
0 commit comments