@@ -154,15 +154,17 @@ class unsynchronized_pool_resource final
154154
155155private:
156156 typedef typename Upstream::pointer void_ptr;
157- typedef typename thrust::detail::pointer_traits<void_ptr>::template rebind<char >::other char_ptr;
157+ typedef thrust::detail::pointer_traits<void_ptr> void_ptr_traits;
158+ typedef typename void_ptr_traits::template rebind<char >::other char_ptr;
158159
159160 struct block_descriptor ;
160161 struct chunk_descriptor ;
161162 struct oversized_block_descriptor ;
162163
163- typedef typename thrust::detail::pointer_traits<void_ptr>::template rebind<block_descriptor>::other block_descriptor_ptr;
164- typedef typename thrust::detail::pointer_traits<void_ptr>::template rebind<chunk_descriptor>::other chunk_descriptor_ptr;
165- typedef typename thrust::detail::pointer_traits<void_ptr>::template rebind<oversized_block_descriptor>::other oversized_block_descriptor_ptr;
164+ typedef typename void_ptr_traits::template rebind<block_descriptor>::other block_descriptor_ptr;
165+ typedef typename void_ptr_traits::template rebind<chunk_descriptor>::other chunk_descriptor_ptr;
166+ typedef typename void_ptr_traits::template rebind<oversized_block_descriptor>::other oversized_block_descriptor_ptr;
167+ typedef thrust::detail::pointer_traits<oversized_block_descriptor_ptr> oversized_block_ptr_traits;
166168
167169 struct block_descriptor
168170 {
@@ -194,6 +196,7 @@ class unsynchronized_pool_resource final
194196 oversized_block_descriptor_ptr prev;
195197 oversized_block_descriptor_ptr next;
196198 oversized_block_descriptor_ptr next_cached;
199+ std::size_t current_size;
197200 };
198201
199202 struct pool
@@ -244,17 +247,20 @@ class unsynchronized_pool_resource final
244247 }
245248
246249 // deallocate cached oversized/overaligned memory
247- while (detail::pointer_traits<oversized_block_descriptor_ptr> ::get (m_oversized))
250+ while (oversized_block_ptr_traits ::get (m_oversized))
248251 {
249252 oversized_block_descriptor_ptr alloc = m_oversized;
250253 m_oversized = thrust::raw_reference_cast (*m_oversized).next ;
251254
255+ oversized_block_descriptor desc =
256+ thrust::raw_reference_cast (*alloc);
257+
252258 void_ptr p = static_cast <void_ptr>(
253- static_cast <char_ptr>(
254- static_cast <void_ptr>(alloc)
255- ) - thrust::raw_reference_cast (*alloc). size
256- );
257- m_upstream-> do_deallocate (p, thrust::raw_reference_cast (*alloc). size + sizeof (oversized_block_descriptor), thrust::raw_reference_cast (*alloc) .alignment );
259+ static_cast <char_ptr>(static_cast <void_ptr>(alloc)) -
260+ desc. current_size );
261+ m_upstream-> do_deallocate (
262+ p, desc. size + sizeof (oversized_block_descriptor),
263+ desc .alignment );
258264 }
259265
260266 m_cached_oversized = oversized_block_descriptor_ptr ();
@@ -272,7 +278,7 @@ class unsynchronized_pool_resource final
272278 {
273279 oversized_block_descriptor_ptr ptr = m_cached_oversized;
274280 oversized_block_descriptor_ptr * previous = &m_cached_oversized;
275- while (detail::pointer_traits<oversized_block_descriptor_ptr> ::get (ptr))
281+ while (oversized_block_ptr_traits ::get (ptr))
276282 {
277283 oversized_block_descriptor desc = *ptr;
278284 bool is_good = desc.size >= bytes && desc.alignment >= alignment;
@@ -305,23 +311,39 @@ class unsynchronized_pool_resource final
305311 {
306312 if (previous != &m_cached_oversized)
307313 {
308- oversized_block_descriptor previous_desc = **previous;
309- previous_desc.next_cached = desc.next_cached ;
310- **previous = previous_desc;
314+ *previous = desc.next_cached ;
311315 }
312316 else
313317 {
314318 m_cached_oversized = desc.next_cached ;
315319 }
316320
317321 desc.next_cached = oversized_block_descriptor_ptr ();
322+
323+ auto ret =
324+ static_cast <char_ptr>(static_cast <void_ptr>(ptr)) -
325+ desc.size ;
326+
327+ if (bytes != desc.size ) {
328+ desc.current_size = bytes;
329+
330+ ptr = static_cast <oversized_block_descriptor_ptr>(
331+ static_cast <void_ptr>(ret + bytes));
332+
333+ if (oversized_block_ptr_traits::get (desc.prev )) {
334+ thrust::raw_reference_cast (*desc.prev ).next = ptr;
335+ } else {
336+ m_oversized = ptr;
337+ }
338+
339+ if (oversized_block_ptr_traits::get (desc.next )) {
340+ thrust::raw_reference_cast (*desc.next ).prev = ptr;
341+ }
342+ }
343+
318344 *ptr = desc;
319345
320- return static_cast <void_ptr>(
321- static_cast <char_ptr>(
322- static_cast <void_ptr>(ptr)
323- ) - desc.size
324- );
346+ return static_cast <void_ptr>(ret);
325347 }
326348
327349 previous = &thrust::raw_reference_cast (*ptr).next_cached ;
@@ -343,10 +365,11 @@ class unsynchronized_pool_resource final
343365 desc.prev = oversized_block_descriptor_ptr ();
344366 desc.next = m_oversized;
345367 desc.next_cached = oversized_block_descriptor_ptr ();
368+ desc.current_size = bytes;
346369 *block = desc;
347370 m_oversized = block;
348371
349- if (detail::pointer_traits<oversized_block_descriptor_ptr> ::get (desc.next ))
372+ if (oversized_block_ptr_traits ::get (desc.next ))
350373 {
351374 oversized_block_descriptor next = *desc.next ;
352375 next.prev = block;
@@ -439,7 +462,7 @@ class unsynchronized_pool_resource final
439462 assert (detail::is_power_of_2 (alignment));
440463
441464 // verify that the pointer is at least as aligned as claimed
442- assert (reinterpret_cast <detail::intmax_t >(detail::pointer_traits<void_ptr> ::get (p)) % alignment == 0 );
465+ assert (reinterpret_cast <detail::intmax_t >(void_ptr_traits ::get (p)) % alignment == 0 );
443466
444467 // the deallocated block is oversized and/or overaligned
445468 if (n > m_options.largest_block_size || alignment > m_options.alignment )
@@ -451,35 +474,44 @@ class unsynchronized_pool_resource final
451474 );
452475
453476 oversized_block_descriptor desc = *block;
477+ assert (desc.current_size == n);
478+ assert (desc.alignment == alignment);
454479
455480 if (m_options.cache_oversized )
456481 {
457482 desc.next_cached = m_cached_oversized;
458- *block = desc;
483+
484+ if (desc.size != n) {
485+ desc.current_size = desc.size ;
486+ block = static_cast <oversized_block_descriptor_ptr>(
487+ static_cast <void_ptr>(static_cast <char_ptr>(p) +
488+ desc.size ));
489+ if (oversized_block_ptr_traits::get (desc.prev )) {
490+ thrust::raw_reference_cast (*desc.prev ).next = block;
491+ } else {
492+ m_oversized = block;
493+ }
494+
495+ if (oversized_block_ptr_traits::get (desc.next )) {
496+ thrust::raw_reference_cast (*desc.next ).prev = block;
497+ }
498+ }
499+
459500 m_cached_oversized = block;
501+ *block = desc;
460502
461503 return ;
462504 }
463505
464- if (!detail::pointer_traits<oversized_block_descriptor_ptr>::get (desc.prev ))
465- {
466- assert (m_oversized == block);
506+ if (oversized_block_ptr_traits::get (
507+ desc.prev )) {
508+ thrust::raw_reference_cast (*desc.prev ).next = desc.next ;
509+ } else {
467510 m_oversized = desc.next ;
468511 }
469- else
470- {
471- oversized_block_descriptor prev = *desc.prev ;
472- assert (prev.next == block);
473- prev.next = desc.next ;
474- *desc.prev = prev;
475- }
476512
477- if (detail::pointer_traits<oversized_block_descriptor_ptr>::get (desc.next ))
478- {
479- oversized_block_descriptor next = *desc.next ;
480- assert (next.prev == block);
481- next.prev = desc.prev ;
482- *desc.next = next;
513+ if (oversized_block_ptr_traits::get (desc.next )) {
514+ thrust::raw_reference_cast (*desc.next ).prev = desc.prev ;
483515 }
484516
485517 m_upstream->do_deallocate (p, desc.size + sizeof (oversized_block_descriptor), desc.alignment );
0 commit comments