From c2aa4b79bc076fc06c4f388e6d74ddbd6a521ca5 Mon Sep 17 00:00:00 2001 From: bernhard-gatzhammer Date: Wed, 17 Feb 2016 09:25:37 +0100 Subject: [PATCH] Started work on mutex-based atomics implementation. EMBB-517 --- CMakeLists.txt | 9 +++++++++ base_c/include/embb/base/c/atomic.h | 8 ++++++-- base_c/include/embb/base/c/internal/atomic/and_assign.h | 16 ++++++++++++++++ base_c/include/embb/base/c/internal/atomic/atomic_variables.h | 23 +++++++++++++++++++++++ base_c/include/embb/base/c/internal/atomic/init.h | 32 -------------------------------- base_c/include/embb/base/c/internal/atomic/init_destroy.h | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ base_c/include/embb/base/c/internal/atomic/load.h | 19 +++++++++++++++++++ base_c/include/embb/base/c/internal/cmake_config.h.in | 5 +++++ base_c/test/atomic_test.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ base_c/test/atomic_test.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ base_c/test/main.cc | 3 +++ 11 files changed, 327 insertions(+), 34 deletions(-) delete mode 100755 base_c/include/embb/base/c/internal/atomic/init.h create mode 100755 base_c/include/embb/base/c/internal/atomic/init_destroy.h create mode 100755 base_c/test/atomic_test.cc create mode 100755 base_c/test/atomic_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f43e85..5a8840a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" ON) option(WARNINGS_ARE_ERRORS "Specify whether warnings should be treated as errors" OFF) option(USE_AUTOMATIC_INITIALIZATION "Specify whether the MTAPI C++ interface, algorithms and dataflow should automatically intialize the MTAPI node if no explicit initialization is present" ON) +option(THREADING_ANALYSIS_MODE "Replaces lock-free synchronization constructs by mutex-based implementations to support threading analysis tools" OFF) ## LOCAL INSTALLATION OF SUBPROJECT BINARIES # @@ -101,12 +102,20 @@ endif() message(" (set with command line option -DWARNINGS_ARE_ERRORS=ON/OFF)") if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) + set(EMBB_THREADING_ANALYSIS_MODE 1) 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)") +if (THREADING_ANALYSIS_MODE STREQUAL ON) + message("-- Threading analysis mode enabled") +else() + message("-- Threading analysis mode disabled (default") +endif() +message(" (set with command line option -DTHREADING_ANALYSIS_MODE=ON/OFF)") + include(CMakeCommon/SetCompilerFlags.cmake) SetGNUCompilerFlags(compiler_libs compiler_flags) SetVisualStudioCompilerFlags(compiler_libs compiler_flags) diff --git a/base_c/include/embb/base/c/atomic.h b/base_c/include/embb/base/c/atomic.h index b1bb9fb..11dfddc 100644 --- a/base_c/include/embb/base/c/atomic.h +++ b/base_c/include/embb/base/c/atomic.h @@ -92,7 +92,9 @@ * atomic operations. * * \ingroup C_BASE_ATOMIC - * \notthreadsafe + * \notthreadsafe No thread safety is given with respect to multiple calls of + * the method itself or to concurrent calls with other + * embb_atomic methods. */ void embb_atomic_init_TYPE( emb_atomic_TYPE* variable, @@ -108,7 +110,9 @@ void embb_atomic_init_TYPE( * \post The atomic variable is uninitialized. * * \ingroup C_BASE_ATOMIC - * \notthreadsafe + * \notthreadsafe No thread safety is given with respect to multiple calls of + * the method itself or to concurrent calls with other + * embb_atomic methods. */ void embb_atomic_destroy_TYPE( emb_atomic_TYPE* variable diff --git a/base_c/include/embb/base/c/internal/atomic/and_assign.h b/base_c/include/embb/base/c/internal/atomic/and_assign.h index 9a99f51..6712ab3 100644 --- a/base_c/include/embb/base/c/internal/atomic/and_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/and_assign.h @@ -53,6 +53,20 @@ * BYTE_SIZE is the number of bytes passed to the macro. * */ +#ifdef EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_AND_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_and_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ + EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ + embb_atomic_internal_check_init_flag(variable->init_flag); \ + embb_mutex_lock(&(variable->mutex)); \ + variable->internal_variable |= value; \ + embb_mutex_unlock(&(variable->mutex)); \ + } + +#else // EMBB_THREADING_ANALYSIS_MODE + #ifdef EMBB_PLATFORM_ARCH_X86 #ifdef EMBB_PLATFORM_COMPILER_MSVC @@ -156,6 +170,8 @@ EMBB_DEFINE_AND_ASSIGN(4, "") (&(variable->internal_variable)), value_pun); \ } +#endif // else EMBB_THREADING_ANALYSIS_MODE + #undef EMBB_ATOMIC_METHOD_TO_GENERATE #define EMBB_ATOMIC_METHOD_TO_GENERATE AND_ASSIGN_METHOD #include diff --git a/base_c/include/embb/base/c/internal/atomic/atomic_variables.h b/base_c/include/embb/base/c/internal/atomic/atomic_variables.h index 1b06df9..9f377a4 100644 --- a/base_c/include/embb/base/c/internal/atomic/atomic_variables.h +++ b/base_c/include/embb/base/c/internal/atomic/atomic_variables.h @@ -28,20 +28,43 @@ #define EMBB_BASE_C_INTERNAL_ATOMIC_ATOMIC_VARIABLES_H_ #include +#include #include #ifdef EMBB_PLATFORM_COMPILER_MSVC #include #endif +#ifdef EMBB_THREADING_ANALYSIS_MODE + +#include + +// Flag value to indicate that an atomic variable has been initialized +// Value 31426 corresponds to binary number 0111101011000010 +#define EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE 31426 + #define EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE( \ EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, \ EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) \ typedef struct \ { \ EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ + embb_mutex_t mutex; \ + volatile int init_flag; \ } EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX); +#else // EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE( \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, \ + EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) \ + typedef struct \ +{ \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ +} EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX); + +#endif // else EMBB_THREADING_ANALYSIS_MODE + EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char) EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(short, short) EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(unsigned short, unsigned_short) diff --git a/base_c/include/embb/base/c/internal/atomic/init.h b/base_c/include/embb/base/c/internal/atomic/init.h deleted file mode 100755 index e282f6c..0000000 --- a/base_c/include/embb/base/c/internal/atomic/init.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_ -#define EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_ - -// TODO implementation of embb_atomic_init() - -#endif // EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_ diff --git a/base_c/include/embb/base/c/internal/atomic/init_destroy.h b/base_c/include/embb/base/c/internal/atomic/init_destroy.h new file mode 100755 index 0000000..e74ef30 --- /dev/null +++ b/base_c/include/embb/base/c/internal/atomic/init_destroy.h @@ -0,0 +1,109 @@ +/* + * 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 +#include +#include +#include +#include + +#ifndef EMBB_BASE_C_INTERNAL_ATOMIC_INIT_DESTROY_H_ +#define EMBB_BASE_C_INTERNAL_ATOMIC_INIT_DESTROY_H_ + +#ifdef EMBB_THREADING_ANALYSIS_MODE + +#include +#include +#include + +EMBB_PLATFORM_INLINE void embb_atomic_internal_check_init_flag(int flag) { + if (flag != EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE) { + fprintf(stderr, "Exit program due to not initialized or not properly " + "synchronized initialization of atomic variable"); + exit(EMBB_ERROR); + } +} +#endif + + +// embb_mutex_init(): + +#ifdef EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_INIT_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_init_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)( \ + volatile EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE initial_value) { \ + embb_mutex_init(&(((EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)*)variable)->mutex), EMBB_MUTEX_PLAIN); \ + variable->init_flag = EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE; \ + variable->internal_variable = initial_value; \ + } + +#else // EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_INIT_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_init_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)( \ + EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) volatile* variable, \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE initial_value) { \ + memcpy(&(variable->internal_variable), &initial_value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ + } + +#endif // else EMBB_THREADING_ANALYSIS_MODE + +#undef EMBB_ATOMIC_METHOD_TO_GENERATE +#define EMBB_ATOMIC_METHOD_TO_GENERATE INIT_METHOD +#include +#undef EMBB_ATOMIC_METHOD_TO_GENERATE + + + +// embb_mutex_destroy(): + +#ifdef EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_DESTROY_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_destroy_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) \ + { \ + embb_mutex_destroy(&(variable->mutex)); \ + variable->init_flag = EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE - 1; \ + } + +#else // EMBB_THREADING_ANALYSIS_MODE + +#define EMBB_ATOMIC_INTERNAL_DEFINE_DESTROY_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_destroy_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) \ + {} + +#endif // else EMBB_THREADING_ANALYSIS_MODE + +#undef EMBB_ATOMIC_METHOD_TO_GENERATE +#define EMBB_ATOMIC_METHOD_TO_GENERATE DESTROY_METHOD +#include +#undef EMBB_ATOMIC_METHOD_TO_GENERATE + + +#endif // EMBB_BASE_C_INTERNAL_ATOMIC_INIT_DESTROY_H_ diff --git a/base_c/include/embb/base/c/internal/atomic/load.h b/base_c/include/embb/base/c/internal/atomic/load.h index 8a01f08..88519b4 100644 --- a/base_c/include/embb/base/c/internal/atomic/load.h +++ b/base_c/include/embb/base/c/internal/atomic/load.h @@ -35,6 +35,23 @@ #include #include +#ifdef EMBB_THREADING_ANALYSIS_MODE + +/** + * This macro is used to generate the load function for all atomic types + */ +#define EMBB_ATOMIC_INTERNAL_DEFINE_LOAD_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ + EMBB_PLATFORM_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_load_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ + const EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \ + embb_atomic_internal_check_init_flag(variable->init_flag); \ + embb_mutex_lock((embb_mutex_t*)&(variable->mutex)); \ + EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_value = variable->internal_variable; \ + embb_mutex_unlock((embb_mutex_t*)&(variable->mutex)); \ + return return_value; \ + } + +#else // EMBB_THREADING_ANALYSIS_MODE + /* * See file and_assign.h for a detailed (and operation independent) description * of the following macro. @@ -128,6 +145,8 @@ EMBB_DEFINE_LOAD(4, "") return return_val_pun; \ } +#endif // else EMBB_THREADING_ANALYSIS_MODE + #undef EMBB_ATOMIC_METHOD_TO_GENERATE #define EMBB_ATOMIC_METHOD_TO_GENERATE LOAD_METHOD #include diff --git a/base_c/include/embb/base/c/internal/cmake_config.h.in b/base_c/include/embb/base/c/internal/cmake_config.h.in index 12eae11..347690c 100644 --- a/base_c/include/embb/base/c/internal/cmake_config.h.in +++ b/base_c/include/embb/base/c/internal/cmake_config.h.in @@ -53,4 +53,9 @@ */ #cmakedefine EMBB_PLATFORM_HAS_GLIB_CPU +/** + * Enables mutex-based implementation of all synchronization constructs. + */ +#cmakedefine EMBB_THREADING_ANALYSIS_MODE + #endif /* EMBB_BASE_INTERNAL_CMAKE_CONFIG_H_ */ diff --git a/base_c/test/atomic_test.cc b/base_c/test/atomic_test.cc new file mode 100755 index 0000000..243cdc1 --- /dev/null +++ b/base_c/test/atomic_test.cc @@ -0,0 +1,71 @@ +/* + * 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 + +namespace embb { +namespace base { +namespace test { + +AtomicTest::AtomicTest() { + CreateUnit("Initialization and destroy").Add(&AtomicTest::TestInitDestroy, this); + CreateUnit("AndAssign").Add(&AtomicTest::TestAndAssign, this); + CreateUnit("Load").Add(&AtomicTest::TestLoad, this); +} + +void AtomicTest::TestInitDestroy() { + embb_atomic_int var; + embb_atomic_init_int(&var, 1); + PT_EXPECT_EQ(var.internal_variable, 1); +#ifdef EMBB_THREADING_ANALYSIS_MODE + PT_EXPECT_EQ(var.init_flag, EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE); +#endif + + embb_atomic_destroy_int(&var); +#ifdef EMBB_THREADING_ANALYSIS_MODE + PT_EXPECT_NE(var.init_flag, EMBB_ATOMIC_INTERNAL_INITIALIZED_VALUE); +#endif +} + +void AtomicTest::TestAndAssign() { + embb_atomic_int var; + embb_atomic_init_int(&var, 1); + embb_atomic_and_assign_int(&var, 2); + PT_EXPECT_EQ(var.internal_variable, 3); + embb_atomic_destroy_int(&var); +} + +void AtomicTest::TestLoad() { + embb_atomic_int var; + embb_atomic_init_int(&var, 1); + int value = embb_atomic_load_int(&var); + PT_EXPECT_EQ(value, 1); +} + +} // namespace test +} // namespace base +} // namespace embb diff --git a/base_c/test/atomic_test.h b/base_c/test/atomic_test.h new file mode 100755 index 0000000..8c56c90 --- /dev/null +++ b/base_c/test/atomic_test.h @@ -0,0 +1,66 @@ +/* + * 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 BASE_C_TEST_ATOMIC_TEST_H_ +#define BASE_C_TEST_ATOMIC_TEST_H_ + +#include + +namespace embb { +namespace base { +namespace test { + +class AtomicTest : public partest::TestCase { + public: + /** + * Adds test methods. + */ + AtomicTest(); + + private: + /** + * Tests init and destroy methods. + */ + void TestInitDestroy(); + + /** + * Tests and_assign method. + */ + void TestAndAssign(); + + /** + * Tests load method. + */ + void TestLoad(); +}; + +} // namespace test +} // namespace base +} // namespace embb + + + +#endif // BASE_C_TEST_ATOMIC_TEST_H_ diff --git a/base_c/test/main.cc b/base_c/test/main.cc index 54ce031..0e1225c 100644 --- a/base_c/test/main.cc +++ b/base_c/test/main.cc @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -41,6 +42,7 @@ #include +using embb::base::test::AtomicTest; using embb::base::test::AllocTest; using embb::base::test::DurationTest; using embb::base::test::TimeTest; @@ -58,6 +60,7 @@ PT_MAIN("Base C") { static_cast(2 * partest::TestSuite::GetDefaultNumThreads()); embb_thread_set_max_count(max_threads); + PT_RUN(AtomicTest); PT_RUN(AllocTest); PT_RUN(DurationTest); PT_RUN(TimeTest); -- libgit2 0.26.0