From da5d91c5f6ba348b5362bc505ad4f335fa3bceaf Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 10:27:59 +0200 Subject: [PATCH 01/11] closes https://github.com/kimkulling/cppcore/issues/3: introduce a freelist to manage relesed pools. --- include/cppcore/Memory/TPoolAllocator.h | 48 ++++++++++++++++++------- test/memory/TPoolAllocatorTest.cpp | 19 ++++++++-- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/include/cppcore/Memory/TPoolAllocator.h b/include/cppcore/Memory/TPoolAllocator.h index 0876b86..cc99721 100644 --- a/include/cppcore/Memory/TPoolAllocator.h +++ b/include/cppcore/Memory/TPoolAllocator.h @@ -86,25 +86,37 @@ class TPoolAllocator { CPPCORE_NONE_COPYING(Pool) }; + Pool *getFreePool() { + Pool *current(m_freeList); + if (nullptr != m_freeList) { + m_freeList = m_freeList->m_next; + } + return current; + } + Pool *m_first; Pool *m_current; + Pool *m_freeList; size_t m_capacity; }; template inline TPoolAllocator::TPoolAllocator() -: m_first(nullptr) -, m_current(nullptr) -, m_capacity(0L) { +: m_first( nullptr ) +, m_current( nullptr ) +, m_freeList( nullptr ) +, m_capacity( 0L ) { // empty } template inline TPoolAllocator::TPoolAllocator(size_t numItems) -: m_first(nullptr) -, m_current(nullptr) { +: m_first( nullptr ) +, m_current( nullptr ) +, m_freeList( nullptr ) +, m_capacity(0L) { m_first = new Pool(numItems); m_current = m_first; } @@ -140,6 +152,14 @@ void TPoolAllocator::release() { } m_current->m_currentIdx = 0; + + Pool *current(m_first); + while(nullptr != current ) { + current->m_currentIdx = 0; + current = current->m_next; + } + m_freeList = m_first->m_next; + m_current = m_first; } template @@ -170,22 +190,19 @@ void TPoolAllocator::clear() { delete current; } m_current = nullptr; + m_freeList = nullptr; } template inline size_t TPoolAllocator::capacity() const { - if (nullptr == m_current) { - return 0L; - } - - return m_current->m_poolsize; + return m_capacity; } template inline size_t TPoolAllocator::reservedMem() const { - return m_capacity; + return m_capacity * sizeof(T); } template @@ -219,11 +236,16 @@ void TPoolAllocator::resize(size_t growSize) { if (nullptr == m_first) { m_first = new Pool(growSize, nullptr); m_current = m_first; + m_capacity += m_current->m_poolsize; } else { - m_current->m_next = new Pool(growSize, nullptr); + Pool *pool = getFreePool(); + if (nullptr == pool) { + pool = new Pool(growSize, nullptr); + m_capacity += growSize; + } + m_current->m_next = pool; m_current = m_current->m_next; } - m_capacity += m_current->m_poolsize; } } // Namespace CPPCore diff --git a/test/memory/TPoolAllocatorTest.cpp b/test/memory/TPoolAllocatorTest.cpp index f1597d3..359bb17 100644 --- a/test/memory/TPoolAllocatorTest.cpp +++ b/test/memory/TPoolAllocatorTest.cpp @@ -92,10 +92,25 @@ TEST_F(TPoolAllocatorTest, clearTest ) { TEST_F(TPoolAllocatorTest, resizeTest) { TPoolAllocator allocator; allocator.resize(100); - //allocator.resize(100); for (size_t i = 0; i < 200; ++i) { EXPECT_NE(nullptr, allocator.alloc()); } - EXPECT_EQ(200u, allocator.reservedMem()); + EXPECT_EQ(200u, allocator.capacity()); +} + +TEST_F(TPoolAllocatorTest, releaseTest) { + TPoolAllocator allocator; + allocator.resize(100); + for (size_t i = 0; i < 200; ++i) { + EXPECT_NE(nullptr, allocator.alloc()); + } + + allocator.release(); + for (size_t i = 0; i < 200; ++i) { + EXPECT_NE(nullptr, allocator.alloc()); + } + + size_t c = allocator.capacity(); + EXPECT_EQ(200u, allocator.capacity()); } From 1a6849a3c73a3d5af2c0fea16cb53ef9c9c398c1 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 10:34:01 +0200 Subject: [PATCH 02/11] Fix compiler warnings: comparing signed against unsigned. --- test/container/TArrayTest.cpp | 34 +++++++++++++++--------------- test/memory/TPoolAllocatorTest.cpp | 1 - 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/test/container/TArrayTest.cpp b/test/container/TArrayTest.cpp index 468012c..e45a6c8 100644 --- a/test/container/TArrayTest.cpp +++ b/test/container/TArrayTest.cpp @@ -2,7 +2,7 @@ ------------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2016 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -158,12 +158,12 @@ TEST_F( TArrayTest, removeTest) { TEST_F( TArrayTest, removeItTest) { TArray arrayInstance; arrayInstance.add( 1.0f ); - EXPECT_EQ( 1, arrayInstance.size() ); + EXPECT_EQ( 1u, arrayInstance.size() ); TArray::Iterator it = arrayInstance.find( 1.0f ); EXPECT_NE( arrayInstance.end(), it ); arrayInstance.remove( it ); - EXPECT_EQ( 0, arrayInstance.size() ); + EXPECT_EQ( 0u, arrayInstance.size() ); } TEST_F( TArrayTest, removeBackTest) { @@ -171,16 +171,16 @@ TEST_F( TArrayTest, removeBackTest) { createArray( ArrayData, ArraySize, arrayInstance ); arrayInstance.removeBack(); - EXPECT_EQ( 3, arrayInstance.size() ); + EXPECT_EQ( 3u, arrayInstance.size() ); EXPECT_EQ( 2.0f, arrayInstance[ 2 ] ); } TEST_F( TArrayTest, resizeTest ) { TArray arrayInstance; - EXPECT_EQ( 0, arrayInstance.size() ); + EXPECT_EQ( 0u, arrayInstance.size() ); arrayInstance.resize( 5 ); - EXPECT_EQ( 5, arrayInstance.size() ); + EXPECT_EQ( 5u, arrayInstance.size() ); } TEST_F( TArrayTest, moveTest ) { @@ -193,22 +193,23 @@ TEST_F( TArrayTest, moveTest ) { TEST_F( TArrayTest, reserveTest ) { TArray arrayInstance; - EXPECT_EQ( 0, arrayInstance.capacity() ); + EXPECT_EQ( 0u, arrayInstance.capacity() ); arrayInstance.reserve( 5 ); - EXPECT_EQ( 5, arrayInstance.capacity() ); + EXPECT_EQ( 5u, arrayInstance.capacity() ); - arrayInstance.reserve( 2000 ); - EXPECT_EQ( 2000, arrayInstance.capacity() ); + static const size_t NewSize = 2000; + arrayInstance.reserve(NewSize); + EXPECT_EQ( NewSize, arrayInstance.capacity() ); } TEST_F( TArrayTest, resize_with_init_Test ) { TArray arrayInstance; - EXPECT_EQ( 0, arrayInstance.capacity() ); + EXPECT_EQ( 0u, arrayInstance.capacity() ); arrayInstance.resize( 10, 1.0f ); - EXPECT_EQ( 10, arrayInstance.size() ); - for ( size_t i = 0; i < 10; i++ ) { + EXPECT_EQ( 10u, arrayInstance.size() ); + for ( size_t i = 0; i < 10; ++i ) { EXPECT_FLOAT_EQ( 1.0f, arrayInstance[ i ] ); } } @@ -230,7 +231,7 @@ TEST_F( TArrayTest, preIncIterateTest ) { bool ok = true; try { - size_t i=0; + size_t i( 0 ); for( TArray::Iterator it = arrayInstance.begin( ); it != arrayInstance.end( ); ++it ) { float tmp = *it; EXPECT_EQ( tmp, ArrayData[ i ] ); @@ -248,7 +249,7 @@ TEST_F( TArrayTest, postIncIterateTest ) { bool ok = true; try { - size_t i=0; + size_t i(0); for( TArray::Iterator it = arrayInstance.begin( ); it != arrayInstance.end( ); it++ ) { float tmp = *it; EXPECT_EQ( tmp, ArrayData[ i ] ); @@ -266,7 +267,7 @@ TEST_F( TArrayTest, findTest ) { arrayInstance.add( 1.0f ); arrayInstance.add( 2.0f ); arrayInstance.add( 3.0f ); - EXPECT_EQ( 4, arrayInstance.size() ); + EXPECT_EQ( 4u, arrayInstance.size() ); TArray::Iterator it = arrayInstance.find( 1.0f ); EXPECT_NE( it, arrayInstance.end() ); @@ -311,4 +312,3 @@ TEST_F( TArrayTest, bug_AddHeapCorruptTest ) { arrayInstance.add( ( float ) i ); } } - diff --git a/test/memory/TPoolAllocatorTest.cpp b/test/memory/TPoolAllocatorTest.cpp index 359bb17..5419839 100644 --- a/test/memory/TPoolAllocatorTest.cpp +++ b/test/memory/TPoolAllocatorTest.cpp @@ -111,6 +111,5 @@ TEST_F(TPoolAllocatorTest, releaseTest) { EXPECT_NE(nullptr, allocator.alloc()); } - size_t c = allocator.capacity(); EXPECT_EQ(200u, allocator.capacity()); } From 0269c484bfcc03f794613cfb20ab11d187243cf6 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 10:40:18 +0200 Subject: [PATCH 03/11] Fix more signed-unsigned warnings. --- .travis.yml | 2 +- build/CMakeLists.txt | 25 ++++++++++++++++++++++++- test/container/TListTest.cpp | 29 +++++++++-------------------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2289b6c..776d471 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ before_install: - sudo apt-get install cmake os: -# - windows - linux language: @@ -13,6 +12,7 @@ language: compiler: - gcc - clang + script: - cd build && cmake -G "Unix Makefiles" && make -j4 && cd bin && ./cppcore_unittest diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2b89b6f..c2da8bf 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -10,7 +10,18 @@ if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) find_package(Threads) endif() -option( BUILD_UNITTESTS "Build unit tests." ON ) +option( BUILD_UNITTESTS + "Build unit tests." + ON +) +option( CPPCORE_ASAN + "Enable AddressSanitizer." + OFF +) +option( CPPCORE_UBSAN + "Enable Undefined Behavior sanitizer." + OFF +) add_definitions( -DCPPCORE_BUILD ) add_definitions( -D_VARIADIC_MAX=10 ) @@ -45,6 +56,18 @@ elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11") endif() +IF (ASSIMP_ASAN) + MESSAGE(STATUS "AddressSanitizer enabled") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") +ENDIF() + +IF (ASSIMP_UBSAN) + MESSAGE(STATUS "Undefined Behavior sanitizer enabled") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") +ENDIF() + SET ( cppcore_src ../code/cppcore.cpp ../include/cppcore/CPPCoreCommon.h diff --git a/test/container/TListTest.cpp b/test/container/TListTest.cpp index d8d6440..5848207 100644 --- a/test/container/TListTest.cpp +++ b/test/container/TListTest.cpp @@ -2,7 +2,7 @@ ------------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2016 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -40,25 +40,23 @@ using namespace CPPCore; //------------------------------------------------------------------------------------------------- class TListTest : public testing::Test { protected: - void createList( size_t numEntries, TList &rDataList, std::vector &rValues ) { - rValues.resize( 0 ); - rDataList.clear(); + void createList( size_t numEntries, TList &dataList, std::vector &values ) { + values.resize( 0 ); + dataList.clear(); for( size_t i = 0; i listTest; EXPECT_TRUE( listTest.isEmpty() ); EXPECT_EQ( 0u, listTest.size() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, addBackTest) { TList listTest; listTest.addBack( 1.0f ); @@ -69,7 +67,6 @@ TEST_F( TListTest, addBackTest) { EXPECT_TRUE( !listTest.isEmpty() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, addFrontTest) { TList listTest; listTest.addFront( 1.0f ); @@ -80,7 +77,6 @@ TEST_F( TListTest, addFrontTest) { EXPECT_TRUE( !listTest.isEmpty() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, copyTest ) { TList listTest; TList copyTest1( listTest ); @@ -94,7 +90,6 @@ TEST_F( TListTest, copyTest ) { EXPECT_EQ( 2u, copyTest2.size() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, accessTest ) { const size_t numEntries = 10; TList listTest; @@ -113,21 +108,19 @@ TEST_F( TListTest, accessTest ) { } } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, clearTest ) { - const size_t numEntries = 10; + static const size_t numEntries = 10; TList listTest; std::vector values; createList( numEntries, listTest, values ); listTest.clear(); - EXPECT_EQ( listTest.size(), 0 ); + EXPECT_EQ( listTest.size(), 0u ); EXPECT_TRUE( listTest.isEmpty() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, removeTest ) { - const size_t numEntries = 10; + static const size_t numEntries = 10; TList listTest; std::vector values; @@ -140,7 +133,6 @@ TEST_F( TListTest, removeTest ) { } } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, isEmptyTest ) { TList listTest; EXPECT_TRUE( listTest.isEmpty() ); @@ -151,7 +143,6 @@ TEST_F( TListTest, isEmptyTest ) { EXPECT_TRUE( listTest.isEmpty() ); } -//--------------------------------------------------------------------------------------------- TEST_F( TListTest, bug_IterateEmptyListTest ) { TList listTest; bool ok = true; @@ -162,5 +153,3 @@ TEST_F( TListTest, bug_IterateEmptyListTest ) { } EXPECT_TRUE( ok ); } - -//--------------------------------------------------------------------------------------------- From f4426c75c859689e35beedceb14f2fefd51faada Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:03:26 +0200 Subject: [PATCH 04/11] Fix review findings. --- include/cppcore/Memory/TPoolAllocator.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/cppcore/Memory/TPoolAllocator.h b/include/cppcore/Memory/TPoolAllocator.h index cc99721..a28ca42 100644 --- a/include/cppcore/Memory/TPoolAllocator.h +++ b/include/cppcore/Memory/TPoolAllocator.h @@ -118,6 +118,7 @@ TPoolAllocator::TPoolAllocator(size_t numItems) , m_freeList( nullptr ) , m_capacity(0L) { m_first = new Pool(numItems); + m_capacity += numItems; m_current = m_first; } @@ -151,8 +152,6 @@ void TPoolAllocator::release() { return; } - m_current->m_currentIdx = 0; - Pool *current(m_first); while(nullptr != current ) { current->m_currentIdx = 0; From 824a6d8610bb6d09dbf37a95f917a3ae6b225e32 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:16:47 +0200 Subject: [PATCH 05/11] Introduce sanity check for clang. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 776d471..9f22d7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,8 @@ compiler: - gcc - clang -script: - - cd build && cmake -G "Unix Makefiles" && make -j4 && cd bin && ./cppcore_unittest - - +before_script: + - cd build && cmake -G "Unix Makefiles" && cd .. +script: + - . ./.travis.sh From a88540bec5f0d75428a97ea3b302d14703dc82da Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:25:51 +0200 Subject: [PATCH 06/11] Add missing file. --- .travis.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .travis.sh diff --git a/.travis.sh b/.travis.sh new file mode 100644 index 0000000..d797ea6 --- /dev/null +++ b/.travis.sh @@ -0,0 +1,28 @@ +function generate() { + OPTIONS="" + + if [ "$ASAN" = "ON" ] ; then + OPTIONS="$OPTIONS -DCPPCORE_ASAN=ON" + else + OPTIONS="$OPTIONS -DCPPCORE_ASAN=OFF" + fi + + if [ "$UBSAN" = "ON" ] ; then + OPTIONS="$OPTIONS -DCPPCORE_UBSAN=ON" + else + OPTIONS="$OPTIONS -DCPPCORE_UBSAN=OFF" + fi + + cmake -G "Unix Makefiles" $OPTIONS +} +if [ "$TRAVIS_OS_NAME" = "linux" ]; then + if [ $ANALYZE = "ON" ] ; then + if [ "$CC" = "clang" ]; then + scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF + scan-build --status-bugs make -j2 + fi + else + generate \ + && make -j4 && cd bin && ./cppcore_unittest + fi +fi From c111751d335227048411b07de839ba769865f0e5 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:30:36 +0200 Subject: [PATCH 07/11] Fix folder for cmake. --- .travis.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.sh b/.travis.sh index d797ea6..3fbb09c 100644 --- a/.travis.sh +++ b/.travis.sh @@ -18,11 +18,12 @@ function generate() { if [ "$TRAVIS_OS_NAME" = "linux" ]; then if [ $ANALYZE = "ON" ] ; then if [ "$CC" = "clang" ]; then - scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF - scan-build --status-bugs make -j2 + cd build + scan-build cmake -G "Unix Makefiles" + scan-build --status-bugs make -j4 fi else generate \ - && make -j4 && cd bin && ./cppcore_unittest + && cd build && make -j4 && cd bin && ./cppcore_unittest fi fi From 7a9c5f82893acce758f0f7d79c99e49bf8abd598 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:37:31 +0200 Subject: [PATCH 08/11] Fix environment for analyze. --- .travis.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9f22d7f..02de489 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,23 @@ language: compiler: - gcc - clang + +matrix: + include: + - os: linux + compiler: clang + env: ASAN=ON + - os: linux + compiler: clang + env: ANALYZE=ON + - os: linux + compiler: clang + env: UBSAN=ON + - os: linux + compiler: gcc + - os: linux + compiler: gcc + env: ANALYZE=ON before_script: - cd build && cmake -G "Unix Makefiles" && cd .. From ea8b29d4cece79ad30bf79cb220504ac49a71d5c Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:44:50 +0200 Subject: [PATCH 09/11] Remove not needed cmake call from travis script. --- .travis.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.sh b/.travis.sh index 3fbb09c..7a02b3d 100644 --- a/.travis.sh +++ b/.travis.sh @@ -15,11 +15,10 @@ function generate() { cmake -G "Unix Makefiles" $OPTIONS } + if [ "$TRAVIS_OS_NAME" = "linux" ]; then if [ $ANALYZE = "ON" ] ; then if [ "$CC" = "clang" ]; then - cd build - scan-build cmake -G "Unix Makefiles" scan-build --status-bugs make -j4 fi else From 3767267b861a81ab9c5b6057b116793448b8d5e0 Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 11:49:29 +0200 Subject: [PATCH 10/11] another fix for cmake generation. --- .travis.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.sh b/.travis.sh index 7a02b3d..568f313 100644 --- a/.travis.sh +++ b/.travis.sh @@ -13,16 +13,19 @@ function generate() { OPTIONS="$OPTIONS -DCPPCORE_UBSAN=OFF" fi + cd build cmake -G "Unix Makefiles" $OPTIONS } if [ "$TRAVIS_OS_NAME" = "linux" ]; then - if [ $ANALYZE = "ON" ] ; then + if [ "$ANALYZE" = "ON" ] ; then if [ "$CC" = "clang" ]; then + cd build + scan-build cmake -G "Unix Makefiles" scan-build --status-bugs make -j4 fi else generate \ - && cd build && make -j4 && cd bin && ./cppcore_unittest + && make -j4 && cd bin && ./cppcore_unittest fi fi From 6a8a81169d76b72281842ccbbaf19976c109c7af Mon Sep 17 00:00:00 2001 From: kimkulling Date: Fri, 9 Aug 2019 12:46:22 +0200 Subject: [PATCH 11/11] Add missing shebang to descripe which shell shall be used. --- .travis.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.sh b/.travis.sh index 568f313..86f6727 100644 --- a/.travis.sh +++ b/.travis.sh @@ -1,3 +1,4 @@ +#!/bin/bash function generate() { OPTIONS=""