diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4e00ad..de0bf2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,9 +52,9 @@ jobs: - { compiler: gcc-4.9, cxxstd: '03,11', os: ubuntu-latest, container: 'ubuntu:16.04' } - { compiler: gcc-5, cxxstd: '03,11,14,1z', os: ubuntu-latest, container: 'ubuntu:18.04' } - { compiler: gcc-6, cxxstd: '03,11,14,17', os: ubuntu-latest, container: 'ubuntu:18.04' } - - { compiler: gcc-7, cxxstd: '03,11,14,17', os: ubuntu-20.04 } - - { compiler: gcc-8, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 } - - { compiler: gcc-9, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 } + - { compiler: gcc-7, cxxstd: '03,11,14,17', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: gcc-8, cxxstd: '03,11,14,17,2a', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: gcc-9, cxxstd: '03,11,14,17,2a', os: ubuntu-latest, container: 'ubuntu:20.04' } - { compiler: gcc-10, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 } - { compiler: gcc-11, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 } - { compiler: gcc-12, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 } @@ -73,14 +73,14 @@ jobs: - { compiler: clang-3.9, cxxstd: '03,11,14', os: ubuntu-latest, container: 'ubuntu:18.04' } - { compiler: clang-4.0, cxxstd: '03,11,14', os: ubuntu-latest, container: 'ubuntu:18.04' } - { compiler: clang-5.0, cxxstd: '03,11,14,1z', os: ubuntu-latest, container: 'ubuntu:18.04' } - - { compiler: clang-6.0, cxxstd: '03,11,14,17', os: ubuntu-20.04 } - - { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-20.04 } + - { compiler: clang-6.0, cxxstd: '03,11,14,17', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-latest, container: 'ubuntu:20.04' } # Note: clang-8 does not fully support C++20, so it is not compatible with some libstdc++ versions in this mode - - { compiler: clang-8, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 , install: 'clang-8 g++-7', gcc_toolchain: 7 } - - { compiler: clang-9, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 } - - { compiler: clang-10, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 } - - { compiler: clang-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 } - - { compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 } + - { compiler: clang-8, cxxstd: '03,11,14,17,2a', os: ubuntu-latest, container: 'ubuntu:20.04' , install: 'clang-8 g++-7', gcc_toolchain: 7 } + - { compiler: clang-9, cxxstd: '03,11,14,17,2a', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: clang-10, cxxstd: '03,11,14,17,20', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: clang-11, cxxstd: '03,11,14,17,20', os: ubuntu-latest, container: 'ubuntu:20.04' } + - { compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-latest, container: 'ubuntu:20.04' } # Clang isn't compatible with libstdc++-13, so use the slightly older one - { compiler: clang-13, cxxstd: '03,11,14,17,20', os: ubuntu-22.04, install: 'clang-13 g++-12', gcc_toolchain: 12 } - { compiler: clang-14, cxxstd: '03,11,14,17,20', os: ubuntu-22.04, install: 'clang-14 g++-12', gcc_toolchain: 12 } @@ -92,9 +92,9 @@ jobs: # libc++ - { compiler: clang-6.0, cxxstd: '03,11,14', os: ubuntu-latest, container: 'ubuntu:18.04', stdlib: libc++, install: 'clang-6.0 libc++-dev libc++abi-dev' } - - { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-20.04, stdlib: libc++, install: 'clang-7 libc++-7-dev libc++abi-7-dev' } + - { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-latest, container: 'ubuntu:20.04', stdlib: libc++, install: 'clang-7 libc++-7-dev libc++abi-7-dev' } - { name: Clang w/ sanitizers, sanitize: yes, - compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev' } + compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-latest, container: 'ubuntu:20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev' } - { name: MacOS w/ clang and sanitizers, compiler: clang, cxxstd: '03,11,14,17,20,2b', os: macos-13, sanitize: yes } @@ -105,7 +105,7 @@ jobs: # requires two github secrets in repo to activate; see ci/github/coverity.sh # does not run on pull requests, only on pushes into develop and master - { name: Coverity, coverity: yes, - compiler: clang-12, cxxstd: '03,20', os: ubuntu-20.04, ccache: no } + compiler: clang-12, cxxstd: '03,20', os: ubuntu-latest, container: 'ubuntu:20.04', ccache: no } # multiarch (bigendian testing) - does not support coverage yet - { name: Big-endian, multiarch: yes, @@ -138,7 +138,7 @@ jobs: osver=$(lsb_release -sr | cut -f1 -d.) pkgs="g++ git xz-utils" # Ubuntu 22+ has only Python 3 in the repos - if [ -n "$osver" ] && [ "$osver" -ge "22" ]; then + if [ -n "$osver" ] && [ "$osver" -ge "20" ]; then pkgs+=" python-is-python3 libpython3-dev" else pkgs+=" python libpython-dev" diff --git a/include/boost/pool/simple_segregated_storage.hpp b/include/boost/pool/simple_segregated_storage.hpp index e0d8c42..fffd4ee 100644 --- a/include/boost/pool/simple_segregated_storage.hpp +++ b/include/boost/pool/simple_segregated_storage.hpp @@ -328,19 +328,6 @@ 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 6c36e97..1323969 100644 --- a/test/test_pool_alloc.cpp +++ b/test/test_pool_alloc.cpp @@ -294,6 +294,61 @@ void test_mem_usage() BOOST_TEST(track_alloc::ok()); } +void test_free_chunk_selection() +{ + typedef boost::pool pool_type; + + { + // Expose a regression from the commit 8ec1be1e82ba559744ecfa3c6ec13f71f9c175cc. + // Two checks will fail here. + pool_type pool(sizeof(void *), 3); + void * ptr_0 = pool.ordered_malloc(1); + void * ptr_1 = pool.ordered_malloc(1); + void * ptr_2 = pool.ordered_malloc(1); + // The blocks are expected to be allocated at subsequent locations + BOOST_TEST((char *)ptr_1 - (char *)ptr_0 == sizeof(void *)); + BOOST_TEST((char *)ptr_2 - (char *)ptr_1 == sizeof(void *)); + + pool.ordered_free(ptr_1, 1); + + void * ptr_1a = pool.ordered_malloc(1); + // Expected to reallocate the former ptr1 block + // which should be the first and only available block + BOOST_TEST(ptr_1a == ptr_1); + + pool.ordered_free(ptr_0, 1); + pool.ordered_free(ptr_1a, 1); + pool.ordered_free(ptr_2, 1); + } + + { + // Another way to expose a regression from the commit 8ec1be1e82ba559744ecfa3c6ec13f71f9c175cc. + // This time we preallocate 4 rather than 3 blocks in the pool. In this case + // the location of the ptr_2 block is as expected. The reallocation of ptr_1 + // block however still fails the location expectation. + pool_type pool(sizeof(void *), 4); + void * ptr_0 = pool.ordered_malloc(1); + void * ptr_1 = pool.ordered_malloc(1); + void * ptr_2 = pool.ordered_malloc(1); + // The blocks are expected to be allocated at subsequent locations + BOOST_TEST((char *)ptr_1 - (char *)ptr_0 == sizeof(void *)); + BOOST_TEST((char *)ptr_2 - (char *)ptr_1 == sizeof(void *)); + + pool.ordered_free(ptr_1, 1); + + void * ptr_1a = pool.ordered_malloc(1); + // Expected to reallocate the former ptr1 block + // which should be the first available block + BOOST_TEST(ptr_1a == ptr_1); + + pool.ordered_free(ptr_0, 1); + pool.ordered_free(ptr_1a, 1); + pool.ordered_free(ptr_2, 1); + } + + BOOST_TEST(track_alloc::ok()); +} + void test_void() { typedef boost::pool_allocator void_allocator; @@ -313,6 +368,7 @@ int main() test(); test_alloc(); test_mem_usage(); + test_free_chunk_selection(); test_void(); return boost::report_errors(); diff --git a/test/test_simple_seg_storage.cpp b/test/test_simple_seg_storage.cpp index 2398cf1..d94be24 100644 --- a/test/test_simple_seg_storage.cpp +++ b/test/test_simple_seg_storage.cpp @@ -315,44 +315,6 @@ int main() 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;