diff --git a/include/boost/pool/simple_segregated_storage.hpp b/include/boost/pool/simple_segregated_storage.hpp index fffd4ee..e0d8c42 100644 --- a/include/boost/pool/simple_segregated_storage.hpp +++ b/include/boost/pool/simple_segregated_storage.hpp @@ -328,6 +328,19 @@ void * simple_segregated_storage::try_malloc_n( void * & start, size_type n, const size_type partition_size) { void * iter = nextof(start); + if (n == 1) + { + void * next = nextof(iter); + if (next != static_cast(iter) + partition_size) + { + start = iter; + return 0; + } + else + { + return iter; + } + } while (--n != 0) { void * next = nextof(iter); diff --git a/test/test_pool_alloc.cpp b/test/test_pool_alloc.cpp index b0b50ea..6c36e97 100644 --- a/test/test_pool_alloc.cpp +++ b/test/test_pool_alloc.cpp @@ -263,6 +263,34 @@ void test_mem_usage() // This will clean up the memory leak from (*B*) } + { + pool_type pool(sizeof(int), 2); + void * ptr_0 = pool.malloc(); + void * ptr_1 = pool.malloc(); + void * ptr_2 = pool.malloc(); + void * ptr_3 = pool.malloc(); + pool.ordered_free(ptr_2); + pool.ordered_free(ptr_3); + BOOST_TEST(pool.release_memory()); + pool.ordered_free(ptr_0); + pool.ordered_free(ptr_1); + BOOST_TEST(pool.release_memory()); + } + + { + pool_type pool(sizeof(int), 2); + void * ptr_0 = pool.malloc(); + void * ptr_1 = pool.malloc(); + void * ptr_2 = pool.malloc(); + void * ptr_3 = pool.malloc(); + pool.ordered_free(ptr_0); + pool.ordered_free(ptr_1); + BOOST_TEST(pool.release_memory()); + pool.ordered_free(ptr_2); + pool.ordered_free(ptr_3); + BOOST_TEST(pool.release_memory()); + } + BOOST_TEST(track_alloc::ok()); } diff --git a/test/test_simple_seg_storage.cpp b/test/test_simple_seg_storage.cpp index 67a33e0..2398cf1 100644 --- a/test/test_simple_seg_storage.cpp +++ b/test/test_simple_seg_storage.cpp @@ -277,6 +277,82 @@ int main() BOOST_TEST(nchunks == 3); } + { + char* const pc = track_allocator::malloc(4 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 4 * partition_sz, partition_sz); + + void* pvret = tstore.malloc_n(1, partition_sz); + BOOST_TEST(pvret == pc); + + // There should still be two contiguous + // and one non-contiguous chunk left + std::size_t nchunks = 0; + while(!tstore.empty()) + { + tstore.malloc(); + ++nchunks; + } + BOOST_TEST(nchunks == 3); + } + + { + char* const pc = track_allocator::malloc(4 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 4 * partition_sz, partition_sz); + + void* pvret = tstore.malloc_n(2, partition_sz); + BOOST_TEST(pvret == pc); + + // There should still be two contiguous + // and one non-contiguous chunk left + std::size_t nchunks = 0; + while(!tstore.empty()) + { + tstore.malloc(); + ++nchunks; + } + BOOST_TEST(nchunks == 2); + } + + { + char* const pc = track_allocator::malloc(4 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 4 * partition_sz, partition_sz); + + void* pvret = tstore.malloc_n(1, 2 * partition_sz); + BOOST_TEST(pvret == 0); + + // There should still be two contiguous + // and one non-contiguous chunk left + std::size_t nchunks = 0; + while(!tstore.empty()) + { + tstore.malloc(); + ++nchunks; + } + BOOST_TEST(nchunks == 4); + } + + { + char* const pc = track_allocator::malloc(4 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 4 * partition_sz, partition_sz); + + void* pvret = tstore.malloc_n(2, 2 * partition_sz); + BOOST_TEST(pvret == 0); + + // There should still be two contiguous + // and one non-contiguous chunk left + std::size_t nchunks = 0; + while(!tstore.empty()) + { + tstore.malloc(); + ++nchunks; + } + BOOST_TEST(nchunks == 4); + } + { char* const pc = track_allocator::malloc(12 * partition_sz); test_simp_seg_store tstore;