diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fa4ed..6a0946d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,37 @@ Embedded Multicore Building Blocks (EMB²) ========================================= +Version 0.3.1 +------------- + +### Features: +- None + +### Changes and improvements: +- Removed one function argument from algorithms::Invoke +- Added "explicit" specifier to base type constructor of Atomic +- Added "const" qualifier to dereference operator and member access operator of AtomicPointer<> +- Changed AtomicBase<>::CompareAndSwap to atomically return expected value +- Replaced constant in dataflow_cpp_test_simple.cc with corresponding macro +- Added initialization of atomic variable in hazard_pointer_test.cc to avoid warning with GCC 5.1 +- Changed initial value of allocated_object_from_different_thread +- Added tests for ID Pool and check for memory leaks +- Updated unit test for the UniqueLock::Swap + +### Bug fixes: +- Fixed implementation of ID pool (provided fewer elements than specified by capacity) +- Fixed unsigned overflow bug in timed wait function of condition variables +- Fixed implementation of UniqueLock::Swap + +### Build system: +- Improved CMake output for automatic initialization option +- Fixed cpplint and unsigned/signed warnings + +### Documentation: +- Fixed documentation of UniqueLock class +- Updated README file + + Version 0.3.0 ------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index ed453d0..3f43e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ cmake_minimum_required (VERSION 2.8.9) # Version number set (EMBB_BASE_VERSION_MAJOR 0) set (EMBB_BASE_VERSION_MINOR 3) -set (EMBB_BASE_VERSION_PATCH 0) +set (EMBB_BASE_VERSION_PATCH 1) # Fix compilation for CMake versions >= 3.1 # @@ -100,6 +100,13 @@ else() endif() message(" (set with command line option -DWARNINGS_ARE_ERRORS=ON/OFF)") +if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) + message("-- MTAPI/Tasks automatic initialization enabled (default)") +else() + message("-- MTAPI/Tasks automatic initialization disabled") +endif() +message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)") + include(CMakeCommon/SetCompilerFlags.cmake) SetGNUCompilerFlags(compiler_libs compiler_flags) SetVisualStudioCompilerFlags(compiler_libs compiler_flags) diff --git a/README.md b/README.md index 7996d94..bf3b609 100644 --- a/README.md +++ b/README.md @@ -323,6 +323,8 @@ Known Bugs and Limitations is bounded by a predefined but modifiable constant (see functions embb_thread_get_max_count() / embb_thread_set_max_count() and class embb::base::Thread). +- While MTAPI fully supports heterogeneous systems, the algorithms and + dataflow components are currently limited to homogeneous systems. Development and Contribution diff --git a/algorithms_cpp/include/embb/algorithms/invoke.h b/algorithms_cpp/include/embb/algorithms/invoke.h index 10dd818..a3884a4 100644 --- a/algorithms_cpp/include/embb/algorithms/invoke.h +++ b/algorithms_cpp/include/embb/algorithms/invoke.h @@ -49,33 +49,37 @@ typedef embb::base::Function InvokeFunctionType; #ifdef DOXYGEN /** - * Spawns one to ten function objects at once and runs them in parallel. + * Spawns two to ten function objects at once and runs them in parallel. * * Blocks until all of them are done. * * \ingroup CPP_ALGORITHMS_INVOKE */ -template +template void Invoke( Function1 func1, /**< [in] First function object to invoke */ + Function2 func2, + /**< [in] Second function object to invoke */ ...); /** -* Spawns one to ten function objects at once and runs them in parallel using the +* Spawns two to ten function objects at once and runs them in parallel using the * given embb::mtapi::ExecutionPolicy. * * Blocks until all of them are done. * * \ingroup CPP_ALGORITHMS_INVOKE */ -template +template void Invoke( Function1 func1, /**< [in] Function object to invoke */ + Function2 func2, + /**< [in] Second function object to invoke */ ..., - const embb::mtapi::ExecutionPolicy & policy - /**< [in] embb::mtapi::ExecutionPolicy to use */ + const embb::tasks::ExecutionPolicy & policy + /**< [in] embb::tasks::ExecutionPolicy to use */ ); #else // DOXYGEN @@ -118,13 +122,6 @@ class TaskWrapper { }; } // namespace internal -template -void Invoke( - Function1 func1, - const embb::tasks::ExecutionPolicy& policy) { - internal::TaskWrapper wrap1(func1, policy); -} - template void Invoke( Function1 func1, @@ -290,12 +287,6 @@ template wrap10(func10, policy); } -template -void Invoke( - Function1 func1) { - Invoke(func1, embb::tasks::ExecutionPolicy()); -} - template void Invoke( Function1 func1, diff --git a/algorithms_cpp/test/invoke_test.cc b/algorithms_cpp/test/invoke_test.cc index 361e73a..1481747 100644 --- a/algorithms_cpp/test/invoke_test.cc +++ b/algorithms_cpp/test/invoke_test.cc @@ -44,7 +44,6 @@ static void Invocable10() {} void InvokeTest::Test() { using embb::algorithms::Invoke; - Invoke(&Invocable1); Invoke(&Invocable1, &Invocable2); Invoke(&Invocable1, &Invocable2, &Invocable3); Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4); @@ -61,4 +60,24 @@ void InvokeTest::Test() { &Invocable6, &Invocable7, &Invocable8, &Invocable9); Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, &Invocable6, &Invocable7, &Invocable8, &Invocable9, &Invocable10); + + embb::tasks::ExecutionPolicy policy; + Invoke(&Invocable1, &Invocable2, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, &Invocable7, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, &Invocable7, &Invocable8, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, &Invocable7, &Invocable8, &Invocable9, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, &Invocable7, &Invocable8, &Invocable9, policy); + Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, + &Invocable6, &Invocable7, &Invocable8, &Invocable9, &Invocable10, + policy); } diff --git a/base_c/src/condition_variable.c b/base_c/src/condition_variable.c index 81f8c3b..575bb33 100644 --- a/base_c/src/condition_variable.c +++ b/base_c/src/condition_variable.c @@ -83,8 +83,8 @@ int embb_condition_wait_until(embb_condition_t* condition_var, embb_time_t now; embb_time_now(&now); /* Check if absolute timepoint (in milliseconds) still is in the future */ - if (time->seconds * 1000 + time->nanoseconds / 1000000 - - now.seconds * 1000 - now.nanoseconds / 1000000 > 0) { + if ((time->seconds * 1000 + time->nanoseconds / 1000000) + > (now.seconds * 1000 + now.nanoseconds / 1000000)) { /* Convert to (unsigned type) milliseconds and round up */ DWORD time_diff = (DWORD) ( time->seconds * 1000 + time->nanoseconds / 1000000 diff --git a/base_c/test/condition_var_test.cc b/base_c/test/condition_var_test.cc index f292d3c..ad0fe32 100644 --- a/base_c/test/condition_var_test.cc +++ b/base_c/test/condition_var_test.cc @@ -105,7 +105,7 @@ void ConditionVarTest::TestTimedWaitTimeouts() { embb_time_t time; embb_duration_t duration = EMBB_DURATION_INIT; - // Wait for now tests already passed time point + // Wait for "now" tests already passed time point embb_time_now(&time); embb_mutex_lock(&mutex); int status = embb_condition_wait_until(&cond, &mutex, &time); diff --git a/base_c/test/time_test.cc b/base_c/test/time_test.cc index 94d6d1c..9797350 100644 --- a/base_c/test/time_test.cc +++ b/base_c/test/time_test.cc @@ -36,6 +36,9 @@ namespace test { TimeTest::TimeTest() { CreateUnit("Time in duration").Add(&TimeTest::TestTimeInDuration, this); + CreateUnit("Monotonicity").Add( + &TimeTest::TestMonotonicity, this, + 1, partest::TestSuite::GetDefaultNumIterations() * 10); } void TimeTest::TestTimeInDuration() { @@ -48,6 +51,20 @@ void TimeTest::TestTimeInDuration() { PT_EXPECT_EQ(status, EMBB_SUCCESS); } +void TimeTest::TestMonotonicity() { + embb_time_t first; + embb_time_t second; + int status1 = embb_time_in(&first, embb_duration_zero()); + int status2 = embb_time_in(&second, embb_duration_zero()); + PT_EXPECT_EQ(status1, EMBB_SUCCESS); + PT_EXPECT_EQ(status2, EMBB_SUCCESS); + unsigned long long first_abs = first.seconds * 1000 + + first.nanoseconds / 1000000; + unsigned long long second_abs = second.seconds * 1000 + + second.nanoseconds / 1000000; + PT_EXPECT_GE(second_abs, first_abs); +} + } // namespace test } // namespace base } // namespace embb diff --git a/base_c/test/time_test.h b/base_c/test/time_test.h index 629befc..419d26d 100644 --- a/base_c/test/time_test.h +++ b/base_c/test/time_test.h @@ -42,9 +42,14 @@ class TimeTest : public partest::TestCase { private: /** - * Tests time in duration method. + * Tests time-in-duration method. */ void TestTimeInDuration(); + + /** + * Tests that succeedingly taken times are monotonously increasing. + */ + void TestMonotonicity(); }; } // namespace test diff --git a/base_cpp/include/embb/base/internal/mutex-inl.h b/base_cpp/include/embb/base/internal/mutex-inl.h index 0d9b336..86f66ac 100644 --- a/base_cpp/include/embb/base/internal/mutex-inl.h +++ b/base_cpp/include/embb/base/internal/mutex-inl.h @@ -28,6 +28,7 @@ #define EMBB_BASE_INTERNAL_MUTEX_INL_H_ #include +#include namespace embb { namespace base { @@ -95,8 +96,8 @@ void UniqueLock::Unlock() { template void UniqueLock::Swap(UniqueLock& other) { - locked_ = other.locked_; - mutex_ = other.Release(); + std::swap(mutex_, other.mutex_); + std::swap(locked_, other.locked_); } template diff --git a/base_cpp/include/embb/base/mutex.h b/base_cpp/include/embb/base/mutex.h index 0b8c7e3..1d63027 100644 --- a/base_cpp/include/embb/base/mutex.h +++ b/base_cpp/include/embb/base/mutex.h @@ -439,11 +439,11 @@ class UniqueLock { void Unlock(); /** - * Transfers ownership of a mutex to this lock. + * Exchanges ownership of the wrapped mutex with another lock. */ void Swap( UniqueLock& other - /**< [IN/OUT] Lock from which ownership shall be transferred */ + /**< [IN/OUT] The lock to exchange ownership with */ ); /** diff --git a/base_cpp/test/mutex_test.cc b/base_cpp/test/mutex_test.cc index 17e5c9e..48cc0a9 100644 --- a/base_cpp/test/mutex_test.cc +++ b/base_cpp/test/mutex_test.cc @@ -191,13 +191,21 @@ void MutexTest::TestUniqueLock() { } { // Test lock swapping - UniqueLock<> lock1; - UniqueLock<> lock2(mutex_); - PT_EXPECT_EQ(lock1.OwnsLock(), false); - PT_EXPECT_EQ(lock2.OwnsLock(), true); - lock1.Swap(lock2); + UniqueLock<> lock1(mutex_); PT_EXPECT_EQ(lock1.OwnsLock(), true); - PT_EXPECT_EQ(lock2.OwnsLock(), false); + + { + UniqueLock<> lock2; + PT_EXPECT_EQ(lock2.OwnsLock(), false); + + lock1.Swap(lock2); + PT_EXPECT_EQ(lock1.OwnsLock(), false); + PT_EXPECT_EQ(lock2.OwnsLock(), true); + } + + // At this point, "lock2" was destroyed and "mutex_" must be unlocked. + UniqueLock<> lock3(mutex_, embb::base::try_lock); + PT_EXPECT_EQ(lock3.OwnsLock(), true); } } diff --git a/containers_cpp/test/hazard_pointer_test.cc b/containers_cpp/test/hazard_pointer_test.cc index 17a4c38..ab2666c 100644 --- a/containers_cpp/test/hazard_pointer_test.cc +++ b/containers_cpp/test/hazard_pointer_test.cc @@ -97,7 +97,7 @@ void HazardPointerTest::HazardPointerTest1_ThreadMethod() { PT_ASSERT(success == true); - embb::base::Atomic* allocated_object_from_different_thread; + embb::base::Atomic* allocated_object_from_different_thread(0); int diff_count = 0; diff --git a/dataflow_cpp/test/dataflow_cpp_test_simple.cc b/dataflow_cpp/test/dataflow_cpp_test_simple.cc index 78af07c..b434625 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_simple.cc +++ b/dataflow_cpp/test/dataflow_cpp_test_simple.cc @@ -39,7 +39,7 @@ #define NUM_SLICES 8 #define TEST_COUNT 12 -typedef embb::dataflow::Network<8> MyNetwork; +typedef embb::dataflow::Network MyNetwork; typedef MyNetwork::ConstantSource< int > MyConstantSource; typedef MyNetwork::Source< int > MySource; typedef MyNetwork::SerialProcess< MyNetwork::Inputs::Type, @@ -156,9 +156,7 @@ void SimpleTest::TestBasic() { core_set, 1024, // max tasks (default: 1024) 128, // max groups (default: 128) - // Currently needs to be initialized - // with (max_queues + 1), see defect embb449 - num_cores + 1, // max queues (default: 16) + num_cores, // max queues (default: 16) 1024, // queue capacity (default: 1024) 4); // num priorities (default: 4) diff --git a/mtapi_c/src/embb_mtapi_id_pool_t.c b/mtapi_c/src/embb_mtapi_id_pool_t.c index 570fa98..184a9f6 100644 --- a/mtapi_c/src/embb_mtapi_id_pool_t.c +++ b/mtapi_c/src/embb_mtapi_id_pool_t.c @@ -71,7 +71,7 @@ mtapi_uint_t embb_mtapi_id_pool_allocate(embb_mtapi_id_pool_t * that) { /* acquire position to fetch id from */ mtapi_uint_t id_position = that->get_id_position; that->get_id_position++; - if (that->capacity <= that->get_id_position) { + if (that->capacity < that->get_id_position) { that->get_id_position = 0; } @@ -97,7 +97,7 @@ void embb_mtapi_id_pool_deallocate( /* acquire position to put id to */ mtapi_uint_t id_position = that->put_id_position; that->put_id_position++; - if (that->capacity <= that->put_id_position) { + if (that->capacity < that->put_id_position) { that->put_id_position = 0; } diff --git a/mtapi_c/test/embb_mtapi_test_id_pool.cc b/mtapi_c/test/embb_mtapi_test_id_pool.cc new file mode 100644 index 0000000..f7c7855 --- /dev/null +++ b/mtapi_c/test/embb_mtapi_test_id_pool.cc @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +IdPoolTest::IdPoolTest() { + CreateUnit("mtapi id pool test single threaded"). + Add(&IdPoolTest::TestBasic, this, 1, 1000). + Pre(&IdPoolTest::TestBasicPre, this). + Post(&IdPoolTest::TestBasicPost, this); + + CreateUnit("mtapi id pool test concurrent"). + Add(&IdPoolTest::TestParallel, this, concurrent_accessors_id_pool_2 + , 20). + Post(&IdPoolTest::TestParallelPost, this). + Pre(&IdPoolTest::TestParallelPre, this); +} + +void IdPoolTest::TestParallel() { + // allocate ID_ELEMENTS_PER_ACCESSOR elements. Each test thread is + // guaranteed to be able to allocate this amount of elements. + TestAllocateDeallocateNElementsFromPool(id_pool_parallel, + id_elements_per_accessor); +} + +void IdPoolTest::TestParallelPre() { + // create second id pool with CONCURRENT_ACCESSORS_ID_POOL_2* + // ID_ELEMENTS_PER_ACCESSOR elements + embb_mtapi_id_pool_initialize(&id_pool_parallel, + concurrent_accessors_id_pool_2*id_elements_per_accessor); +} + +void IdPoolTest::TestParallelPost() { + // after the parallel tests, try to again allocate and deallocate all + // elements sequentially. + TestAllocateDeallocateNElementsFromPool(id_pool_parallel, + concurrent_accessors_id_pool_2*id_elements_per_accessor, true); + + // finalize pool + embb_mtapi_id_pool_finalize(&id_pool_parallel); +} + +void IdPoolTest::TestBasic() { + TestAllocateDeallocateNElementsFromPool(id_pool, id_pool_size_1, true); +} + +void IdPoolTest::TestBasicPre() { + // create id pool with ID_POOL_SIZE_1 elements + embb_mtapi_id_pool_initialize(&id_pool, id_pool_size_1); +} + +void IdPoolTest::TestBasicPost() { + // finalize pool + embb_mtapi_id_pool_finalize(&id_pool); +} + +void IdPoolTest::TestAllocateDeallocateNElementsFromPool( + embb_mtapi_id_pool_t &pool, + int count_elements, + bool empty_check) { + std::vector allocated; + + for (int i = 0; i != count_elements; ++i) { + allocated.push_back(embb_mtapi_id_pool_allocate(&pool)); + } + + // the allocated elements should be disjunctive, and never invalid element + for (unsigned int x = 0; x != allocated.size(); ++x) { + PT_ASSERT(allocated[x] != EMBB_MTAPI_IDPOOL_INVALID_ID); + for (unsigned int y = 0; y != allocated.size(); ++y) { + if (x == y) { + continue; + } + PT_ASSERT(allocated[x] != allocated[y]); + } + } + + // now the id pool should be empty... try ten times to get an id, + // we should always get the invalid element + if (empty_check) { + for (int i = 0; i != 10; ++i) { + PT_ASSERT_EQ(embb_mtapi_id_pool_allocate(&pool), + static_cast(EMBB_MTAPI_IDPOOL_INVALID_ID) + ) + } + } + + // now return allocated elements in a shuffled manner. + ::std::random_shuffle(allocated.begin(), allocated.end()); + + for (int i = 0; i != count_elements; ++i) { + embb_mtapi_id_pool_deallocate(&pool, + allocated[static_cast(i)]); + } +} + diff --git a/mtapi_c/test/embb_mtapi_test_id_pool.h b/mtapi_c/test/embb_mtapi_test_id_pool.h new file mode 100644 index 0000000..a85a284 --- /dev/null +++ b/mtapi_c/test/embb_mtapi_test_id_pool.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MTAPI_C_TEST_EMBB_MTAPI_TEST_ID_POOL_H_ +#define MTAPI_C_TEST_EMBB_MTAPI_TEST_ID_POOL_H_ + +#include +#include + +// for shuffling a vector +#include + +class IdPoolTest : public partest::TestCase { + public: + embb_mtapi_id_pool_t id_pool; + embb_mtapi_id_pool_t id_pool_parallel; + + IdPoolTest(); + + private: + static const unsigned int id_pool_size_1 = 100; + static const unsigned int concurrent_accessors_id_pool_2 = 10; + static const unsigned int id_elements_per_accessor = 10; + + /** + * We create a pool of size number_accessors*elements_per_accessor, so + * at each time we can guarantee each thread to be able to allocate + * elements_per_accessor elements. + * We create number_accessor threads, where each thread iteratively + * allocates and frees elements_per_accessor elements, which in each case + * has to be successful. Additionally, the sanity checks from the basic tests + * are repeated. The TestParallelPost function also repeats all + * sequential tests. + */ + void TestParallel(); + void TestParallelPre(); + void TestParallelPost(); + + /** + * Create a pool of size N. We repeatedly allocate and free N elements, check + * if the pool always returns disjunctive ids and check that the pool never + * returns the invalid element, if the pool is not empty. Check that the + * invalid element is returned if the pool is empty. + */ + void TestBasic(); + void TestBasicPre(); + void TestBasicPost(); + + static void TestAllocateDeallocateNElementsFromPool( + embb_mtapi_id_pool_t &pool, + int count_elements, + bool empty_check = false); +}; + +#endif // MTAPI_C_TEST_EMBB_MTAPI_TEST_ID_POOL_H_ diff --git a/mtapi_c/test/main.cc b/mtapi_c/test/main.cc index a92b25d..85b2e57 100644 --- a/mtapi_c/test/main.cc +++ b/mtapi_c/test/main.cc @@ -37,6 +37,9 @@ #include #include #include +#include + +#include PT_MAIN("MTAPI C") { embb_log_set_log_level(EMBB_LOG_LEVEL_NONE); @@ -48,4 +51,7 @@ PT_MAIN("MTAPI C") { PT_RUN(InitFinalizeTest); PT_RUN(GroupTest); PT_RUN(QueueTest); + PT_RUN(IdPoolTest); + + PT_EXPECT(embb_get_bytes_allocated() == 0); } diff --git a/mtapi_cpp/CMakeLists.txt b/mtapi_cpp/CMakeLists.txt index 3652d63..3a343f2 100644 --- a/mtapi_cpp/CMakeLists.txt +++ b/mtapi_cpp/CMakeLists.txt @@ -5,14 +5,10 @@ file(GLOB_RECURSE EMBB_MTAPI_CPP_HEADERS "include/*.h") file(GLOB_RECURSE EMBB_MTAPI_CPP_TEST_SOURCES "test/*.cc" "test/*.h") if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) - message("-- Automatic initialization enabled (default)") set(MTAPI_CPP_AUTOMATIC_INITIALIZE 1) else() set(MTAPI_CPP_AUTOMATIC_INITIALIZE 0) - message("-- Automatic initialization disabled") endif() -message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)") - # Execute the GroupSources macro include(${CMAKE_SOURCE_DIR}/CMakeCommon/GroupSourcesMSVC.cmake) diff --git a/tasks_cpp/CMakeLists.txt b/tasks_cpp/CMakeLists.txt index 31effbf..397be86 100644 --- a/tasks_cpp/CMakeLists.txt +++ b/tasks_cpp/CMakeLists.txt @@ -5,13 +5,10 @@ file(GLOB_RECURSE EMBB_TASKS_CPP_HEADERS "include/*.h") file(GLOB_RECURSE EMBB_TASKS_CPP_TEST_SOURCES "test/*.cc" "test/*.h") if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) - message("-- Automatic initialization enabled (default)") set(TASKS_CPP_AUTOMATIC_INITIALIZE 1) else() set(TASKS_CPP_AUTOMATIC_INITIALIZE 0) - message("-- Automatic initialization disabled") endif() -message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)") configure_file("include/embb/tasks/internal/cmake_config.h.in" "include/embb/tasks/internal/cmake_config.h")