diff --git a/.travis.yml b/.travis.yml index bcf3c95..1a2db19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, Siemens AG. All rights reserved. # SPDX-License-Identifier: BSD-2-Clause language: cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a0946d..75ccdd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,33 @@ -Embedded Multicore Building Blocks (EMB²) +Embedded Multicore Building Blocks (EMB²) ========================================= +Version 0.3.2 +------------- + +### Features: +- Added central spinlock implementation for C/C++ and removed existing (decentral) ones + +### Changes and improvements: +- Reworked and optimized hazard pointer implementation +- Adjusted interfaces of value pool and object pool +- Replaced C style casts + +### Bug fixes: +- Fixed ordering of destruction and deallocation in value pool +- Fixed potential use of uninitialized memory in WaitFreeArrayValuePool and LockFreeTreeValuePool + +### Build system: +- Given user the ability to append compiler flags +- Let Cmake return an error on Doxygen warnings when WARNINGS_ARE_ERRORS is enabled +- Fixed cpplint warnings + +### Documentation: +- Added mutex concept +- Corrected library ordering/names in README (section "Using the Library") +- Improved exception messages +- Fixed typos in condition_var_test.cc + + Version 0.3.1 ------------- diff --git a/CMakeCommon/CheckEnableTests.cmake b/CMakeCommon/CheckEnableTests.cmake index 7a28984..1a58ee2 100644 --- a/CMakeCommon/CheckEnableTests.cmake +++ b/CMakeCommon/CheckEnableTests.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/CMakeCommon/CopyInstallFiles.cmake b/CMakeCommon/CopyInstallFiles.cmake index 321b62e..1ecf6b7 100644 --- a/CMakeCommon/CopyInstallFiles.cmake +++ b/CMakeCommon/CopyInstallFiles.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/CMakeCommon/CreateDoxygenDocumentationTarget.cmake b/CMakeCommon/CreateDoxygenDocumentationTarget.cmake index 644f621..547a9b8 100644 --- a/CMakeCommon/CreateDoxygenDocumentationTarget.cmake +++ b/CMakeCommon/CreateDoxygenDocumentationTarget.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: @@ -40,13 +40,30 @@ function (CreateDoxygenDocumentationTarget) if (TARGET doxygen) # Do nothing, since the repeated adding causes an error else() - add_custom_target ( - doxygen - #ALL - COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile - SOURCES ${PROJECT_BINARY_DIR}/Doxyfile) - # IF you do NOT want the documentation to be generated EVERY time you build the project - # then leave out the 'ALL' keyword from the above command. + + FILE(WRITE ${CMAKE_BINARY_DIR}/doxygen_makefile.cmake " +MESSAGE(STATUS \"Running Doxygen\") +EXECUTE_PROCESS( +COMMAND \${EXE} \${IN} +ERROR_VARIABLE DOXYGEN_OUT_ERR +RESULT_VARIABLE DOXYGEN_OUT_RESULT) +STRING(LENGTH \"\${DOXYGEN_OUT_ERR}\" LENGTH_ERR) +IF ( NOT \${LENGTH_ERR} STREQUAL \"0\" ) + MESSAGE (WARNING \"Doxygen produced following warnings and or/errors: \${DOXYGEN_OUT_ERR}\") + IF ( \${WARNINGS_ARE_ERRORS} STREQUAL ON OR NOT \${DOXYGEN_OUT_RESULT} STREQUAL \"0\" ) + MESSAGE (FATAL_ERROR \"Exiting doxygen generation due to errors (or warnings, if WARNINGS_ARE_ERRORS is enabled)\") + ENDIF () +ENDIF () +") + + add_custom_target(doxygen) + add_custom_command( + TARGET doxygen + COMMAND ${CMAKE_COMMAND} + -DEXE=${DOXYGEN_EXECUTABLE} + -DIN=${PROJECT_BINARY_DIR}/Doxyfile + -DWARNINGS_ARE_ERRORS=${WARNINGS_ARE_ERRORS} + -P ${CMAKE_BINARY_DIR}/doxygen_makefile.cmake) endif() endif() endfunction() diff --git a/CMakeCommon/GroupSourcesMSVC.cmake b/CMakeCommon/GroupSourcesMSVC.cmake index e74470b..b16748b 100644 --- a/CMakeCommon/GroupSourcesMSVC.cmake +++ b/CMakeCommon/GroupSourcesMSVC.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/CMakeCommon/SetCompilerFlags.cmake b/CMakeCommon/SetCompilerFlags.cmake index dc07374..9e18728 100644 --- a/CMakeCommon/SetCompilerFlags.cmake +++ b/CMakeCommon/SetCompilerFlags.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: @@ -90,10 +90,19 @@ function(SetVisualStudioCompilerFlags) # Locally suppressed warnings (should not be globally suppressed): # 4640 -> Information that local static variable initialization is not # thread-safe. + # + # VS 2015 specific warnings: + # 5026 -> Move constructor was implicitly defined as deleted + # 5027 -> Move assignment operator was implicitly defined as deleted + # set(warning_flags "/Wall /wd4820 /wd4514 /wd4668 /wd4710 /wd4350 /wd4571 /wd4625 /wd4626 /wd4711 /wd4255") - if (WARNINGS_ARE_ERRORS STREQUAL ON) + if (WARNINGS_ARE_ERRORS STREQUAL ON) set(warning_flags "${warning_flags} /WX") - endif() + endif() + string(FIND "${CMAKE_GENERATOR}" "Visual Studio 14 2015" vs2015_state) + if (vs2015_state EQUAL 0) + set(warning_flags "${warning_flags} /wd5026 /wd5027") + endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warning_flags}" PARENT_SCOPE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${warning_flags}" PARENT_SCOPE) endif() diff --git a/CMakeCommon/SetInstallPaths.cmake b/CMakeCommon/SetInstallPaths.cmake index ae498bb..bd98c78 100644 --- a/CMakeCommon/SetInstallPaths.cmake +++ b/CMakeCommon/SetInstallPaths.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f43e85..048cb09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: @@ -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 1) +set (EMBB_BASE_VERSION_PATCH 2) # Fix compilation for CMake versions >= 3.1 # @@ -53,13 +53,9 @@ if(POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif(POLICY CMP0053) - -include(CMakeCommon/FindOpenCL.cmake) -IF(NOT OpenCL_FOUND) - MESSAGE( STATUS "OpenCL is not there, will build without MTAPI OpenCL Plugin." ) -ENDIF() - - +# give the user the possibility, to append compiler flags +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CMAKE_CXX_FLAGS}") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CMAKE_C_FLAGS}") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING @@ -86,6 +82,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(BUILD_OPENCL_PLUGIN "Specify whether the MTAPI OpenCL plugin should be built" OFF) ## LOCAL INSTALLATION OF SUBPROJECT BINARIES # @@ -144,7 +141,7 @@ set(EXPECTED_EMBB_TEST_EXECUTABLES "embb_algorithms_cpp_test" ) # if opencl is there, we also expect the mtapi opencl test to be generated -if(OpenCL_FOUND) +if(BUILD_OPENCL_PLUGIN STREQUAL ON) list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test") endif() @@ -179,9 +176,9 @@ CheckPartestInstall(${BUILD_TESTS} partest_includepath partest_libpath) add_subdirectory(base_c) add_subdirectory(base_cpp) add_subdirectory(mtapi_c) -add_subdirectory(mtapi_network_c) -if(OpenCL_FOUND) - add_subdirectory(mtapi_opencl_c) +add_subdirectory(mtapi_plugins_c/mtapi_network_c) +if(BUILD_OPENCL_PLUGIN STREQUAL ON) + add_subdirectory(mtapi_plugins_c/mtapi_opencl_c) endif() add_subdirectory(tasks_cpp) add_subdirectory(mtapi_cpp) diff --git a/COPYING.md b/COPYING.md index da45e32..3459f6f 100644 --- a/COPYING.md +++ b/COPYING.md @@ -1,4 +1,4 @@ -Embedded Multicore Building Blocks (EMB²) +Embedded Multicore Building Blocks (EMB²) ========================================= Overview @@ -13,7 +13,7 @@ license (see file include\embb\mtapi\c\mtapi.h). License ------- -Copyright (c) 2014-2015, Siemens AG. All rights reserved. +Copyright (c) 2014-2016, 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: diff --git a/README.md b/README.md index bf3b609..f829b34 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,8 @@ postfixed with either "_cpp" or "_c" for the C++ and C versions, respectively. Currently, EMB² contains the following components: - base: base_c, base_cpp - - mtapi: mtapi_c, mtapi_network_c, mtapi_opencl_c, mtapi_cpp + - mtapi: mtapi_c, mtapi_cpp and + mtapi_plugins_c (mtapi_network_c and mtapi_opencl_c) - tasks: tasks_cpp - algorithms: algorithms_cpp - dataflow: dataflow_cpp @@ -270,8 +271,8 @@ If you want to use the C++ functionalities of EMB², you have to link the following libraries (names will be different on Windows and on Linux) in the given order: - embb_base, embb_base_cpp, embb_mtapi_c, embb_mtapi_cpp, embb_containers_cpp, - embb_algorithms_cpp, embb_dataflow_cpp + embb_dataflow_cpp, embb_algorithms_cpp, embb_containers_cpp, + embb_mtapi_cpp, embb_mtapi_c, embb_base_cpp, embb_base_c The C++ header files can be included as follows: @@ -284,7 +285,7 @@ The C++ header files can be included as follows: The following libraries have to be linked in the given order: - embb_base_c, mtapi_c + embb_mtapi_c, embb_base_c The C header files can be included as follows: diff --git a/algorithms_cpp/include/embb/algorithms/algorithms.h b/algorithms_cpp/include/embb/algorithms/algorithms.h index a4df292..bac8709 100644 --- a/algorithms_cpp/include/embb/algorithms/algorithms.h +++ b/algorithms_cpp/include/embb/algorithms/algorithms.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/count.h b/algorithms_cpp/include/embb/algorithms/count.h index 73f5b31..6016687 100644 --- a/algorithms_cpp/include/embb/algorithms/count.h +++ b/algorithms_cpp/include/embb/algorithms/count.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/for_each.h b/algorithms_cpp/include/embb/algorithms/for_each.h index 23af854..54e57a0 100644 --- a/algorithms_cpp/include/embb/algorithms/for_each.h +++ b/algorithms_cpp/include/embb/algorithms/for_each.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/identity.h b/algorithms_cpp/include/embb/algorithms/identity.h index 26235ce..d2ae305 100644 --- a/algorithms_cpp/include/embb/algorithms/identity.h +++ b/algorithms_cpp/include/embb/algorithms/identity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/count-inl.h b/algorithms_cpp/include/embb/algorithms/internal/count-inl.h index 140fe51..dd11e38 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/count-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/count-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h b/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h index fb5dcd3..8a4457a 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h b/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h index 7cd2448..f278811 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h b/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h index 231ccb4..f1c2bca 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/partition.h b/algorithms_cpp/include/embb/algorithms/internal/partition.h index 400923d..948eb28 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/partition.h +++ b/algorithms_cpp/include/embb/algorithms/internal/partition.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h b/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h index 79a1241..e87927e 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h b/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h index bc15801..28c35ab 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h b/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h index cbf748e..b81022e 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/invoke.h b/algorithms_cpp/include/embb/algorithms/invoke.h index a3884a4..ced924f 100644 --- a/algorithms_cpp/include/embb/algorithms/invoke.h +++ b/algorithms_cpp/include/embb/algorithms/invoke.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/merge_sort.h b/algorithms_cpp/include/embb/algorithms/merge_sort.h index 6e94903..a09cc90 100644 --- a/algorithms_cpp/include/embb/algorithms/merge_sort.h +++ b/algorithms_cpp/include/embb/algorithms/merge_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/quick_sort.h b/algorithms_cpp/include/embb/algorithms/quick_sort.h index 80181d5..adefe09 100644 --- a/algorithms_cpp/include/embb/algorithms/quick_sort.h +++ b/algorithms_cpp/include/embb/algorithms/quick_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/reduce.h b/algorithms_cpp/include/embb/algorithms/reduce.h index 463e1b8..1cf5d86 100644 --- a/algorithms_cpp/include/embb/algorithms/reduce.h +++ b/algorithms_cpp/include/embb/algorithms/reduce.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/scan.h b/algorithms_cpp/include/embb/algorithms/scan.h index 8a32e91..11d1315 100644 --- a/algorithms_cpp/include/embb/algorithms/scan.h +++ b/algorithms_cpp/include/embb/algorithms/scan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/include/embb/algorithms/zip_iterator.h b/algorithms_cpp/include/embb/algorithms/zip_iterator.h index a3e033d..0de6ebf 100644 --- a/algorithms_cpp/include/embb/algorithms/zip_iterator.h +++ b/algorithms_cpp/include/embb/algorithms/zip_iterator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/src/dummy.cc b/algorithms_cpp/src/dummy.cc index 13566b9..f2ce3d4 100644 --- a/algorithms_cpp/src/dummy.cc +++ b/algorithms_cpp/src/dummy.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/count_test.cc b/algorithms_cpp/test/count_test.cc index 0ab2571..6678383 100644 --- a/algorithms_cpp/test/count_test.cc +++ b/algorithms_cpp/test/count_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/count_test.h b/algorithms_cpp/test/count_test.h index 95f2a32..55862c7 100644 --- a/algorithms_cpp/test/count_test.h +++ b/algorithms_cpp/test/count_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/for_each_test.cc b/algorithms_cpp/test/for_each_test.cc index df46122..b42179e 100644 --- a/algorithms_cpp/test/for_each_test.cc +++ b/algorithms_cpp/test/for_each_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/for_each_test.h b/algorithms_cpp/test/for_each_test.h index f768662..efe7875 100644 --- a/algorithms_cpp/test/for_each_test.h +++ b/algorithms_cpp/test/for_each_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/invoke_test.cc b/algorithms_cpp/test/invoke_test.cc index 1481747..2776ed3 100644 --- a/algorithms_cpp/test/invoke_test.cc +++ b/algorithms_cpp/test/invoke_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/invoke_test.h b/algorithms_cpp/test/invoke_test.h index e75ecc3..4679b26 100644 --- a/algorithms_cpp/test/invoke_test.h +++ b/algorithms_cpp/test/invoke_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/main.cc b/algorithms_cpp/test/main.cc index 1da1475..5ae28d5 100644 --- a/algorithms_cpp/test/main.cc +++ b/algorithms_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/merge_sort_test.cc b/algorithms_cpp/test/merge_sort_test.cc index c3fd3ee..43c9dc1 100644 --- a/algorithms_cpp/test/merge_sort_test.cc +++ b/algorithms_cpp/test/merge_sort_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/merge_sort_test.h b/algorithms_cpp/test/merge_sort_test.h index 7dbc8b0..45bc4dc 100644 --- a/algorithms_cpp/test/merge_sort_test.h +++ b/algorithms_cpp/test/merge_sort_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/partitioner_test.cc b/algorithms_cpp/test/partitioner_test.cc index d17cc77..2ce02c9 100644 --- a/algorithms_cpp/test/partitioner_test.cc +++ b/algorithms_cpp/test/partitioner_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/partitioner_test.h b/algorithms_cpp/test/partitioner_test.h index ecea402..31001bb 100644 --- a/algorithms_cpp/test/partitioner_test.h +++ b/algorithms_cpp/test/partitioner_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/quick_sort_test.cc b/algorithms_cpp/test/quick_sort_test.cc index 151b658..ef1faba 100644 --- a/algorithms_cpp/test/quick_sort_test.cc +++ b/algorithms_cpp/test/quick_sort_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/quick_sort_test.h b/algorithms_cpp/test/quick_sort_test.h index 1d2ef03..1523117 100644 --- a/algorithms_cpp/test/quick_sort_test.h +++ b/algorithms_cpp/test/quick_sort_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/reduce_test.cc b/algorithms_cpp/test/reduce_test.cc index 63d31be..cf66a0a 100644 --- a/algorithms_cpp/test/reduce_test.cc +++ b/algorithms_cpp/test/reduce_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/reduce_test.h b/algorithms_cpp/test/reduce_test.h index 50ab6ca..e2d8e13 100644 --- a/algorithms_cpp/test/reduce_test.h +++ b/algorithms_cpp/test/reduce_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/scan_test.cc b/algorithms_cpp/test/scan_test.cc index 61f85f5..ffab634 100644 --- a/algorithms_cpp/test/scan_test.cc +++ b/algorithms_cpp/test/scan_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/scan_test.h b/algorithms_cpp/test/scan_test.h index 553f8bc..44e66b5 100644 --- a/algorithms_cpp/test/scan_test.h +++ b/algorithms_cpp/test/scan_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/zip_iterator_test.cc b/algorithms_cpp/test/zip_iterator_test.cc index d345206..2e67e7c 100644 --- a/algorithms_cpp/test/zip_iterator_test.cc +++ b/algorithms_cpp/test/zip_iterator_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/algorithms_cpp/test/zip_iterator_test.h b/algorithms_cpp/test/zip_iterator_test.h index 56b4639..8764914 100644 --- a/algorithms_cpp/test/zip_iterator_test.h +++ b/algorithms_cpp/test/zip_iterator_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/atomic.h b/base_c/include/embb/base/c/atomic.h index b1bb9fb..fc33736 100644 --- a/base_c/include/embb/base/c/atomic.h +++ b/base_c/include/embb/base/c/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/base.h b/base_c/include/embb/base/c/base.h index 0251a43..bcc178a 100644 --- a/base_c/include/embb/base/c/base.h +++ b/base_c/include/embb/base/c/base.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/condition_variable.h b/base_c/include/embb/base/c/condition_variable.h index 86143cc..d707c2b 100644 --- a/base_c/include/embb/base/c/condition_variable.h +++ b/base_c/include/embb/base/c/condition_variable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/core_set.h b/base_c/include/embb/base/c/core_set.h index 0980fef..767a3dc 100644 --- a/base_c/include/embb/base/c/core_set.h +++ b/base_c/include/embb/base/c/core_set.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/counter.h b/base_c/include/embb/base/c/counter.h index 05536a2..e38a167 100644 --- a/base_c/include/embb/base/c/counter.h +++ b/base_c/include/embb/base/c/counter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/duration.h b/base_c/include/embb/base/c/duration.h index fe1b435..1af05db 100644 --- a/base_c/include/embb/base/c/duration.h +++ b/base_c/include/embb/base/c/duration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/errors.h b/base_c/include/embb/base/c/errors.h index 3276dfc..fef908b 100644 --- a/base_c/include/embb/base/c/errors.h +++ b/base_c/include/embb/base/c/errors.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: 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..48871ca 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/atomic_sizes.h.in b/base_c/include/embb/base/c/internal/atomic/atomic_sizes.h.in index 972239b..26a7528 100644 --- a/base_c/include/embb/base/c/internal/atomic/atomic_sizes.h.in +++ b/base_c/include/embb/base/c/internal/atomic/atomic_sizes.h.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: 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..4c35b1e 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -39,7 +39,7 @@ EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) \ typedef struct \ { \ - EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ + volatile EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ } EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX); EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char) diff --git a/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h b/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h index bf6c273..8de4e09 100644 --- a/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h +++ b/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h index 627c817..a165744 100644 --- a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h +++ b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/generate_atomic_implementation_template.h b/base_c/include/embb/base/c/internal/atomic/generate_atomic_implementation_template.h index 49a38f7..318b835 100644 --- a/base_c/include/embb/base/c/internal/atomic/generate_atomic_implementation_template.h +++ b/base_c/include/embb/base/c/internal/atomic/generate_atomic_implementation_template.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: 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..20094b5 100644 --- a/base_c/include/embb/base/c/internal/atomic/load.h +++ b/base_c/include/embb/base/c/internal/atomic/load.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/memory_barrier.h b/base_c/include/embb/base/c/internal/atomic/memory_barrier.h index a7e0966..392366f 100644 --- a/base_c/include/embb/base/c/internal/atomic/memory_barrier.h +++ b/base_c/include/embb/base/c/internal/atomic/memory_barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/or_assign.h b/base_c/include/embb/base/c/internal/atomic/or_assign.h index b492529..9c76cf8 100644 --- a/base_c/include/embb/base/c/internal/atomic/or_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/or_assign.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/store.h b/base_c/include/embb/base/c/internal/atomic/store.h index c139f2e..fdb6a40 100644 --- a/base_c/include/embb/base/c/internal/atomic/store.h +++ b/base_c/include/embb/base/c/internal/atomic/store.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/swap.h b/base_c/include/embb/base/c/internal/atomic/swap.h index 0c53f63..70c397c 100644 --- a/base_c/include/embb/base/c/internal/atomic/swap.h +++ b/base_c/include/embb/base/c/internal/atomic/swap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/atomic/xor_assign.h b/base_c/include/embb/base/c/internal/atomic/xor_assign.h index 823dee0..8de71fe 100644 --- a/base_c/include/embb/base/c/internal/atomic/xor_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/xor_assign.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/bitset.h b/base_c/include/embb/base/c/internal/bitset.h index b32e6c7..0dd7216 100644 --- a/base_c/include/embb/base/c/internal/bitset.h +++ b/base_c/include/embb/base/c/internal/bitset.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: 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..21b3048 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/config.h b/base_c/include/embb/base/c/internal/config.h index 3c34467..8a08174 100644 --- a/base_c/include/embb/base/c/internal/config.h +++ b/base_c/include/embb/base/c/internal/config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/macro_helper.h b/base_c/include/embb/base/c/internal/macro_helper.h index 857d71d..8d43d8c 100644 --- a/base_c/include/embb/base/c/internal/macro_helper.h +++ b/base_c/include/embb/base/c/internal/macro_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/platform.h b/base_c/include/embb/base/c/internal/platform.h index 7f025fc..5e21de6 100644 --- a/base_c/include/embb/base/c/internal/platform.h +++ b/base_c/include/embb/base/c/internal/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/thread_index.h b/base_c/include/embb/base/c/internal/thread_index.h index 0bda787..239b6e3 100644 --- a/base_c/include/embb/base/c/internal/thread_index.h +++ b/base_c/include/embb/base/c/internal/thread_index.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/internal/unused.h b/base_c/include/embb/base/c/internal/unused.h index 2109249..d68ff3a 100644 --- a/base_c/include/embb/base/c/internal/unused.h +++ b/base_c/include/embb/base/c/internal/unused.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/log.h b/base_c/include/embb/base/c/log.h index 68419c4..31c5128 100644 --- a/base_c/include/embb/base/c/log.h +++ b/base_c/include/embb/base/c/log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -28,6 +28,7 @@ #define EMBB_BASE_C_LOG_H_ #include +#include /** * \defgroup C_LOG Logging @@ -197,6 +198,13 @@ void embb_log_error( \c message */ ); +/* function for internal use only */ +void embb_log_write_internal( + char const * channel, + embb_log_level_t log_level, + char const * message, + va_list argp); + #ifdef __cplusplus } #endif diff --git a/base_c/include/embb/base/c/memory_allocation.h b/base_c/include/embb/base/c/memory_allocation.h index c9d797d..9f2d199 100644 --- a/base_c/include/embb/base/c/memory_allocation.h +++ b/base_c/include/embb/base/c/memory_allocation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/mutex.h b/base_c/include/embb/base/c/mutex.h index ffd2c7f..ebac1d6 100644 --- a/base_c/include/embb/base/c/mutex.h +++ b/base_c/include/embb/base/c/mutex.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -46,12 +46,25 @@ extern "C" { #include #include +#include #ifdef DOXYGEN /** * Opaque type representing a mutex. */ typedef opaque_type embb_mutex_t; + +/** + * Opaque type representing a spinlock. + */ +typedef opaque_type embb_spinlock_t; +#else +/** + * Spinlock type, treat as opaque. + */ +typedef struct { + embb_atomic_int atomic_spin_variable_; +} embb_spinlock_t; #endif /* DOXYGEN */ /** @@ -147,6 +160,89 @@ void embb_mutex_destroy( /**< [IN/OUT] Pointer to mutex */ ); +/** + * Initializes a spinlock + * + * \pre \c spinlock is uninitialized + * \post \c spinlock is initialized + * \return EMBB_SUCCESS if spinlock could be initialized \n + * EMBB_ERROR otherwise + * \memory (Potentially) allocates dynamic memory + * \notthreadsafe + * \see embb_spinlock_destroy() + */ +int embb_spin_init( + embb_spinlock_t* spinlock + /**< [OUT] Pointer to spinlock */ + ); + +/** + * Spins until the spinlock can be locked and locks it. + * + * \note This method yields the current thread in regular, + * implementation-defined intervals. + * + * \pre \c spinlock is initialized \n + * \post If successful, \c spinlock is locked. + * \return EMBB_SUCCESS if spinlock could be locked. \n + * EMBB_ERROR if an error occurred. + * \threadsafe + * \see embb_spinlock_try_lock(), embb_mutex_unlock() + */ +int embb_spin_lock( + embb_spinlock_t* spinlock + /**< [IN/OUT] Pointer to spinlock */ + ); + +/** + * Tries to lock the spinlock and returns if not successful. + * + * \pre \c spinlock is initialized + * \post If successful, \c spinlock is locked + * + * \return EMBB_SUCCESS if spinlock could be locked \n + * EMBB_BUSY if spinlock could not be locked \n + * EMBB_ERROR if an error occurred + * \threadsafe + * \see embb_spin_lock(), embb_spin_unlock() + */ +int embb_spin_try_lock( + embb_spinlock_t* spinlock, + /**< [IN/OUT] Pointer to spinlock */ + unsigned int max_number_spins + /**< [IN] Maximal count of spins to perform, trying to acquire lock. Note that + * passing 0 here results in not trying to obtain the lock at all. + */ + ); + +/** + * Unlocks a locked spinlock. + * + * \pre \c spinlock has been locked by the current thread. + * \post If successful, \c spinlock is unlocked. + * \return EMBB_SUCCESS if the operation was successful \n + * EMBB_ERROR otherwise + * \threadsafe + * \see embb_spin_lock(), embb_spin_try_lock() + */ +int embb_spin_unlock( + embb_spinlock_t* spinlock + /**< [IN/OUT] Pointer to spinlock */ + ); + +/** + * Destroys a spinlock and frees its resources. + * + * \pre \c spinlock has been initialized + * \post \c spinlock is uninitialized + * \notthreadsafe + * \see embb_spin_init() + */ +void embb_spin_destroy( + embb_spinlock_t* spinlock + /**< [IN/OUT] Pointer to spinlock */ + ); + #ifdef __cplusplus } /* Close extern "C" { */ #endif diff --git a/base_c/include/embb/base/c/thread.h b/base_c/include/embb/base/c/thread.h index 0e9efd2..1d7ea11 100644 --- a/base_c/include/embb/base/c/thread.h +++ b/base_c/include/embb/base/c/thread.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/thread_specific_storage.h b/base_c/include/embb/base/c/thread_specific_storage.h index 3b70bed..31ef36a 100644 --- a/base_c/include/embb/base/c/thread_specific_storage.h +++ b/base_c/include/embb/base/c/thread_specific_storage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/include/embb/base/c/time.h b/base_c/include/embb/base/c/time.h index a220ce7..3316253 100644 --- a/base_c/include/embb/base/c/time.h +++ b/base_c/include/embb/base/c/time.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/atomic.c b/base_c/src/atomic.c index e21603e..e8ea812 100644 --- a/base_c/src/atomic.c +++ b/base_c/src/atomic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/condition_variable.c b/base_c/src/condition_variable.c index 575bb33..14ca240 100644 --- a/base_c/src/condition_variable.c +++ b/base_c/src/condition_variable.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/core_set.c b/base_c/src/core_set.c index aa142f3..3500a59 100644 --- a/base_c/src/core_set.c +++ b/base_c/src/core_set.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/counter.c b/base_c/src/counter.c index d71eb4d..ef16ea8 100644 --- a/base_c/src/counter.c +++ b/base_c/src/counter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/duration.c b/base_c/src/duration.c index 8db8c7c..fd16a02 100644 --- a/base_c/src/duration.c +++ b/base_c/src/duration.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/internal/thread_index.c b/base_c/src/internal/thread_index.c index 80f6d1f..b4c1a75 100644 --- a/base_c/src/internal/thread_index.c +++ b/base_c/src/internal/thread_index.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -128,6 +128,20 @@ void embb_internal_thread_index_set_max(unsigned int max) { *embb_max_number_thread_indices() = max; } +/** + * \pre the calling thread is the only active thread + * + * \post the thread indices count and calling thread index is reset + */ void embb_internal_thread_index_reset() { + /** This function is only called in tests, usually when all other threads + * except the main thread have terminated. However, the main thread still has + * potentially stored its old index value in its thread local storage, + * which might be assigned additionally to another thread (as the counter is + * reset), which may lead to hard to detect bugs. Therefore, reset the thread + * local thread id here. + */ + embb_internal_thread_index_var = UINT_MAX; + embb_counter_init(embb_thread_index_counter()); } diff --git a/base_c/src/log.c b/base_c/src/log.c index c544947..a622275 100644 --- a/base_c/src/log.c +++ b/base_c/src/log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -59,7 +59,7 @@ void embb_log_set_log_function( embb_log_global_log_function = func; } -static void embb_log_write_internal( +void embb_log_write_internal( char const * channel, embb_log_level_t log_level, char const * message, @@ -75,18 +75,20 @@ static void embb_log_write_internal( log_context = (void*)stdout; } switch (log_level) { - case EMBB_LOG_LEVEL_INFO: - log_level_str = "INFO "; - break; case EMBB_LOG_LEVEL_ERROR: log_level_str = "ERROR"; break; + case EMBB_LOG_LEVEL_WARNING: + log_level_str = "WARN "; + break; + case EMBB_LOG_LEVEL_INFO: + log_level_str = "INFO "; + break; case EMBB_LOG_LEVEL_TRACE: log_level_str = "TRACE"; break; case EMBB_LOG_LEVEL_NONE: - case EMBB_LOG_LEVEL_WARNING: default: log_level_str = " "; break; diff --git a/base_c/src/memory_allocation.c b/base_c/src/memory_allocation.c index e1462db..8977240 100644 --- a/base_c/src/memory_allocation.c +++ b/base_c/src/memory_allocation.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/mutex.c b/base_c/src/mutex.c index cd32696..7b9a0f5 100644 --- a/base_c/src/mutex.c +++ b/base_c/src/mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -25,6 +25,7 @@ */ #include +#include #include #include @@ -115,3 +116,59 @@ void embb_mutex_destroy(embb_mutex_t* mutex) { } #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */ + +int embb_spin_init(embb_spinlock_t* spinlock) { + // For now, store the initial value. In the future will use atomic init + // function (as soon as available). + embb_atomic_store_int(&spinlock->atomic_spin_variable_, 0); + return EMBB_SUCCESS; +} + +int embb_spin_lock(embb_spinlock_t* spinlock) { + int expected = 0; + int spins = 1; + + // try to swap the + while (0 == embb_atomic_compare_and_swap_int( + &spinlock->atomic_spin_variable_, &expected, 1)) { + if (0 == (spins & 1023)) { + embb_thread_yield(); + } + spins++; + // reset expected, as CAS might change it... + expected = 0; + } + return EMBB_SUCCESS; +} + +int embb_spin_try_lock(embb_spinlock_t* spinlock, + unsigned int max_number_spins) { + if (max_number_spins == 0) + return EMBB_BUSY; + + int expected = 0; + while (0 == embb_atomic_compare_and_swap_int( + &spinlock->atomic_spin_variable_, + &expected, 1)) { + max_number_spins--; + if (0 == max_number_spins) { + return EMBB_BUSY; + } + expected = 0; + } + + return EMBB_SUCCESS; +} + +int embb_spin_unlock(embb_spinlock_t* spinlock) { + int expected = 1; + return embb_atomic_compare_and_swap_int(&spinlock->atomic_spin_variable_, + &expected, 0) ? + EMBB_SUCCESS : EMBB_ERROR; +} + +void embb_spin_destroy(embb_spinlock_t* spinlock) { + // for now, doing nothing here... in future, will call the respective + // destroy function for atomics... + EMBB_UNUSED(spinlock); +} diff --git a/base_c/src/thread.c b/base_c/src/thread.c index e7abb40..92f8bfc 100644 --- a/base_c/src/thread.c +++ b/base_c/src/thread.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/thread_specific_storage.c b/base_c/src/thread_specific_storage.c index fea5d18..f27e828 100644 --- a/base_c/src/thread_specific_storage.c +++ b/base_c/src/thread_specific_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/src/time.c b/base_c/src/time.c index bc92363..9a07727 100644 --- a/base_c/src/time.c +++ b/base_c/src/time.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/alloc_test.cc b/base_c/test/alloc_test.cc index 3ddaf4a..840c514 100644 --- a/base_c/test/alloc_test.cc +++ b/base_c/test/alloc_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/alloc_test.h b/base_c/test/alloc_test.h index b83c8bf..62ad953 100644 --- a/base_c/test/alloc_test.h +++ b/base_c/test/alloc_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/condition_var_test.cc b/base_c/test/condition_var_test.cc index 3a526d2..8688f1b 100644 --- a/base_c/test/condition_var_test.cc +++ b/base_c/test/condition_var_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/condition_var_test.h b/base_c/test/condition_var_test.h index 23b56be..4224074 100644 --- a/base_c/test/condition_var_test.h +++ b/base_c/test/condition_var_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/core_set_test.cc b/base_c/test/core_set_test.cc index 38e8e39..f8ab25b 100644 --- a/base_c/test/core_set_test.cc +++ b/base_c/test/core_set_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/core_set_test.h b/base_c/test/core_set_test.h index 1c6dbfb..33e5996 100644 --- a/base_c/test/core_set_test.h +++ b/base_c/test/core_set_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/counter_test.cc b/base_c/test/counter_test.cc index e6b9950..2cba520 100644 --- a/base_c/test/counter_test.cc +++ b/base_c/test/counter_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/counter_test.h b/base_c/test/counter_test.h index cf3297b..9f14bfa 100644 --- a/base_c/test/counter_test.h +++ b/base_c/test/counter_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/duration_test.cc b/base_c/test/duration_test.cc index 9b93ce3..675ad68 100644 --- a/base_c/test/duration_test.cc +++ b/base_c/test/duration_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/duration_test.h b/base_c/test/duration_test.h index d2a7d2f..73aca64 100644 --- a/base_c/test/duration_test.h +++ b/base_c/test/duration_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/main.cc b/base_c/test/main.cc index 54ce031..ad864c8 100644 --- a/base_c/test/main.cc +++ b/base_c/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -46,6 +46,7 @@ using embb::base::test::DurationTest; using embb::base::test::TimeTest; using embb::base::test::CounterTest; using embb::base::test::MutexTest; +using embb::base::test::SpinLockTest; using embb::base::test::ThreadIndexTest; using embb::base::test::CoreSetTest; using embb::base::test::ConditionVarTest; @@ -63,11 +64,11 @@ PT_MAIN("Base C") { PT_RUN(TimeTest); PT_RUN(CounterTest); PT_RUN(MutexTest); + PT_RUN(SpinLockTest); PT_RUN(ThreadIndexTest); PT_RUN(CoreSetTest); PT_RUN(ConditionVarTest); PT_RUN(ThreadTest); PT_RUN(ThreadSpecificStorageTest); - PT_EXPECT(embb_get_bytes_allocated() == 0); } diff --git a/base_c/test/mutex_test.cc b/base_c/test/mutex_test.cc index ab2be92..ed970df 100644 --- a/base_c/test/mutex_test.cc +++ b/base_c/test/mutex_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -76,6 +76,77 @@ void MutexTest::TestRecursiveMutex() { embb_mutex_destroy(&mutex); } +SpinLockTest::SpinLockTest() : counter_(0), +number_threads_(partest::TestSuite::GetDefaultNumThreads()), + number_iterations_(partest::TestSuite::GetDefaultNumIterations()), + counter_iterations_(10000) { + CreateUnit("Protected counter using Lock") + .Pre(&SpinLockTest::PreSpinLockInc, this) + .Add(&SpinLockTest::TestSpinLockIncUseLock, this, + number_threads_, + number_iterations_) + .Post(&SpinLockTest::PostSpinLockInc, this); + + CreateUnit("Protected counter using TryLock") + .Pre(&SpinLockTest::PreSpinLockInc, this) + .Add(&SpinLockTest::TestSpinLockIncUseTryLock, this, + number_threads_, + number_iterations_) + .Post(&SpinLockTest::PostSpinLockInc, this); + + CreateUnit("Test spinning (too many spins), single thread") + .Add(&SpinLockTest::TestSpinLockTooManySpins, this, + // one thread + 1, + // one iteration + 1); +} + +void SpinLockTest::TestSpinLockTooManySpins() { + embb_spin_init(&spinlock_); + embb_spin_lock(&spinlock_); + + int return_code = embb_spin_try_lock(&spinlock_, 100); + PT_ASSERT(return_code == EMBB_BUSY); + + embb_spin_unlock(&spinlock_); + + return_code = embb_spin_try_lock(&spinlock_, 100); + PT_ASSERT(return_code == EMBB_SUCCESS); + + embb_spin_unlock(&spinlock_); + + embb_spin_destroy(&spinlock_); +} + +void SpinLockTest::PreSpinLockInc() { + embb_spin_init(&spinlock_); +} + +void SpinLockTest::TestSpinLockIncUseLock() { + for (unsigned int i = 0; i != counter_iterations_; ++i) { + embb_spin_lock(&spinlock_); + counter_++; + embb_spin_unlock(&spinlock_); + } +} + +void SpinLockTest::TestSpinLockIncUseTryLock() { + for (unsigned int i = 0; i != counter_iterations_; ++i) { + while (embb_spin_try_lock(&spinlock_, 100) != EMBB_SUCCESS) {} + counter_++; + embb_spin_unlock(&spinlock_); + } +} + +void SpinLockTest::PostSpinLockInc() { + embb_spin_destroy(&spinlock_); + PT_EXPECT_EQ(counter_, number_iterations_ * + number_threads_* + counter_iterations_); + counter_ = 0; +} + } // namespace test } // namespace base } // namespace embb diff --git a/base_c/test/mutex_test.h b/base_c/test/mutex_test.h index 012df6f..b049933 100644 --- a/base_c/test/mutex_test.h +++ b/base_c/test/mutex_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -85,6 +85,64 @@ class MutexTest : public partest::TestCase { size_t number_iterations_; }; + +class SpinLockTest : public partest::TestCase { + public: + SpinLockTest(); + + private: + /** + * Check that the try lock fails, when lock is already set. + */ + void TestSpinLockTooManySpins(); + + /** + * Prepares TestMutexIncCpp. + */ + void PreSpinLockInc(); + + /** + * Tests mutex locking and unlocking to protect shared counter. + */ + void TestSpinLockIncUseLock(); + + /** + * Tests mutex locking and unlocking to protect shared counter using trylock. + */ + void TestSpinLockIncUseTryLock(); + + /** + * Checks and tears down TestMutexIncCpp. + */ + void PostSpinLockInc(); + + /** + * Shared counter to check effectiveness of mutex. + */ + size_t counter_; + + /** + * Number of threads used to run tests. + */ + size_t number_threads_; + + /** + * Number of times the test method is called by each thread. + */ + size_t number_iterations_; + + /** + * Number of internal iterations, for incrementing the counter. + */ + size_t counter_iterations_; + + /** + * The used spinlock + */ + embb_spinlock_t spinlock_; +}; + + } // namespace test } // namespace base } // namespace embb diff --git a/base_c/test/thread_index_test.cc b/base_c/test/thread_index_test.cc index 1dd5c13..baf2f75 100644 --- a/base_c/test/thread_index_test.cc +++ b/base_c/test/thread_index_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/thread_index_test.h b/base_c/test/thread_index_test.h index 1f07630..3452a41 100644 --- a/base_c/test/thread_index_test.h +++ b/base_c/test/thread_index_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/thread_specific_storage_test.cc b/base_c/test/thread_specific_storage_test.cc index 50e7b0c..3033e29 100644 --- a/base_c/test/thread_specific_storage_test.cc +++ b/base_c/test/thread_specific_storage_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/thread_specific_storage_test.h b/base_c/test/thread_specific_storage_test.h index 1d77e3e..ac2c7df 100644 --- a/base_c/test/thread_specific_storage_test.h +++ b/base_c/test/thread_specific_storage_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/thread_test.cc b/base_c/test/thread_test.cc index 6308f78..f5af851 100644 --- a/base_c/test/thread_test.cc +++ b/base_c/test/thread_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/thread_test.h b/base_c/test/thread_test.h index 6cdd684..149a489 100644 --- a/base_c/test/thread_test.h +++ b/base_c/test/thread_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/time_test.cc b/base_c/test/time_test.cc index 9797350..7b1b63e 100644 --- a/base_c/test/time_test.cc +++ b/base_c/test/time_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_c/test/time_test.h b/base_c/test/time_test.h index 419d26d..0cf3b84 100644 --- a/base_c/test/time_test.h +++ b/base_c/test/time_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/atomic.h b/base_cpp/include/embb/base/atomic.h index d39f494..2d00b86 100644 --- a/base_cpp/include/embb/base/atomic.h +++ b/base_cpp/include/embb/base/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -62,7 +62,7 @@ class Atomic { /** * Default constructor. * - * Constructs an atomic variable holding an uninitialized value. + * Constructs an atomic variable holding zero. * * \waitfree * diff --git a/base_cpp/include/embb/base/base.h b/base_cpp/include/embb/base/base.h index bf7e903..9bde979 100644 --- a/base_cpp/include/embb/base/base.h +++ b/base_cpp/include/embb/base/base.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/condition_variable.h b/base_cpp/include/embb/base/condition_variable.h index 8f72e5e..50dd37a 100644 --- a/base_cpp/include/embb/base/condition_variable.h +++ b/base_cpp/include/embb/base/condition_variable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/core_set.h b/base_cpp/include/embb/base/core_set.h index 9682c0d..82599ac 100644 --- a/base_cpp/include/embb/base/core_set.h +++ b/base_cpp/include/embb/base/core_set.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/duration.h b/base_cpp/include/embb/base/duration.h index 4dbc4e4..dd66468 100644 --- a/base_cpp/include/embb/base/duration.h +++ b/base_cpp/include/embb/base/duration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/exceptions.h b/base_cpp/include/embb/base/exceptions.h index abcc09d..9beb684 100644 --- a/base_cpp/include/embb/base/exceptions.h +++ b/base_cpp/include/embb/base/exceptions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/function.h b/base_cpp/include/embb/base/function.h index 0abad4e..58aef0d 100644 --- a/base_cpp/include/embb/base/function.h +++ b/base_cpp/include/embb/base/function.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_arithmetic.h b/base_cpp/include/embb/base/internal/atomic/atomic_arithmetic.h index 2709dca..f9cdd25 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_arithmetic.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_arithmetic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_base.h b/base_cpp/include/embb/base/internal/atomic/atomic_base.h index 1be01e5..bfa3dd6 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_base.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_base.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_implementation.h b/base_cpp/include/embb/base/internal/atomic/atomic_implementation.h index c877564..0367be7 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_implementation.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_implementation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_integer.h b/base_cpp/include/embb/base/internal/atomic/atomic_integer.h index 2c1476c..c609bd9 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_integer.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_integer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_pointer.h b/base_cpp/include/embb/base/internal/atomic/atomic_pointer.h index a689054..5a5bcae 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_pointer.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_pointer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/atomic/atomic_utility.h b/base_cpp/include/embb/base/internal/atomic/atomic_utility.h index b8051ee..89f08c9 100644 --- a/base_cpp/include/embb/base/internal/atomic/atomic_utility.h +++ b/base_cpp/include/embb/base/internal/atomic/atomic_utility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/cmake_config.h.in b/base_cpp/include/embb/base/internal/cmake_config.h.in index 0c6d975..02226f6 100644 --- a/base_cpp/include/embb/base/internal/cmake_config.h.in +++ b/base_cpp/include/embb/base/internal/cmake_config.h.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/condition_variable-inl.h b/base_cpp/include/embb/base/internal/condition_variable-inl.h index 25b65aa..97f4caf 100644 --- a/base_cpp/include/embb/base/internal/condition_variable-inl.h +++ b/base_cpp/include/embb/base/internal/condition_variable-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/config.h b/base_cpp/include/embb/base/internal/config.h index ceddb94..ffab0c2 100644 --- a/base_cpp/include/embb/base/internal/config.h +++ b/base_cpp/include/embb/base/internal/config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/duration-inl.h b/base_cpp/include/embb/base/internal/duration-inl.h index 2d502fd..982fcb7 100644 --- a/base_cpp/include/embb/base/internal/duration-inl.h +++ b/base_cpp/include/embb/base/internal/duration-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function0.h b/base_cpp/include/embb/base/internal/function0.h index 99f9ff2..396c7da 100644 --- a/base_cpp/include/embb/base/internal/function0.h +++ b/base_cpp/include/embb/base/internal/function0.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function1.h b/base_cpp/include/embb/base/internal/function1.h index 4951140..b880d86 100644 --- a/base_cpp/include/embb/base/internal/function1.h +++ b/base_cpp/include/embb/base/internal/function1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function2.h b/base_cpp/include/embb/base/internal/function2.h index 079b663..3b9f9ba 100644 --- a/base_cpp/include/embb/base/internal/function2.h +++ b/base_cpp/include/embb/base/internal/function2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function3.h b/base_cpp/include/embb/base/internal/function3.h index 343001b..545feca 100644 --- a/base_cpp/include/embb/base/internal/function3.h +++ b/base_cpp/include/embb/base/internal/function3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function4.h b/base_cpp/include/embb/base/internal/function4.h index 67de1d2..22415e5 100644 --- a/base_cpp/include/embb/base/internal/function4.h +++ b/base_cpp/include/embb/base/internal/function4.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/function5.h b/base_cpp/include/embb/base/internal/function5.h index c6ad05f..3221e57 100644 --- a/base_cpp/include/embb/base/internal/function5.h +++ b/base_cpp/include/embb/base/internal/function5.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/functionT.h b/base_cpp/include/embb/base/internal/functionT.h index 0c80b6b..9935cb7 100644 --- a/base_cpp/include/embb/base/internal/functionT.h +++ b/base_cpp/include/embb/base/internal/functionT.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/memory_allocation-inl.h b/base_cpp/include/embb/base/internal/memory_allocation-inl.h index 3f6f6cb..7565bc4 100644 --- a/base_cpp/include/embb/base/internal/memory_allocation-inl.h +++ b/base_cpp/include/embb/base/internal/memory_allocation-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/mutex-inl.h b/base_cpp/include/embb/base/internal/mutex-inl.h index 86f66ac..ffdbf12 100644 --- a/base_cpp/include/embb/base/internal/mutex-inl.h +++ b/base_cpp/include/embb/base/internal/mutex-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -114,6 +114,8 @@ bool UniqueLock::OwnsLock() const { return locked_; } + + } // namespace base } // namespace embb diff --git a/base_cpp/include/embb/base/internal/nil.h b/base_cpp/include/embb/base/internal/nil.h index 5d46990..36503c0 100644 --- a/base_cpp/include/embb/base/internal/nil.h +++ b/base_cpp/include/embb/base/internal/nil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/platform.h b/base_cpp/include/embb/base/internal/platform.h index 6258563..65b82f1 100644 --- a/base_cpp/include/embb/base/internal/platform.h +++ b/base_cpp/include/embb/base/internal/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/thread-inl.h b/base_cpp/include/embb/base/internal/thread-inl.h index 454f75a..8c856f0 100644 --- a/base_cpp/include/embb/base/internal/thread-inl.h +++ b/base_cpp/include/embb/base/internal/thread-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/thread_closures.h b/base_cpp/include/embb/base/internal/thread_closures.h index 03273ac..9de9d72 100644 --- a/base_cpp/include/embb/base/internal/thread_closures.h +++ b/base_cpp/include/embb/base/internal/thread_closures.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/internal/thread_specific_storage-inl.h b/base_cpp/include/embb/base/internal/thread_specific_storage-inl.h index 00b81c3..e142aee 100644 --- a/base_cpp/include/embb/base/internal/thread_specific_storage-inl.h +++ b/base_cpp/include/embb/base/internal/thread_specific_storage-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/log.h b/base_cpp/include/embb/base/log.h new file mode 100644 index 0000000..275e95a --- /dev/null +++ b/base_cpp/include/embb/base/log.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014-2016, 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_LOG_H_ +#define EMBB_BASE_LOG_H_ + +#include + +/** + * \defgroup CPP_LOG Logging + * \ingroup CPP_BASE + * Simple logging facilities. + */ + +namespace embb { +namespace base { + +/** + * Simple logging facilities. + * + * \ingroup CPP_LOG + */ +class Log { + private: + // do not allow construction + Log(); + + public: + /** + * Sets the global log level. + * This determines what messages will be shown, messages with a more detailed + * log level will be filtered out. The default log level is EMBB_LOG_LEVEL_NONE. + * \notthreadsafe + */ + static void SetLogLevel( + embb_log_level_t log_level /**< [in] Log level to use for + filtering */ + ); + + /** + * Sets the global logging function. + * The logging function implements the mechanism for transferring log messages + * to their destination. \c context is a pointer to data the user needs in the + * function to determine where the messages should go (may be NULL if no + * additional data is needed). The default logging function is + * embb_log_write_file() with context set to \c stdout. + * \see embb_log_function_t + * \notthreadsafe + */ + static void SetLogFunction( + void * context, /**< [in] User context to supply as the + first parameter of the logging + function*/ + embb_log_function_t func /**< [in] The logging function */ + ); + + /** + * Logs a message to the given channel with the specified log level. + * If the log level is greater than the configured log level for the channel, + * the message will be ignored. + * \see embb::base::Log::SetLogLevel, embb::base::Log::SetLogFunction + * \threadsafe + */ + static void Write( + char const * channel, /**< [in] User specified channel id + for filtering the log later on. + Might be NULL, channel identifier + will be "global" in that case */ + embb_log_level_t log_level, /**< [in] Log level to use */ + char const * message, /**< [in] Message to convey, may use + \c printf style formatting */ + ... /**< Additional parameters determined + by the format specifiers in + \c message */ + ); + + /** + * Logs a message to the given channel with EMBB_LOG_LEVEL_TRACE. + * In non-debug builds, this function does nothing. + * \see embb::base::Log::Write + * \threadsafe + */ + static void Trace( + char const * channel, /**< [in] User specified channel id */ + char const * message, /**< [in] Message to convey, may use + \c printf style formatting */ + ... /**< Additional parameters determined + by the format specifiers in + \c message */ + ); + + /** + * Logs a message to the given channel with EMBB_LOG_LEVEL_INFO. + * In non-debug builds, this function does nothing. + * \see embb::base::Log::Write + * \threadsafe + */ + static void Info( + char const * channel, /**< [in] User specified channel id */ + char const * message, /**< [in] Message to convey, may use + \c printf style formatting */ + ... /**< Additional parameters determined + by the format specifiers in + \c message */ + ); + + /** + * Logs a message to the given channel with EMBB_LOG_LEVEL_WARNING. + * \see embb::base::Log::Write + * \threadsafe + */ + static void Warning( + char const * channel, /**< [in] User specified channel id */ + char const * message, /**< [in] Message to convey, may use + \c printf style formatting */ + ... /**< Additional parameters determined + by the format specifiers in + \c message */ + ); + + /** + * Logs a message to the given channel with EMBB_LOG_LEVEL_ERROR. + * \see embb::base::Log::Write + * \threadsafe + */ + static void Error( + char const * channel, /**< [in] User specified channel id */ + char const * message, /**< [in] Message to convey, may use + \c printf style formatting */ + ... /**< Additional parameters determined + by the format specifiers in + \c message */ + ); +}; + +} // namespace base +} // namespace embb + +#endif // EMBB_BASE_LOG_H_ diff --git a/base_cpp/include/embb/base/memory_allocation.h b/base_cpp/include/embb/base/memory_allocation.h index 0eb03b7..7b415a3 100644 --- a/base_cpp/include/embb/base/memory_allocation.h +++ b/base_cpp/include/embb/base/memory_allocation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/mutex.h b/base_cpp/include/embb/base/mutex.h index 1d63027..bae49d6 100644 --- a/base_cpp/include/embb/base/mutex.h +++ b/base_cpp/include/embb/base/mutex.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -29,9 +29,63 @@ #include #include +#include namespace embb { namespace base { +/** + * \defgroup CPP_CONCEPTS_MUTEX Mutex Concept + * + * \brief Concept for thread synchronization. + * + * \anchor CPP_CONCEPTS_MUTEX_ANCHOR + * + * \ingroup CPP_CONCEPT + * \{ + * \par Description + * + 12345678901234567890123456789012345678901234567890123456789012345678901234567890 + * The mutex concept is used for thread synchronization and provides a lock. + * At any point in time, only one thread can exclusively hold the lock and + * the lock is held until the thread explicitly releases it. + * + * \par Requirements + * - Let \c Mutex be the mutex type + * - Let \c m be an object of type \c Mutex. + * + * \par Valid Expressions + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ExpressionReturn typeDescription
Mutex()\c voidConstructs a mutex.
m.TryLock()\c boolTries to lock the mutex and immediately returns. Returns \c false, if + * the mutex could not be acquired (locked), otherwise \c true. + *
m.Lock()\c voidLocks the mutex. When the mutex is already locked, the current thread + * is blocked until the mutex is unlocked.
m.Unlock()\c voidUnlocks the mutex.
+ * \} + */ /** * \defgroup CPP_BASE_MUTEX Mutex and Lock @@ -47,7 +101,6 @@ namespace base { class ConditionVariable; namespace internal { - /** * Provides main functionality for mutexes. */ @@ -111,10 +164,85 @@ class MutexBase { */ friend class embb::base::ConditionVariable; }; - } // namespace internal /** + * Spinlock + * + * \concept{CPP_CONCEPTS_MUTEX} + * + * \ingroup CPP_BASE_MUTEX + */ +class Spinlock { + public: + /** + * Creates a spinlock which is in unlocked state. + * + * \notthreadsafe + */ + Spinlock(); + + /** + * Destructs a spinlock. + * + * \notthreadsafe + */ + ~Spinlock(); + + /** + * Waits until the spinlock can be locked and locks it. + * + * \note This method yields the current thread in regular, + * implementation-defined intervals. + * + * \pre The spinlock is not locked by the current thread. + * \post The spinlock is locked. + * \threadsafe + * \see TryLock(), Unlock() + */ + void Lock(); + + /** + * Tries to lock the spinlock for \c number_spins times and returns. + * + * \pre The spinlock is not locked by the current thread. + * \post If successful, the spinlock is locked. + * \return \c true if the spinlock could be locked, otherwise \c false. + * \threadsafe + * \see Lock(), Unlock() + */ + bool TryLock( + unsigned int number_spins = 1 + /**< [IN] Maximal number of spins when trying to acquire the lock. + * Note that passing 0 here results in not trying to obtain the lock at all. + * The default parameter is 1. + */ + ); + + /** + * Unlocks the spinlock. + * + * \pre The spinlock is locked by the current thread. + * \post The spinlock is unlocked. + * \threadsafe + * \see Lock(), TryLock() + */ + void Unlock(); + + private: + /** + * Disables copy construction and assignment. + */ + Spinlock(const Spinlock&); + Spinlock& operator=(const Spinlock&); + + /** + * Internal spinlock from base_c + */ + embb_spinlock_t spinlock_; +}; + +/** * Non-recursive, exclusive mutex. * * Mutexes of this type cannot be locked recursively, that is, multiple times @@ -123,6 +251,8 @@ class MutexBase { * * \see RecursiveMutex * \ingroup CPP_BASE_MUTEX + * + * \concept{CPP_CONCEPTS_MUTEX} */ class Mutex : public internal::MutexBase { public: @@ -182,7 +312,6 @@ class Mutex : public internal::MutexBase { friend class ConditionVariable; }; - /** * Recursive, exclusive mutex. * @@ -193,6 +322,8 @@ class Mutex : public internal::MutexBase { * * \see Mutex * \ingroup CPP_BASE_MUTEX + * + * \concept{CPP_CONCEPTS_MUTEX} */ class RecursiveMutex : public internal::MutexBase { public: @@ -246,15 +377,16 @@ class RecursiveMutex : public internal::MutexBase { RecursiveMutex& operator=(const RecursiveMutex&); }; - /** * Scoped lock (according to the RAII principle) using a mutex. * * The mutex is locked on construction and unlocked on leaving the scope of the * lock. * - * \tparam Mutex Used mutex type - * \see Mutex, UniqueLock + * \tparam Mutex Used mutex type. Has to fulfil the + * \ref CPP_CONCEPTS_MUTEX_ANCHOR "Mutex Concept". + * + * \see UniqueLock * \ingroup CPP_BASE_MUTEX */ template @@ -352,7 +484,8 @@ const AdoptLockTag adopt_lock = AdoptLockTag(); * * \notthreadsafe * \see Mutex, LockGuard - * \tparam Mutex Used mutex type + * \tparam Mutex Used mutex type. Has to fulfil the + * \ref CPP_CONCEPTS_MUTEX_ANCHOR "Mutex Concept". * \ingroup CPP_BASE_MUTEX */ template @@ -482,7 +615,6 @@ class UniqueLock { */ friend class embb::base::ConditionVariable; }; - } // namespace base } // namespace embb diff --git a/base_cpp/include/embb/base/thread.h b/base_cpp/include/embb/base/thread.h index a2278ea..10fe983 100644 --- a/base_cpp/include/embb/base/thread.h +++ b/base_cpp/include/embb/base/thread.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/thread_specific_storage.h b/base_cpp/include/embb/base/thread_specific_storage.h index fa2191e..1f07996 100644 --- a/base_cpp/include/embb/base/thread_specific_storage.h +++ b/base_cpp/include/embb/base/thread_specific_storage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/include/embb/base/time.h b/base_cpp/include/embb/base/time.h index 06f9ee8..f942588 100644 --- a/base_cpp/include/embb/base/time.h +++ b/base_cpp/include/embb/base/time.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/condition_variable.cc b/base_cpp/src/condition_variable.cc index 9a6a2a8..8124d2e 100644 --- a/base_cpp/src/condition_variable.cc +++ b/base_cpp/src/condition_variable.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/core_set.cc b/base_cpp/src/core_set.cc index eb7ce6b..751a373 100644 --- a/base_cpp/src/core_set.cc +++ b/base_cpp/src/core_set.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/duration.cc b/base_cpp/src/duration.cc index efc493f..2870ef8 100644 --- a/base_cpp/src/duration.cc +++ b/base_cpp/src/duration.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/function.cc b/base_cpp/src/function.cc index 118035a..3eea841 100644 --- a/base_cpp/src/function.cc +++ b/base_cpp/src/function.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/functionN.lua b/base_cpp/src/functionN.lua index 8a311a8..5c62f91 100644 --- a/base_cpp/src/functionN.lua +++ b/base_cpp/src/functionN.lua @@ -1,4 +1,4 @@ --- Copyright (c) 2014-2015, Siemens AG. All rights reserved. +-- Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/log.cc b/base_cpp/src/log.cc new file mode 100644 index 0000000..c2f10f3 --- /dev/null +++ b/base_cpp/src/log.cc @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014-2016, 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 { + +Log::Log() { + // empty +} + +void Log::SetLogLevel( + embb_log_level_t log_level) { + embb_log_set_log_level(log_level); +} + +void Log::SetLogFunction( + void * context, + embb_log_function_t func) { + embb_log_set_log_function(context, func); +} + +void Log::Write( + char const * channel, + embb_log_level_t log_level, + char const * message, + ...) { + va_list argp; + va_start(argp, message); + embb_log_write_internal(channel, log_level, message, argp); + va_end(argp); +} + +void Log::Trace( + char const * channel, + char const * message, + ...) { +#if defined(EMBB_DEBUG) + va_list argp; + va_start(argp, message); + embb_log_write_internal(channel, EMBB_LOG_LEVEL_TRACE, message, argp); + va_end(argp); +#else + EMBB_UNUSED(channel); + EMBB_UNUSED(message); +#endif +} + +void Log::Info( + char const * channel, + char const * message, + ...) { +#if defined(EMBB_DEBUG) + va_list argp; + va_start(argp, message); + embb_log_write_internal(channel, EMBB_LOG_LEVEL_INFO, message, argp); + va_end(argp); +#else + EMBB_UNUSED(channel); + EMBB_UNUSED(message); +#endif +} + +void Log::Warning( + char const * channel, + char const * message, + ...) { + va_list argp; + va_start(argp, message); + embb_log_write_internal(channel, EMBB_LOG_LEVEL_WARNING, message, argp); + va_end(argp); +} + +void Log::Error( + char const * channel, + char const * message, + ...) { + va_list argp; + va_start(argp, message); + embb_log_write_internal(channel, EMBB_LOG_LEVEL_ERROR, message, argp); + va_end(argp); +} + +} // namespace base +} // namespace embb diff --git a/base_cpp/src/memory_allocation.cc b/base_cpp/src/memory_allocation.cc index 73ac560..34cb28e 100644 --- a/base_cpp/src/memory_allocation.cc +++ b/base_cpp/src/memory_allocation.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/mutex.cc b/base_cpp/src/mutex.cc index 61693ba..83dd946 100644 --- a/base_cpp/src/mutex.cc +++ b/base_cpp/src/mutex.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -60,8 +60,42 @@ Mutex::Mutex() : MutexBase(EMBB_MUTEX_PLAIN) { RecursiveMutex::RecursiveMutex() : MutexBase(EMBB_MUTEX_RECURSIVE) { } -} // namespace base -} // namespace embb +Spinlock::Spinlock() { + embb_spin_init(&spinlock_); +} + +Spinlock::~Spinlock() { + embb_spin_destroy(&spinlock_); +} + +void Spinlock::Lock() { + int status = embb_spin_lock(&spinlock_); + + // Currently, embb_spin_lock will always return EMBB_SUCCESS. However, + // This might change. + if (status != EMBB_SUCCESS) { + EMBB_THROW(ErrorException, "Error while locking spinlock"); + } +} + +bool Spinlock::TryLock(unsigned int number_spins) { + int status = embb_spin_try_lock(&spinlock_, number_spins); + if (status == EMBB_BUSY) { + return false; + } else if (status != EMBB_SUCCESS) { + EMBB_THROW(ErrorException, "Error while try-locking spinlock"); + } + + return true; +} +void Spinlock::Unlock() { + int status = embb_spin_unlock(&spinlock_); + if (status != EMBB_SUCCESS) { + EMBB_THROW(ErrorException, "Error while unlocking spinlock"); + } +} +} // namespace base +} // namespace embb diff --git a/base_cpp/src/thread.cc b/base_cpp/src/thread.cc index 6f6259e..3766dd9 100644 --- a/base_cpp/src/thread.cc +++ b/base_cpp/src/thread.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/src/time.cc b/base_cpp/src/time.cc index 8f99b01..1f827c5 100644 --- a/base_cpp/src/time.cc +++ b/base_cpp/src/time.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/atomic_test.cc b/base_cpp/test/atomic_test.cc index 580859c..f31d523 100644 --- a/base_cpp/test/atomic_test.cc +++ b/base_cpp/test/atomic_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/atomic_test.h b/base_cpp/test/atomic_test.h index 6696d29..9dea845 100644 --- a/base_cpp/test/atomic_test.h +++ b/base_cpp/test/atomic_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/condition_var_test.cc b/base_cpp/test/condition_var_test.cc index a023cf0..1159c38 100644 --- a/base_cpp/test/condition_var_test.cc +++ b/base_cpp/test/condition_var_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/condition_var_test.h b/base_cpp/test/condition_var_test.h index a2fefb7..597fc9f 100644 --- a/base_cpp/test/condition_var_test.h +++ b/base_cpp/test/condition_var_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/core_set_test.cc b/base_cpp/test/core_set_test.cc index 9dff77f..b23db7b 100644 --- a/base_cpp/test/core_set_test.cc +++ b/base_cpp/test/core_set_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/core_set_test.h b/base_cpp/test/core_set_test.h index d9579a9..bf70437 100644 --- a/base_cpp/test/core_set_test.h +++ b/base_cpp/test/core_set_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/duration_test.cc b/base_cpp/test/duration_test.cc index fb70d22..dcad281 100644 --- a/base_cpp/test/duration_test.cc +++ b/base_cpp/test/duration_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/duration_test.h b/base_cpp/test/duration_test.h index 48b8509..d36e2b5 100644 --- a/base_cpp/test/duration_test.h +++ b/base_cpp/test/duration_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/log_test.cc b/base_cpp/test/log_test.cc new file mode 100644 index 0000000..2109885 --- /dev/null +++ b/base_cpp/test/log_test.cc @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014-2016, 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 + +namespace embb { +namespace base { +namespace test { + +LogTest::LogTest() { + CreateUnit("Test all").Add(&LogTest::Test, this); +} + +static char const * logged_message; + +static void test_log_function(void * context, char const * msg) { + EMBB_UNUSED(context); + logged_message = msg; +} + +void LogTest::Test() { + using embb::base::Log; + char const * test_msg = "hello"; + char const * null = 0; + + Log::SetLogFunction(0, test_log_function); + + Log::SetLogLevel(EMBB_LOG_LEVEL_TRACE); + logged_message = null; + Log::Trace("chn", test_msg); +#ifdef EMBB_DEBUG + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [TRACE] hello")); +#else + PT_EXPECT_EQ(null, logged_message); +#endif + logged_message = null; + Log::Info("chn", test_msg); +#ifdef EMBB_DEBUG + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [INFO ] hello")); +#else + PT_EXPECT_EQ(null, logged_message); +#endif + logged_message = null; + Log::Warning("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello")); + logged_message = null; + Log::Error("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello")); + + Log::SetLogLevel(EMBB_LOG_LEVEL_INFO); + logged_message = null; + Log::Trace("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Info("chn", test_msg); +#ifdef EMBB_DEBUG + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [INFO ] hello")); +#else + PT_EXPECT_EQ(null, logged_message); +#endif + logged_message = null; + Log::Warning("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello")); + logged_message = null; + Log::Error("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello")); + + Log::SetLogLevel(EMBB_LOG_LEVEL_WARNING); + logged_message = null; + Log::Trace("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Info("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Warning("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello")); + logged_message = null; + Log::Error("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello")); + + Log::SetLogLevel(EMBB_LOG_LEVEL_ERROR); + logged_message = null; + Log::Trace("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Info("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Warning("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Error("chn", test_msg); + PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello")); + + Log::SetLogLevel(EMBB_LOG_LEVEL_NONE); + logged_message = null; + Log::Trace("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Info("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Warning("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); + logged_message = null; + Log::Error("chn", test_msg); + PT_EXPECT_EQ(null, logged_message); +} + +} // namespace test +} // namespace base +} // namespace embb + + + diff --git a/dataflow_cpp/include/embb/dataflow/internal/spinlock.h b/base_cpp/test/log_test.h similarity index 53% rename from dataflow_cpp/include/embb/dataflow/internal/spinlock.h rename to base_cpp/test/log_test.h index bc28910..d258a4e 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/spinlock.h +++ b/base_cpp/test/log_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -24,42 +24,34 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EMBB_DATAFLOW_INTERNAL_SPINLOCK_H_ -#define EMBB_DATAFLOW_INTERNAL_SPINLOCK_H_ +#ifndef BASE_CPP_TEST_LOG_TEST_H_ +#define BASE_CPP_TEST_LOG_TEST_H_ -#include +#include namespace embb { -namespace dataflow { -namespace internal { +namespace base { +namespace test { -class SpinLock { +/** + * Provides tests for Log. + */ +class LogTest : public partest::TestCase { public: - SpinLock() : lock_(0) {} - void Lock() { - int expected = 0; - while (!lock_.CompareAndSwap(expected, 1)) { - expected = 0; - } - } - bool TryLock(int spins = 0) { - int expected = 0; - while (spins > 0 && !lock_.CompareAndSwap(expected, 1)) { - expected = 0; - spins--; - } - return spins > 0; - } - void Unlock() { - lock_ = 0; - } + /** + * Adds test methods. + */ + LogTest(); private: - embb::base::Atomic lock_; + /** + * Tests all functionalities. + */ + void Test(); }; -} // namespace internal -} // namespace dataflow +} // namespace test +} // namespace base } // namespace embb -#endif // EMBB_DATAFLOW_INTERNAL_SPINLOCK_H_ +#endif // BASE_CPP_TEST_LOG_TEST_H_ diff --git a/base_cpp/test/main.cc b/base_cpp/test/main.cc index 5d7626d..31b57d2 100644 --- a/base_cpp/test/main.cc +++ b/base_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -41,23 +42,28 @@ using embb::base::test::CoreSetTest; using embb::base::test::DurationTest; using embb::base::test::ConditionVarTest; using embb::base::test::MutexTest; +using embb::base::test::SpinLockTest; using embb::base::test::ThreadSpecificStorageTest; using embb::base::test::AtomicTest; using embb::base::test::MemoryAllocationTest; using embb::base::test::ThreadTest; +using embb::base::test::LogTest; PT_MAIN("Base C++") { unsigned int max_threads = static_cast(2 * partest::TestSuite::GetDefaultNumThreads()); embb_thread_set_max_count(max_threads); + PT_RUN(CoreSetTest); PT_RUN(DurationTest); PT_RUN(ConditionVarTest); PT_RUN(MutexTest); + PT_RUN(SpinLockTest); PT_RUN(ThreadSpecificStorageTest); PT_RUN(AtomicTest); PT_RUN(MemoryAllocationTest); PT_RUN(ThreadTest); + PT_RUN(LogTest); PT_EXPECT(embb_get_bytes_allocated() == 0); } diff --git a/base_cpp/test/memory_allocation_test.cc b/base_cpp/test/memory_allocation_test.cc index 8d75726..f43a66a 100644 --- a/base_cpp/test/memory_allocation_test.cc +++ b/base_cpp/test/memory_allocation_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/memory_allocation_test.h b/base_cpp/test/memory_allocation_test.h index 58a360a..2c1dbda 100644 --- a/base_cpp/test/memory_allocation_test.h +++ b/base_cpp/test/memory_allocation_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/mutex_test.cc b/base_cpp/test/mutex_test.cc index 48cc0a9..496b3c8 100644 --- a/base_cpp/test/mutex_test.cc +++ b/base_cpp/test/mutex_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -32,7 +32,6 @@ namespace embb { namespace base { namespace test { - MutexTest::MutexTest() : mutex_(), counter_(0), number_threads_(partest::TestSuite::GetDefaultNumThreads()), number_iterations_(partest::TestSuite::GetDefaultNumIterations()) { @@ -209,6 +208,57 @@ void MutexTest::TestUniqueLock() { } } +SpinLockTest::SpinLockTest() : spinlock_(), counter_(0), +number_threads_(partest::TestSuite::GetDefaultNumThreads()), + number_iterations_(partest::TestSuite::GetDefaultNumIterations()), + counter_iterations_(10000) { + CreateUnit("Spinlock protected counter (using Lock)") + .Add(&SpinLockTest::TestSpinlockCountLock, this, number_threads_, + number_iterations_) + .Post(&SpinLockTest::PostSpinlockCount, this); + + CreateUnit("Spinlock protected counter (using Trylock)") + .Add(&SpinLockTest::TestSpinlockCountLockTryLock, this, number_threads_, + number_iterations_) + .Post(&SpinLockTest::PostSpinlockCount, this); + + CreateUnit("Test spinning (too many spins), single thread") + .Add(&SpinLockTest::TestSpinLockTooManySpins, this, 1, 1); +} + +void SpinLockTest::TestSpinlockCountLock() { + for (unsigned int i = 0; i != counter_iterations_; ++i) { + spinlock_.Lock(); + counter_++; + spinlock_.Unlock(); + } +} + +void SpinLockTest::TestSpinlockCountLockTryLock() { + for (unsigned int i = 0; i != counter_iterations_; ++i) { + while (!spinlock_.TryLock()) {} + counter_++; + spinlock_.Unlock(); + } +} + +void SpinLockTest::PostSpinlockCount() { + PT_EXPECT_EQ(counter_, + number_iterations_ * + number_threads_* + counter_iterations_); + counter_ = 0; +} + +void SpinLockTest::TestSpinLockTooManySpins() { + Spinlock lock; + lock.Lock(); + bool success = lock.TryLock(100); + PT_ASSERT(!success); + lock.Unlock(); + success = lock.TryLock(100); + PT_ASSERT(success); +} } // namespace test } // namespace base } // namespace embb diff --git a/base_cpp/test/mutex_test.h b/base_cpp/test/mutex_test.h index 80579a8..793ff90 100644 --- a/base_cpp/test/mutex_test.h +++ b/base_cpp/test/mutex_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -89,6 +89,49 @@ class MutexTest : public partest::TestCase { size_t number_iterations_; }; +class SpinLockTest : public partest::TestCase { + public: + SpinLockTest(); + + private: + /** + * Uses Spinlock to realize multi-threaded counting. + */ + void TestSpinlockCountLock(); + void TestSpinlockCountLockTryLock(); + void PostSpinlockCount(); + + /** + * Test that TryLock returns false, if lock is already locked. + */ + void TestSpinLockTooManySpins(); + + /** + * Spinlock for tests + */ + Spinlock spinlock_; + + /** + * Shared counter to check effectiveness of mutex. + */ + size_t counter_; + + /** + * Number of threads used to run tests. + */ + size_t number_threads_; + + /** + * Number of times the test method is called by each thread. + */ + size_t number_iterations_; + + /** + * Number of internal iterations, for incrementing the counter. + */ + size_t counter_iterations_; +}; + } // namespace test } // namespace base } // namespace embb diff --git a/base_cpp/test/thread_specific_storage_test.cc b/base_cpp/test/thread_specific_storage_test.cc index f979b50..398af51 100644 --- a/base_cpp/test/thread_specific_storage_test.cc +++ b/base_cpp/test/thread_specific_storage_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/thread_specific_storage_test.h b/base_cpp/test/thread_specific_storage_test.h index 1c94e2a..7a07c5d 100644 --- a/base_cpp/test/thread_specific_storage_test.h +++ b/base_cpp/test/thread_specific_storage_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/thread_test.cc b/base_cpp/test/thread_test.cc index f8af461..68de306 100644 --- a/base_cpp/test/thread_test.cc +++ b/base_cpp/test/thread_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/thread_test.h b/base_cpp/test/thread_test.h index 3d27579..48d2f30 100644 --- a/base_cpp/test/thread_test.h +++ b/base_cpp/test/thread_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/base_cpp/test/time_test.h b/base_cpp/test/time_test.h index d49a1fb..da00d6d 100644 --- a/base_cpp/test/time_test.h +++ b/base_cpp/test/time_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/include/embb/containers/containers.h b/containers_cpp/include/embb/containers/containers.h index 8cc7c79..8e842a6 100644 --- a/containers_cpp/include/embb/containers/containers.h +++ b/containers_cpp/include/embb/containers/containers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h b/containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h index 3873dba..9e82f73 100644 --- a/containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h +++ b/containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -30,386 +30,360 @@ namespace embb { namespace containers { namespace internal { -template< typename ElementT > -FixedSizeList::FixedSizeList(size_t max_size) : - max_size(max_size), - size(0) { - elementsArray = static_cast( - embb::base::Allocation::Allocate(sizeof(ElementT) * - max_size)); -} - -template< typename ElementT > -inline size_t FixedSizeList::GetSize() const { - return size; -} - -template< typename ElementT > -inline size_t FixedSizeList::GetMaxSize() const { - return max_size; -} - -template< typename ElementT > -inline void FixedSizeList::clear() { - size = 0; -} - -template< typename ElementT > -typename FixedSizeList::iterator -FixedSizeList::begin() const { - return &elementsArray[0]; -} - -template< typename ElementT > -typename FixedSizeList::iterator -FixedSizeList::end() const { - return &elementsArray[size]; -} - -template< typename ElementT > -FixedSizeList< ElementT > & -FixedSizeList::operator= (const FixedSizeList & other) { - size = 0; - - if (max_size < other.size) { - EMBB_THROW(embb::base::ErrorException, "Copy target to small"); - } +// Visual Studio is complaining, that the return in the last line of this +// function is not reachable. This is true, as long as exceptions are enabled. +// Otherwise, the exception becomes an assertion and with disabling assertions, +// the code becomes reachable. So, disabling this warning. +#ifdef EMBB_PLATFORM_COMPILER_MSVC +#pragma warning(push) +#pragma warning(disable:4702) +#endif + template< typename GuardType > + unsigned int HazardPointer< GuardType >::GetObjectLocalThreadIndex() { + // first, get the EMBB native thread id. + unsigned int embb_thread_index; - for (const_iterator it = other.begin(); it != other.end(); ++it) { - PushBack(*it); - } - return *this; -} + int return_val = embb_internal_thread_index(&embb_thread_index); + + if (return_val != EMBB_SUCCESS) { + EMBB_THROW(embb::base::ErrorException, "Could not get thread id"); + } + + // iterate over the mappings array + for (unsigned int i = 0; i != max_accessors_count_; ++i) { + // end of mappings? then we need to write our id + if (thread_id_mapping_[i] == -1) { + // try to CAS the initial value with out thread id + int expected = -1; + if (thread_id_mapping_[i].CompareAndSwap(expected, + static_cast(embb_thread_index))) { + //successful, return our mapping + return i; + } + } + + if (thread_id_mapping_[i] == static_cast(embb_thread_index)) { + // found our mapping! + return i; + } + } + + // when we reach this point, we have too many accessors + // (no mapping possible) + EMBB_THROW(embb::base::ErrorException, "Too many accessors"); -template< typename ElementT > -bool FixedSizeList::PushBack(ElementT const el) { - if (size + 1 > max_size) { - return false; + return 0; } - elementsArray[size] = el; - size++; - return true; -} - -template< typename ElementT > -FixedSizeList::~FixedSizeList() { - embb::base::Allocation::Free(elementsArray); -} - -template< typename GuardType > -bool HazardPointerThreadEntry::IsActive() { - return is_active; -} - -template< typename GuardType > -bool HazardPointerThreadEntry::TryReserve() { - bool expected = false; - return is_active.CompareAndSwap(expected, true); -} - -template< typename GuardType > -void HazardPointerThreadEntry::Deactivate() { - is_active = false; -} - -template< typename GuardType > -size_t HazardPointerThreadEntry::GetRetiredCounter() { - return retired_list.GetSize(); -} - -template< typename GuardType > -FixedSizeList< GuardType >& HazardPointerThreadEntry:: -GetRetired() { - return retired_list; -} - -template< typename GuardType > -FixedSizeList< GuardType >& HazardPointerThreadEntry:: -GetRetiredTemp() { - return retired_list_temp; -} - -template< typename GuardType > -FixedSizeList< GuardType >& HazardPointerThreadEntry:: -GetHazardTemp() { - return hazard_pointer_list_temp; -} - -template< typename GuardType > -void HazardPointerThreadEntry:: -SetRetired(internal::FixedSizeList< GuardType > const & retired_list) { - this->retired_list = retired_list; -} - -template< typename GuardType > -HazardPointerThreadEntry:: -HazardPointerThreadEntry(GuardType undefined_guard, int guards_per_thread, - size_t max_size_retired_list) : -#ifdef EMBB_DEBUG - who_is_scanning(-1), +#ifdef EMBB_PLATFORM_COMPILER_MSVC +#pragma warning(pop) #endif - undefined_guard(undefined_guard), - guards_per_thread(guards_per_thread), - max_size_retired_list(max_size_retired_list), - // initially, each potential thread is active... if that is not the case - // another thread could call "HelpScan", and block this thread in making - // progress. - // Still, threads can be leave the hazard pointer processing (deactivation), - // but this can only be done once, i.e., this is not revertable... - is_active(1), - retired_list(max_size_retired_list), - retired_list_temp(max_size_retired_list), - hazard_pointer_list_temp(embb::base::Thread::GetThreadsMaxCount() * - guards_per_thread) { - // Initialize guarded pointer list - guarded_pointers = static_cast*> - (embb::base::Allocation::Allocate( - sizeof(embb::base::Atomic)*guards_per_thread)); - - for (int i = 0; i != guards_per_thread; ++i) { - new (static_cast(&guarded_pointers[i])) - embb::base::Atomic(undefined_guard); - } -} -template< typename GuardType > -HazardPointerThreadEntry::~HazardPointerThreadEntry() { - for (int i = 0; i != guards_per_thread; ++i) { - guarded_pointers[i].~Atomic(); + template< typename GuardType > + void HazardPointer< GuardType >::RemoveGuard(int guard_position) { + const unsigned int my_thread_id = GetObjectLocalThreadIndex(); + + // check invariants... + assert(guard_position < max_guards_per_thread_); + assert(my_thread_id < max_accessors_count_); + + // set guard + guards_[guard_position*max_accessors_count_ + my_thread_id] = + undefined_guard_; } - embb::base::Allocation::Free(guarded_pointers); -} - -template< typename GuardType > -GuardType HazardPointerThreadEntry::GetGuard(int pos) const { - return guarded_pointers[pos]; -} - -template< typename GuardType > -void HazardPointerThreadEntry::AddRetired(GuardType pointerToGuard) { - retired_list.PushBack(pointerToGuard); -} - -template< typename GuardType > -void HazardPointerThreadEntry:: -GuardPointer(int guardNumber, GuardType pointerToGuard) { - guarded_pointers[guardNumber] = pointerToGuard; -} - -template< typename GuardType > -void HazardPointerThreadEntry::SetActive(bool active) { - is_active = active; -} - -template< typename GuardType > -unsigned int HazardPointer< GuardType >::GetCurrentThreadIndex() { - unsigned int thread_index; - int return_val = embb_internal_thread_index(&thread_index); - - if (return_val != EMBB_SUCCESS) - EMBB_THROW(embb::base::ErrorException, "Could not get thread id!"); - - return thread_index; -} -template< typename GuardType > -bool HazardPointer< GuardType >::IsThresholdExceeded() { - double retiredCounterLocThread = - static_cast(GetHazardPointerElementForCurrentThread(). - GetRetiredCounter()); - - return (retiredCounterLocThread >= - RETIRE_THRESHOLD * - static_cast(active_hazard_pointer)* - static_cast(guards_per_thread)); -} - -template< typename GuardType > -size_t HazardPointer< GuardType >::GetActiveHazardPointers() { - return active_hazard_pointer; -} -template< typename GuardType > -typename HazardPointer< GuardType >::HazardPointerThreadEntry_t & -HazardPointer< GuardType >::GetHazardPointerElementForCurrentThread() { - // For each thread, there is a slot in the hazard pointer array. - // Initially, the active flag of a hazard pointer entry is false. - // Only the respective thread changes the flag from true to false. - // This means that the current thread tells that he is about to - // stop operating, and the others are responsible for his retired - // list. - - return hazard_pointer_thread_entry_array[GetCurrentThreadIndex()]; -} - -template< typename GuardType > -void HazardPointer< GuardType >::HelpScan() { - // This is a little bit different than in the paper. In the paper, - // the retired nodes from other threads are added to our retired list. - // To be able to give a bound on memory consumption, we execute scan - // for those threads, without moving elements. The effect shall be - // the same. - - for (size_t i = 0; i != hazard_pointers; ++i) { - // Try to find non active lists... - if (!hazard_pointer_thread_entry_array[i].IsActive() && - hazard_pointer_thread_entry_array[i].TryReserve()) { - // Here: grab retired things, first check if there are any... - if (hazard_pointer_thread_entry_array[i].GetRetiredCounter() > 0) { - Scan(&hazard_pointer_thread_entry_array[i]); - } + template< typename GuardType > + HazardPointer< GuardType >::HazardPointer( + embb::base::Function freeGuardCallback, + GuardType undefined_guard, int guardsPerThread, int accessors) : + max_accessors_count_(accessors < 0 ? + embb::base::Thread::GetThreadsMaxCount() : accessors), + undefined_guard_(undefined_guard), + max_guards_per_thread_(guardsPerThread), + release_object_callback_(freeGuardCallback), + thread_id_mapping_(static_cast*>( + embb::base::Allocation::Allocate(sizeof(embb::base::Atomic) + *max_accessors_count_))), + guards_(static_cast*> + (embb::base::Allocation::Allocate( + sizeof(embb::base::Atomic< GuardType >) * max_guards_per_thread_ * + max_accessors_count_))), + thread_local_retired_lists_temp_(static_cast + (embb::base::Allocation::Allocate( + sizeof(GuardType) * max_guards_per_thread_ * max_accessors_count_ * + max_accessors_count_ + ))), + thread_local_retired_lists_(static_cast + (embb::base::Allocation::Allocate( + sizeof(GuardType) * max_guards_per_thread_ * max_accessors_count_ * + max_accessors_count_ + ))) { + const unsigned int count_guards = + max_guards_per_thread_ * max_accessors_count_; + + const unsigned int count_ret_elements = + count_guards * max_accessors_count_; + + for (unsigned int i = 0; i != max_accessors_count_; ++i) { + //in-place new for each cell + new (&thread_id_mapping_[i]) embb::base::Atomic < int >(-1); + } - // We are done, mark it as deactivated again - hazard_pointer_thread_entry_array[i].Deactivate(); + for (unsigned int i = 0; i != count_guards; ++i) { + //in-place new for each cell + new (&guards_[i]) embb::base::Atomic < GuardType >(undefined_guard); + } + + for (unsigned int i = 0; i != count_ret_elements; ++i) { + //in-place new for each cell + new (&thread_local_retired_lists_temp_[i]) GuardType(undefined_guard); + } + + for (unsigned int i = 0; i != count_ret_elements; ++i) { + //in-place new for each cell + new (&thread_local_retired_lists_[i]) GuardType(undefined_guard); } } -} - -template< typename GuardType > -void HazardPointer< GuardType >:: -Scan(HazardPointerThreadEntry_t* currentHazardPointerEntry) { -#ifdef EMBB_DEBUG - // scan should only be executed by one thread at a time, otherwise we have - // a bug... this assertions checks that - int expected = -1; - if (!currentHazardPointerEntry->GetScanningThread().CompareAndSwap( - expected, static_cast(GetCurrentThreadIndex()))) { - assert(false); - } -#endif - // In this function, we compute the intersection between local retired - // pointers and all hazard pointers. This intersection cannot be deleted and - // forms the new local retired pointers list. - // It is assumed that the union of all retired pointers contains no two - // pointers with the same value. However, the union of all hazard guards - // might. - - // Here, we store the temporary hazard pointers. We have to store them, - // as iterating multiple time over them might be expensive, as this - // atomic array is shared between threads. - currentHazardPointerEntry->GetHazardTemp().clear(); - - // Get all active hazard pointers! - for (unsigned int i = 0; i != hazard_pointers; ++i) { - // Only consider guards of active threads - if (hazard_pointer_thread_entry_array[i].IsActive()) { - // For each guard in an hazard pointer entry - for (int pos = 0; pos != guards_per_thread; ++pos) { - GuardType guard = hazard_pointer_thread_entry_array[i].GetGuard(pos); - - // UndefinedGuard means not guarded - if (guard == undefined_guard) - continue; - - currentHazardPointerEntry->GetHazardTemp().PushBack(guard); + + template< typename GuardType > + HazardPointer< GuardType >::~HazardPointer() { + const unsigned int count_guards = + max_guards_per_thread_ * max_accessors_count_; + + const unsigned int count_ret_elements = + count_guards * max_accessors_count_; + + // Release references from all retired lists. Note that for this to work, + // the data structure using hazard pointer has still to be active... So + // first, the hazard pointer class shall be destructed, then the memory + // management class (e.g. some pool). Otherwise, the hazard pointer class + // would try to return memory to an already destructed memory manager. + for (unsigned int i = 0; i != count_ret_elements; ++i) { + GuardType pointerToFree = + thread_local_retired_lists_[i]; + if (pointerToFree == undefined_guard_) { + break; } + release_object_callback_(pointerToFree); } - } - currentHazardPointerEntry->GetRetiredTemp().clear(); - - // Sort them, we will do a binary search on each entry from the retired list - std::sort( - currentHazardPointerEntry->GetHazardTemp().begin(), - currentHazardPointerEntry->GetHazardTemp().end()); - - for ( - EMBB_CONTAINERS_CPP_DEPENDANT_TYPENAME FixedSizeList< GuardType >::iterator - it = currentHazardPointerEntry->GetRetired().begin(); - it != currentHazardPointerEntry->GetRetired().end(); ++it) { - if (false == ::std::binary_search( - currentHazardPointerEntry->GetHazardTemp().begin(), - currentHazardPointerEntry->GetHazardTemp().end(), *it)) { - this->free_guard_callback(*it); - } else { - currentHazardPointerEntry->GetRetiredTemp().PushBack(*it); + for (unsigned int i = 0; i != max_accessors_count_; ++i) { + thread_id_mapping_[i].~Atomic(); + } + + embb::base::Allocation::Free(thread_id_mapping_); + + for (unsigned int i = 0; i != count_guards; ++i) { + guards_[i].~Atomic(); } + + embb::base::Allocation::Free(guards_); + + for (unsigned int i = 0; i != count_ret_elements; ++i) { + thread_local_retired_lists_temp_[i].~GuardType(); + } + + embb::base::Allocation::Free(thread_local_retired_lists_temp_); + + for (unsigned int i = 0; i != count_ret_elements; ++i) { + thread_local_retired_lists_[i].~GuardType(); + } + + embb::base::Allocation::Free(thread_local_retired_lists_); } - currentHazardPointerEntry->SetRetired( - currentHazardPointerEntry->GetRetiredTemp()); -#ifdef EMBB_DEBUG - currentHazardPointerEntry->GetScanningThread().Store(-1); -#endif -} - -template< typename GuardType > -size_t HazardPointer< GuardType >::GetRetiredListMaxSize() const { - return static_cast(RETIRE_THRESHOLD * - static_cast(embb::base::Thread::GetThreadsMaxCount()) * - static_cast(guards_per_thread)) + 1; -} - -template< typename GuardType > -HazardPointer< GuardType >::HazardPointer( - embb::base::Function free_guard_callback, - GuardType undefined_guard, int guards_per_thread) : - undefined_guard(undefined_guard), - guards_per_thread(guards_per_thread), - //initially, all potential hazard pointers are active... - active_hazard_pointer(embb::base::Thread::GetThreadsMaxCount()), - free_guard_callback(free_guard_callback) { - hazard_pointers = embb::base::Thread::GetThreadsMaxCount(); - - hazard_pointer_thread_entry_array = static_cast( - embb::base::Allocation::Allocate(sizeof(HazardPointerThreadEntry_t) * - hazard_pointers)); - - for (size_t i = 0; i != hazard_pointers; ++i) { - new (static_cast(&(hazard_pointer_thread_entry_array[i]))) - HazardPointerThreadEntry_t(undefined_guard, guards_per_thread, - GetRetiredListMaxSize()); + template< typename GuardType > + void HazardPointer< GuardType >::Guard(int guardPosition, + GuardType guardedElement) { + const unsigned int my_thread_id = GetObjectLocalThreadIndex(); + + // check invariants... + assert(guardPosition < max_guards_per_thread_); + assert(my_thread_id < max_accessors_count_); + + // set guard + guards_[guardPosition*max_accessors_count_ + my_thread_id] = guardedElement; } -} -template< typename GuardType > -HazardPointer< GuardType >::~HazardPointer() { - for (size_t i = 0; i != hazard_pointers; ++i) { - hazard_pointer_thread_entry_array[i].~HazardPointerThreadEntry_t(); + template< typename GuardType > + size_t HazardPointer< GuardType >::ComputeMaximumRetiredObjectCount( + size_t guardsPerThread, int accessors) { + unsigned int accessorCount = (accessors == -1 ? + embb::base::Thread::GetThreadsMaxCount() : + accessors); + + return static_cast( + guardsPerThread * accessorCount * accessorCount); } - embb::base::Allocation::Free(static_cast < void* > - (hazard_pointer_thread_entry_array)); -} - -template< typename GuardType > -void HazardPointer< GuardType >::DeactivateCurrentThread() { - HazardPointerThreadEntry_t* current_thread_entry = - &hazard_pointer_thread_entry_array[GetCurrentThreadIndex()]; - - // Deactivating a non-active hazard pointer entry has no effect! - if (!current_thread_entry->IsActive()) { - return; - } else { - current_thread_entry->SetActive(false); - active_hazard_pointer--; + /** + * Remark: it might be faster to just swap pointers for temp retired list and + * retired list. However, with the current implementation (one array for all + * retired and retired temp lists, respectively) this is not possible. This is + * not changed until this copying accounts for a performance problem. The + * copying is not the bottleneck currently. + */ + template< typename GuardType > + void HazardPointer< GuardType >::CopyRetiredList(GuardType* sourceList, + GuardType* targetList, unsigned int retiredListSize, + GuardType undefinedGuard) { + bool done = false; + for (unsigned int ii = 0; ii != retiredListSize; ++ii) { + if (!done) { + GuardType guardToCopy = sourceList[ii]; + + if (guardToCopy == undefinedGuard) { + done = true; + + if (targetList[ii] == undefinedGuard) { + // end of target list + break; + } + } + targetList[ii] = guardToCopy; + } else { + // we copied the whole source list, remaining values in the target + // have to be zeroed. + if (targetList[ii] == undefinedGuard) { + // end of target list + break; + } else { + targetList[ii] = undefinedGuard; + } + } + } } -} - -template< typename GuardType > -void HazardPointer< GuardType >::GuardPointer(int guardPosition, - GuardType guardedElement) { - GetHazardPointerElementForCurrentThread().GuardPointer( - guardPosition, guardedElement); -} - -template< typename GuardType > -void HazardPointer< GuardType >::EnqueuePointerForDeletion( - GuardType guardedElement) { - GetHazardPointerElementForCurrentThread().AddRetired(guardedElement); - if (IsThresholdExceeded()) { - HazardPointerThreadEntry_t* currentHazardPointerEntry = - &GetHazardPointerElementForCurrentThread(); - - Scan(currentHazardPointerEntry); - - // Help deactivated threads to clean their retired nodes. - HelpScan(); + + template< typename GuardType > + void HazardPointer< GuardType >::UpdateRetiredList(GuardType* retired_list, + GuardType* updated_retired_list, unsigned int retired_list_size, + GuardType guarded_element, GuardType considered_hazard, + GuardType undefined_guard) { + // no hazard set here + if (considered_hazard == undefined_guard) + return; + + // if this hazard is currently in the union of + // threadLocalRetiredLists and pointerToRetire, but not yet in + // threadLocalRetiredListsTemp, add it to that list + bool contained_in_union = false; + + // first iterate over our retired list + for (unsigned int i = 0; i != retired_list_size; ++i) { + // when reaching 0, we can stop iterating (end of the "list") + if (retired_list[i] == 0) + break; + + // the hazard is contained in the retired list... it shall go + // into the temp list, if not already there + if (retired_list[i] == considered_hazard) { + contained_in_union = true; + break; + } + } + + // the union also contains pointerToRetire + if (!contained_in_union) { + contained_in_union = (considered_hazard == guarded_element); + } + + // add the pointer to temp. retired list, if not already there + if (contained_in_union) { + for (unsigned int ii = 0; ii != retired_list_size; ++ii) { + // is it already there? + if (updated_retired_list[ii] == considered_hazard) + break; + + // end of the list + if (updated_retired_list[ii] == undefined_guard) { + // add hazard + updated_retired_list[ii] = considered_hazard; + + // we are done here... + break; + } + } + } } -} -template -const double embb::containers::internal::HazardPointer:: - RETIRE_THRESHOLD = 1.25f; + template< typename GuardType > + void HazardPointer< GuardType >::EnqueueForDeletion(GuardType toRetire) { + unsigned int my_thread_id = GetObjectLocalThreadIndex(); + + // check for invariant + assert(my_thread_id < max_accessors_count_); + + const unsigned int retired_list_size = max_accessors_count_ * + max_guards_per_thread_; + + const unsigned int count_guards = max_accessors_count_ * + max_guards_per_thread_; + + GuardType* retired_list = + &thread_local_retired_lists_[my_thread_id * retired_list_size]; + + GuardType* retired_list_temp = + &thread_local_retired_lists_temp_[my_thread_id * retired_list_size]; + + // wipe my temp. retired list... + for (unsigned int i = 0; i < retired_list_size; ++i) { + // the list is filled always from left to right, so occurring the first + // undefinedGuard, the remaining ones are also undefinedGuard... + if (retired_list_temp[i] == undefined_guard_) + break; + + retired_list_temp[i] = undefined_guard_; + } + + // we test each hazard if it is in the union of retiredList and + // guardedElement. If it is, it goes into the new retired list... + for (unsigned int i = 0; i != count_guards; ++i) { + // consider each current active guard + GuardType considered_hazard = guards_[i].Load(); + UpdateRetiredList(retired_list, retired_list_temp, retired_list_size, + toRetire, considered_hazard, undefined_guard_); + } + + int retired_list_size_signed = static_cast(retired_list_size); + assert(retired_list_size_signed >= 0); + + // now we created a a new retired list... the elements that are "removed" + // from the old retired list can be safely deleted now... + for (int i = -1; i != retired_list_size_signed; ++i) { + // we iterate over the current retired list... -1 is used as dummy element + // in the iteration, to also iterate over the pointerToRetire, which is + // logically also part of the current retired list... + + // end of the list, stop iterating + if (i >= 0 && retired_list[i] == undefined_guard_) + break; + + GuardType to_check_if_in_new_list = undefined_guard_; + + to_check_if_in_new_list = (i == -1 ? toRetire : retired_list[i]); + + // still in the new retired list? + bool still_in_list = false; + for (unsigned int ii = 0; ii != retired_list_size; ++ii) { + // end of list + if (retired_list_temp[ii] == undefined_guard_) + break; + + if (to_check_if_in_new_list == retired_list_temp[ii]) { + // still in list, cannot delete element! + still_in_list = true; + break; + } + } + + if (!still_in_list) { + this->release_object_callback_(to_check_if_in_new_list); + } + } + + // copy the updated retired list (temp) to the retired list... + CopyRetiredList(retired_list_temp, retired_list, retired_list_size, + undefined_guard_); + } } // namespace internal } // namespace containers } // namespace embb diff --git a/containers_cpp/include/embb/containers/internal/hazard_pointer.h b/containers_cpp/include/embb/containers/internal/hazard_pointer.h index e1e5f49..25570dd 100644 --- a/containers_cpp/include/embb/containers/internal/hazard_pointer.h +++ b/containers_cpp/include/embb/containers/internal/hazard_pointer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -40,487 +40,274 @@ #define EMBB_CONTAINERS_CPP_DEPENDANT_TYPENAME typename #endif +// forward declaration for white-box test, used in friend declaration of +// HazardPointer class. +namespace embb { +namespace containers { +namespace test { +class HazardPointerTest2; +} +} +} + namespace embb { namespace containers { namespace internal { /** - * A list with fixed size, implemented as an array. Replaces std::vector that - * was used in previous hazard pointer implementation. + * This class contains a hazard pointer implementation following publication: * - * Provides iterators, so we can apply algorithms from the STL. + * Maged M. Michael. "Hazard pointers: Safe memory reclamation for lock-free + * objects." IEEE Transactions on Parallel and Distributed Systems, 15.6 (2004) + * : 491-504. * - * \tparam ElementT Type of the elements contained in the list. - */ -template< typename ElementT > -class FixedSizeList { - private: - /** - * Capacity of the list - */ - size_t max_size; - - /** - * Size of the list - */ - size_t size; - - /** - * Pointer to the array containing the list - */ - ElementT* elementsArray; - - /** - * Copy constructor not implemented. Would require dynamic memory allocation. - */ - FixedSizeList( - const FixedSizeList & - /**< [IN] Other list */); - - public: - /** - * Definition of an iterator - */ - typedef ElementT * iterator; - - /** - * Definition of a const iterator - */ - typedef const ElementT * const_iterator; - - /** - * Constructor, initializes list with given capacity - */ - FixedSizeList( - size_t max_size - /**< [IN] Capacity of the list */); - - /** - * Gets the current size of the list - * - * \return Size of the list - */ - inline size_t GetSize() const; - - /** - * Gets the capacity of the list - * - * \return The capacity of the list - */ - inline size_t GetMaxSize() const; - - /** - * Removes all elements from the list without changing the capacity - */ - inline void clear(); - - /** - * Iterator pointing to the first element - * - * \return Begin iterator - */ - iterator begin() const; - - /** - * Iterator pointing beyond the last element - * - * \return End iterator - */ - iterator end() const; - - /** - * Copies the elements of another list to this list. The capacity of - * this list has to be greater than or equal to the size of the other list. - */ - FixedSizeList & operator=( - const FixedSizeList & other - /**< [IN] Other list */); - - /** - * Appends an element to the end of the list - * - * \return \c false if the operation was not successful because the list is - * full, otherwise \c true. - */ - bool PushBack( - ElementT const el - /**< [IN] Element to append to the list */); - - /** - * Destructs the list. - */ - ~FixedSizeList(); -}; - -/** - * Hazard pointer entry for a single thread. Holds the actual guards that - * determine if the current thread is about to use the guarded pointer. - * Guarded pointers are protected and not deleted. + * Hazard pointers are a wait-free memory reclamation scheme for lock-free + * algorithms. Loosely speaking, they act as garbage collector. The release of + * objects contained within the memory, managed by the hazard pointer class, is + * intercepted and possibly delayed to avoid concurrency bugs. + * + * Before accessing an object, threads announce their intention to do so (i.e. + * the intention to dereference the respective pointer) to the hazard pointer + * class. This is called guarding. From now on, the hazard pointer class will + * prohibit the release or reuse of the guarded object. This is necessary, to + * assure that the object is not released or reused while it is accessed and to + * assure that it has not unnoticed changed (effectively avoiding the ABA + * problem). + * + * Note that after guarding an object, a consecutive check that the object (i.e. + * its pointer) is still valid is necessary; the object release could already + * have been started when guarding the object. Guarding is repeated, until this + * check eventually succeeds. Note that this "guard-and-check" loop makes the + * usage of the hazard pointer class lock-free, even though its implementation + * is wait-free. + * + * Internally, guarding is realized by providing each thread slots, where + * pointers can be placed that should not be freed (so called guards). When + * trying to release an object, it is checked if the object's pointer is + * guarded, and if so this object is not released, but instead put into a + * retired list for later release, when all guards for this object have been + * removed. + * + * In contrast to the original implementation, our implementation consumes only + * fixed-size memory. Note that the number of threads accessing the hazard + * pointer object accounts quadratic for the memory consumption: managed objects + * are provided from outside and the number of accessors accounts quadric for + * the minimum count of those objects. * - * Moreover, the retired list for this thread is contained. It determines - * the pointers that have been allocated from this thread, but are not used - * anymore by this thread. However, another thread could have a guard on it, - * so the pointer cannot be deleted immediately. + * Also in contrast to the original implementation, we do not provide a HelpScan + * functionality, which gives threads the possibility, to not participate in the + * garbage collection anymore: other threads will help to clean-up the objects + * protected by the exiting thread. The reason is, that the only use-case would + * be a crashing thread, not participating anymore. However, as the thread has + * to signal its exit himself, this is not possible to realize anyways. In the + * end, it is still guaranteed that all memory is properly returned (in the + * destructor). * - * For the scan operation, the intersection of the guarded pointers from all - * threads and the retired list has to be computed. For this computation, we - * need thread local temporary lists which are also contained here. + * Additionally, the original implementation holds a threshold, which determines + * when objects shall be freed. In this implementation, we free whenever it is + * possibly to do so, as we want to keep the memory footprint as low as + * possible. We also don't see a performance drop in the current algorithms that + * are using hazard pointers, when not using a threshold. * - * \tparam GuardType The type of guard, usually a pointer. + * \tparam GuardType the type of the guards. Usually the pointer type of some + * object to protect. */ template< typename GuardType > -class HazardPointerThreadEntry { -#ifdef EMBB_DEBUG - - public: - embb::base::Atomic& GetScanningThread() { - return who_is_scanning; - } - - private: - embb::base::Atomic who_is_scanning; -#endif - - private: - /** - * Value of the undefined guard (means that no guard is set). - */ - GuardType undefined_guard; - - /** - * The number of guards per thread. Determines the size of the guard array. - */ - int guards_per_thread; - - /** - * The capacity of the retired list. It is determined by number of guards, - * retired threshold, and maximum number of threads. - */ - size_t max_size_retired_list; - - /** - * Set to true if the current thread is active. Is used for a thread to - * signal that it is leaving. If a thread has left, the other threads are - * responsible for cleaning up its retired list. - */ - embb::base::Atomic< bool > is_active; - - /** - * The guarded pointer of this thread, has size \c guard_per_thread. - */ - embb::base::Atomic< GuardType >* guarded_pointers; - - /** - * The retired list of this thread, contains pointer that shall be released - * when no thread holds a guard on it anymore. - */ - FixedSizeList< GuardType > retired_list; - - /** - * Temporary retired list, has same capacity as \c retired_list, It is used to - * compute the intersection of all guards and the \c retired list. - */ - FixedSizeList< GuardType > retired_list_temp; - - /** - * Temporary guards list. Used to compute the intersection of all guards and - * the \c retired_list. - */ - FixedSizeList< GuardType > hazard_pointer_list_temp; - - /** - * HazardPointerThreadEntry shall not be copied - */ - HazardPointerThreadEntry(const HazardPointerThreadEntry&); - - /** - * HazardPointerThreadEntry shall not be assigned - */ - HazardPointerThreadEntry & operator= (const HazardPointerThreadEntry&); - +class HazardPointer { public: /** - * Checks if current thread is active (with respect to participating in hazard - * pointer management) + * The user of the hazard pointer class has to provide the memory that is + * managed here. The user has to take into account, that releasing of memory + * might be delayed. He has therefore to provide more memory than he wants to + * guarantee at each point in time. More specific, on top of the guaranteed + * count of objects, he has to provide the additional count of objects that + * can be (worst-case) contained in the retired lists and therefore are not + * released yet. The size sum of all retired lists is guardsPerThread * + * accessorCount * accessorCount, which is computed using this function. So + * the result of function denotes to the user, how many objects he has to + * allocate additionally to the guaranteed count. * - * \return \c true if the current thread is active, otherwise \c false. - */ - bool IsActive(); - - /** - * Tries to set the active flag to true (atomically). Used if the current - * thread is not active anymore as lock for another thread to help cleaning - * up hazard pointer. - * - * \return \c true if this thread was successful setting the active flag, - * otherwise \c false. - */ - bool TryReserve(); - - /** - * Deactivates current thread by atomically setting active flag to false. + * \waitfree */ - void Deactivate(); + static size_t ComputeMaximumRetiredObjectCount( + size_t guardsPerThread, + /**<[IN] the count of guards per thread*/ + int accessors = -1 + /**<[IN] Number of accessors. Determines, how many threads will access + the hazard pointer object. Default value -1 will allow the + maximum amount of threads as defined with + \c embb::base::Thread::GetThreadsMaxCount()*/ + ); /** - * Gets the count of current retired pointer for the current thread. + * Initializes the hazard pointer object * - * \return Count of current retired pointer - */ - size_t GetRetiredCounter(); - - /** - * Gets the retired list. + * \notthreadsafe * - * \return Reference to \c retired_list - */ - FixedSizeList< GuardType >& GetRetired(); - - /** - * Gets the temporary retired list. + * \memory We dynamically allocate the following: * - * \return Reference to \c retired_list_temp - */ - FixedSizeList< GuardType >& GetRetiredTemp(); - - /** - * Gets the temporary hazard pointer list. + * (sizeof(Atomic) * accessors) + (sizeof(Atomic) * + * guards_per_thread * accessors) + (2*sizeof(GuardType) * + * guards_per_thread * accessors^2) * - * \return Reference to \c hazard_pointer_list_temp - */ - FixedSizeList< GuardType >& GetHazardTemp(); - - /** - * Sets the retired list. - */ - void SetRetired( - embb::containers::internal::FixedSizeList< GuardType > const & retired_list - /**< [IN] Retired list */); - - /** - * Constructor + * The last addend is the dominant one, as accessorCount accounts + * quadratically for it. */ - HazardPointerThreadEntry( + HazardPointer( + embb::base::Function free_guard_callback, + /**<[IN] Callback to the function that shall be called when a retired + guard can be deleted */ GuardType undefined_guard, - /**< [IN] Value of the undefined guard (e.g. NULL) */ + /**<[IN] The guard value denoting "not guarded"*/ int guards_per_thread, - /**< [IN] Number of guards per thread */ - size_t max_size_retired_list - /**< [IN] The capacity of the retired list(s) */); - - /** - * Destructor + /**<[IN] Number of guards per thread*/ + int accessors = -1 + /**<[IN] Number of accessors. Determines, how many threads will access + this hazard pointer object. Default value -1 will allow the + maximum amount of threads as defined with + \c embb::base::Thread::GetThreadsMaxCount()*/ + ); + + /** + * Deallocates internal data structures. Additionally releases all objects + * currently held in the retired lists, using the release functor passed in + * the constructor. * - * Deallocate lists - */ - ~HazardPointerThreadEntry(); - - /** - * Gets the guard at the specified position. - * Positions are numbered, beginning with 0. + * \notthreadsafe */ - GuardType GetGuard( - int pos - /**< [IN] Position of the guard */) const; + ~HazardPointer(); /** - * Adds pointer to the retired list + * Guards \c to_guard. If the guarded_element is passed to \c EnqueueForDeletion + * it is prevented from release from now on. The user must have a check, that + * EnqueueForDeletion has not been called on to_guard, before the guarding took + * effect. + * + * \waitfree */ - void AddRetired( - GuardType pointerToGuard - /**< [IN] Guard to retire */); + void Guard( + int guard_position, + /**<[IN] position to place guard*/ + GuardType to_guard + /**<[IN] element to guard*/ + ); /** - * Guards pointer + * Enqueue guarded element for deletion. If not guarded, it is deleted + * immediately. If it is guarded, it is added to a thread local retired list, + * and deleted in a subsequent call to \c EnqueueForDeletion, when no guard is + * placed on it anymore. */ - void GuardPointer( - int guardNumber, - /**< [IN] Position of guard */ - GuardType pointerToGuard - /**<[IN] Pointer to guard */); + void EnqueueForDeletion( + GuardType guarded_element + /**<[IN] element to logically delete*/ + ); /** - * Sets the current thread active, i.e., announce that the thread - * participates in managing hazard pointer. + * Explicitly remove guard from thread local slot. + * + * \waitfree */ - void SetActive( - bool active - /**<[IN] \c true for active, \c false for inactive */); -}; + void RemoveGuard(int guard_position); -/** - * HazardPointer implementation as presented in: - * - * Maged M. Michael. "Hazard pointers: Safe memory reclamation for lock-free - * objects." IEEE Transactions on Parallel and Distributed Systems, 15.6 (2004) - * : 491-504. - * - * In contrast to the original implementation, our implementation only uses - * fixed-size memory. There is a safe upper limit, hazard pointer are guaranteed - * to not consume more memory. Memory is allocated solely at initialization. - * - * Hazard pointers solve the ABA problem for lock-free algorithms. Before - * accessing a pointer, threads announce that they want to access this pointer - * and then check if the pointer is still valid. This announcement is done by - * placing a guard. It is guaranteed that the pointer is not reused until all - * threads remove their guards to this pointer. Objects, these pointers are - * pointing to, can therefore not be deleted directly. Instead, these pointers - * are put into a list for later deletion (retired list). Regularly, this list - * is processed to check which pointers can be deleted. If a pointer can be - * deleted, a callback function provided by the user is called. The user can - * then, e.g., free the respective object, so that the pointer can be safely - * reused. - */ -template< typename GuardType > -class HazardPointer { private: - /** - * Concrete hazard pointer entry type - */ - typedef HazardPointerThreadEntry < GuardType > - HazardPointerThreadEntry_t; - - /** - * The guard value denoting "not guarding" - */ - GuardType undefined_guard; - /** - * The capacity of the retired list (safe upper bound for retired list size) + * HazardPointerTest2 is a white-box test, needing access to private members + * of this class. So declaring it as friend. */ - int retired_list_max_size; + friend class embb::containers::test::HazardPointerTest2; /** - * Guards that can be set per thread + * This number determines the amount of maximal accessors (threads) that + * will access this hazard pointer instance. Note that a thread once + * accessing this object will be permanently count as accessor, even if not + * participating anymore. If too many threads access this object, an + * exception is thrown. */ - int guards_per_thread; + unsigned int max_accessors_count_; /** - * Array of HazardPointerElements. Each thread is assigned to one. + * The guard value denoting "not guarded" */ - HazardPointerThreadEntry_t* hazard_pointer_thread_entry_array; + GuardType undefined_guard_; /** - * The threshold, determines at which size of the retired list pointers - * are tried to be deleted. + * The maximal count of guards that can be set per thread. */ - static const double RETIRE_THRESHOLD; + int max_guards_per_thread_; /** - * Each thread is assigned a thread index (starting with 0). - * Get the index of the current thread. + * The functor that is called to release an object. This is called by this + * class, when it is safe to do so, i.e., no thread accesses this object + * anymore. */ - static unsigned int GetCurrentThreadIndex(); + embb::base::Function release_object_callback_; /** - * The number of hazard pointers currently active. + * Mapping from EMBB thread id to hazard pointer thread ids. Hazard pointer + * thread ids are in range [0;accesor_count-1]. The position of a EMBB thread + * id in that array determines the respective hazard pointer thread id. */ - size_t active_hazard_pointer; + embb::base::Atomic* thread_id_mapping_; /** - * Count of all hazard pointers. + * The hazard pointer guards, represented as array. Each thread has a fixed + * set of slots (guardsPerThread) within this array. */ - size_t hazard_pointers; + embb::base::Atomic* guards_; /** - * The callback that is triggered when a retired guard can be - * freed. Usually, the user will call a free here. + * \see threadLocalRetiredLists documentation */ - embb::base::Function free_guard_callback; + GuardType* thread_local_retired_lists_temp_; /** - * Checks if the current size of the retired list exceeds the threshold, so - * that each retired guard is checked for being not hazardous anymore. - * - * \return \c true is threshold is exceeded, otherwise \c false. - */ - bool IsThresholdExceeded(); - - /** - * Gets the number of hazard pointe, currently active - * - * \return Number of active hazard pointers - */ - size_t GetActiveHazardPointers(); - - /** - * Gets the hazard pointer entry for the current thread - * - * \return Hazard pointer entry for current thread - */ - HazardPointerThreadEntry_t& - GetHazardPointerElementForCurrentThread(); - - /** - * Threads might leave from participating in hazard pointer management. - * This method helps all those threads processing their retired list. - */ - void HelpScan(); - - /** - * Checks the retired list of a hazard pointer entry for elements of the - * retired list that can be freed, and executes the delete callback for those - * elements. - */ - void Scan( - HazardPointerThreadEntry_t* currentHazardPointerEntry - /**<[IN] Hazard pointer entry that should be checked for elements that - can be deleted*/); - - public: - /** - * Gets the capacity of one retired list - * - * \waitfree + * A list of lists, represented as single array. Each thread maintains a list + * of retired pointers, that are objects that are logically released but not + * released because some thread placed a guard on it. */ - size_t GetRetiredListMaxSize() const; + GuardType* thread_local_retired_lists_; /** - * Initializes hazard pointer + * Each thread is assigned a thread index (starting with 0). Get the index of + * the current thread. Note that this is not the global index, but an hazard + * pointer class internal one. The user is free to define less accessors than + * the amount of default threads. This is useful, as the number of accessors + * accounts quadratic for the memory consumption, so the user should have the + * possibility to avoid memory wastage when only having a small, fixed size, + * number of accessors. * - * \notthreadsafe - * - * \memory - * - Let \c t be the number of maximal threads determined by EMBB - * - Let \c g be the number of guards per thread - * - Let \c x be 1.25*t*g + 1 - * - * We dynamically allocate \c x*(3*t+1) elements of size \c sizeof(void*). - */ - HazardPointer( - embb::base::Function free_guard_callback, - /**<[IN] Callback to the function that shall be called when a retired - guard can be deleted */ - GuardType undefined_guard, - /**<[IN] The guard value denoting "not guarded"*/ - int guards_per_thread - /**<[IN] Number of guards per thread*/); - - /** - * Deallocates lists for hazard pointer management. Note that no objects - * currently in the retired lists are deleted. This is the responsibility - * of the user. Usually, HazardPointer manages pointers of an object pool. - * After destructing HazardPointer, the object pool is deleted, so that - * everything is properly cleaned up. - */ - ~HazardPointer(); - - /** - * Announces that the current thread stops participating in hazard pointer - * management. The other threads now take care of his retired list. - * - * \waitfree - */ - void DeactivateCurrentThread(); - - /** - * Guards \c guardedElement with the guard at position \c guardPosition - */ - void GuardPointer(int guardPosition, GuardType guardedElement); - /** - * Enqueue a pointer for deletion. It is added to the retired list and - * deleted when no thread accesses it anymore. - */ - void EnqueuePointerForDeletion(GuardType guardedElement); + * @return current (hazard pointer object local) thread index + */ + unsigned int GetObjectLocalThreadIndex(); + + /** + * Copy retired list \c sourceList to retired list \c targetList + */ + static void CopyRetiredList( + GuardType* source_list, + /**<[IN] the source retired list*/ + GuardType* target_list, + /**<[IN] the target retired list*/ + unsigned int single_retired_list_size, + /**<[IN] the size of a thread local retired list*/ + GuardType undefined_guard + /**<[IN] the undefined guard (usually the NULL pointer)*/ + ); + + static void UpdateRetiredList( + GuardType* retired_list, + /**<[IN] the old retired list*/ + GuardType* updated_retired_list, + /**<[IN] the updated retired list*/ + unsigned int retired_list_size, + /**<[IN] the size of a thread local retired list*/ + GuardType to_retire, + /**<[IN] the element to retire*/ + GuardType considered_hazard, + /**<[IN] the currently considered hazard*/ + GuardType undefined_guard + /**<[IN] the undefined guard (usually the NULL pointer)*/ + ); }; } // namespace internal } // namespace containers diff --git a/containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h b/containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h index c4914e9..a3defd6 100644 --- a/containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h +++ b/containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -77,7 +77,12 @@ LockFreeMPMCQueue::~LockFreeMPMCQueue() { template< typename Type, typename ValuePool > LockFreeMPMCQueue::LockFreeMPMCQueue(size_t capacity) : -capacity(capacity), + capacity(capacity), + // Object pool, size with respect to the maximum number of retired nodes not + // eligible for reuse. +1 for dummy node. + objectPool( + MPMCQueueNodeHazardPointer_t::ComputeMaximumRetiredObjectCount(2) + + capacity + 1), // Disable "this is used in base member initializer" warning. // We explicitly want this. #ifdef EMBB_PLATFORM_COMPILER_MSVC @@ -89,13 +94,7 @@ delete_pointer_callback(*this, #ifdef EMBB_PLATFORM_COMPILER_MSVC #pragma warning(pop) #endif - hazardPointer(delete_pointer_callback, NULL, 2), - // Object pool, size with respect to the maximum number of retired nodes not - // eligible for reuse. +1 for dummy node. - objectPool( - hazardPointer.GetRetiredListMaxSize()* - embb::base::Thread::GetThreadsMaxCount() + - capacity + 1) { + hazardPointer(delete_pointer_callback, NULL, 2) { // Allocate dummy node to reduce the number of special cases to consider. internal::LockFreeMPMCQueueNode* dummyNode = objectPool.Allocate(); // Initially, head and tail point to the dummy node. @@ -120,7 +119,7 @@ bool LockFreeMPMCQueue::TryEnqueue(Type const& element) { for (;;) { my_tail = tail; - hazardPointer.GuardPointer(0, my_tail); + hazardPointer.Guard(0, my_tail); // Check if pointer is still valid after guarding. if (my_tail != tail) { @@ -163,12 +162,12 @@ bool LockFreeMPMCQueue::TryDequeue(Type & element) { Type data; for (;;) { my_head = head; - hazardPointer.GuardPointer(0, my_head); + hazardPointer.Guard(0, my_head); if (my_head != head) continue; my_tail = tail; my_next = my_head->GetNext(); - hazardPointer.GuardPointer(1, my_next); + hazardPointer.Guard(1, my_next); if (head != my_head) continue; if (my_next == NULL) @@ -187,7 +186,7 @@ bool LockFreeMPMCQueue::TryDequeue(Type & element) { break; } - hazardPointer.EnqueuePointerForDeletion(my_head); + hazardPointer.EnqueueForDeletion(my_head); element = data; return true; } diff --git a/containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h b/containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h index 2c29395..70b409f 100644 --- a/containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h +++ b/containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -46,8 +46,8 @@ namespace internal { } template< typename T > - void LockFreeStackNode< T >::SetNext(LockFreeStackNode< T >* next) { - this->next = next; + void LockFreeStackNode< T >::SetNext(LockFreeStackNode< T >* next_to_set) { + this->next = next_to_set; } template< typename T > @@ -81,13 +81,12 @@ capacity(capacity), #ifdef EMBB_PLATFORM_COMPILER_MSVC #pragma warning(pop) #endif - hazardPointer(delete_pointer_callback, NULL, 1), // Object pool, size with respect to the maximum number of retired nodes not // eligible for reuse: objectPool( - hazardPointer.GetRetiredListMaxSize()* - embb::base::Thread::GetThreadsMaxCount() + - capacity) { + StackNodeHazardPointer_t::ComputeMaximumRetiredObjectCount(1) + + capacity), + hazardPointer(delete_pointer_callback, NULL, 1) { } template< typename Type, typename ValuePool > @@ -128,7 +127,7 @@ bool LockFreeStack< Type, ValuePool >::TryPop(Type & element) { return false; // Guard top_cached - hazardPointer.GuardPointer(0, top_cached); + hazardPointer.Guard(0, top_cached); // Check if top is still top. If this is the case, it has not been // retired yet (because before retiring that thing, the retiring thread @@ -144,16 +143,16 @@ bool LockFreeStack< Type, ValuePool >::TryPop(Type & element) { break; } else { // We continue with the next and can unguard top_cached - hazardPointer.GuardPointer(0, NULL); + hazardPointer.Guard(0, NULL); } } Type data = top_cached->GetElement(); // We don't need to read from this reference anymore, unguard it - hazardPointer.GuardPointer(0, NULL); + hazardPointer.Guard(0, NULL); - hazardPointer.EnqueuePointerForDeletion(top_cached); + hazardPointer.EnqueueForDeletion(top_cached); element = data; return true; diff --git a/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h b/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h index 2049174..83b4353 100644 --- a/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h +++ b/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -42,7 +42,7 @@ template bool LockFreeTreeValuePool:: IsLeaf(int node) { - if (node >= size - 1 && node <= 2 * size - 1) { + if (node >= size_ - 1 && node <= 2 * size_ - 1) { return true; } return false; @@ -52,7 +52,7 @@ template bool LockFreeTreeValuePool:: IsValid(int node) { - return (node >= 0 && node <= 2 * size - 1); + return (node >= 0 && node <= 2 * size_ - 1); } template int LockFreeTreeValuePool:: NodeIndexToPoolIndex(int node) { assert(IsLeaf(node)); - return(node - (size - 1)); + return(node - (size_ - 1)); } template int LockFreeTreeValuePool:: PoolIndexToNodeIndex(int index) { - int node = index + (size - 1); + int node = index + (size_ - 1); assert(IsLeaf(node)); return node; } @@ -100,7 +100,7 @@ template int LockFreeTreeValuePool:: GetParentNode(int node) { int parent = (node - 1) / 2; - assert(parent >= 0 && parent < size - 1); + assert(parent >= 0 && parent < size_ - 1); return parent; } @@ -112,11 +112,11 @@ allocate_rec(int node, Type& element) { if (IsLeaf(node)) { int pool_index = NodeIndexToPoolIndex(node); - Type expected = pool[pool_index]; + Type expected = pool_[pool_index]; if (expected == Undefined) return -1; - if (pool[pool_index].CompareAndSwap(expected, Undefined)) { + if (pool_[pool_index].CompareAndSwap(expected, Undefined)) { element = expected; return pool_index; } @@ -131,11 +131,11 @@ allocate_rec(int node, Type& element) { // atomically decrement the value in the node if the result is greater than // or equal to zero. This cannot be done atomically. do { - current = tree[node]; + current = tree_[node]; desired = current - 1; if (desired < 0) return -1; - } while (!tree[node].CompareAndSwap(current, desired)); + } while (!tree_[node].CompareAndSwap(current, desired)); int leftResult = allocate_rec(GetLeftChildIndex(node), element); if (leftResult != -1) { @@ -156,7 +156,7 @@ Fill(int node, int elementsToStore, int power2Value) { if (IsLeaf(node)) return; - tree[node] = elementsToStore; + tree_[node] = elementsToStore; int postPower2Value = power2Value >> 1; @@ -188,14 +188,14 @@ Free(Type element, int index) { assert(element != Undefined); // Put the element back - pool[index].Store(element); + pool_[index].Store(element); - assert(index >= 0 && index < size); + assert(index >= 0 && index < size_); int node = PoolIndexToNodeIndex(index); while (!IsRoot(node)) { node = GetParentNode(node); - tree[node].FetchAndAdd(1); + tree_[node].FetchAndAdd(1); } } @@ -205,37 +205,76 @@ template< typename ForwardIterator > LockFreeTreeValuePool:: LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) { // Number of elements to store - real_size = static_cast(::std::distance(first, last)); + real_size_ = static_cast(::std::distance(first, last)); // Let k be smallest number so that real_size <= 2^k, size = 2^k - size = GetSmallestPowerByTwoValue(real_size); + size_ = GetSmallestPowerByTwoValue(real_size_); // Size of binary tree without the leaves - tree_size = size - 1; + tree_size_ = size_ - 1; + + // make sure, signed values are not negative + assert(tree_size_ >= 0); + assert(real_size_ >= 0); + + size_t tree_size_unsigned = static_cast(tree_size_); + size_t real_size_unsigned = static_cast(real_size_); // Pool stores elements of type T - pool = poolAllocator.allocate(static_cast(real_size)); + pool_ = pool_allocator_.allocate(real_size_unsigned); + + // invoke inplace new for each pool element + for (size_t i = 0; i != real_size_unsigned; ++i) { + new (&pool_[i]) embb::base::Atomic(); + } // Tree holds the counter of not allocated elements - tree = treeAllocator.allocate(static_cast(tree_size)); + tree_ = tree_allocator_.allocate(tree_size_unsigned); + + // invoke inplace new for each tree element + for (size_t i = 0; i != tree_size_unsigned; ++i) { + new (&tree_[i]) embb::base::Atomic(); + } int i = 0; // Store the elements from the range for (ForwardIterator curIter(first); curIter != last; ++curIter) { - pool[i++] = *curIter; + pool_[i++] = *curIter; } // Initialize the binary tree without leaves (counters) - Fill(0, static_cast(::std::distance(first, last)), size); + Fill(0, static_cast(::std::distance(first, last)), size_); } template LockFreeTreeValuePool:: ~LockFreeTreeValuePool() { - poolAllocator.deallocate(pool, static_cast(real_size)); - treeAllocator.deallocate(tree, static_cast(tree_size)); + size_t tree_size_unsigned = static_cast(tree_size_); + size_t real_size_unsigned = static_cast(real_size_); + + // invoke destructor for each pool element + for (size_t i = 0; i != real_size_unsigned; ++i) { + pool_[i].~Atomic(); + } + + pool_allocator_.deallocate(pool_, real_size_unsigned); + + // invoke destructor for each tree element + for (size_t i = 0; i != tree_size_unsigned; ++i) { + tree_[i].~Atomic(); + } + + tree_allocator_.deallocate(tree_, tree_size_unsigned); +} + +template +size_t LockFreeTreeValuePool:: +GetMinimumElementCountForGuaranteedCapacity(size_t capacity) { + // for this value pool, this is just capacity... + return capacity; } } // namespace containers diff --git a/containers_cpp/include/embb/containers/internal/object_pool-inl.h b/containers_cpp/include/embb/containers/internal/object_pool-inl.h index 61711d5..3663c29 100644 --- a/containers_cpp/include/embb/containers/internal/object_pool-inl.h +++ b/containers_cpp/include/embb/containers/internal/object_pool-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -83,7 +83,8 @@ ReturningTrueIterator::operator!=(const self_type& rhs) { template bool ObjectPool:: IsContained(const Type &obj) const { - if ((&obj < &objects[0]) || (&obj > &objects[capacity - 1])) { + if ((&obj < &objects_array_[0]) || + (&obj > &objects_array_[value_pool_size_ - 1])) { return false; } else { return true; @@ -94,17 +95,17 @@ template int ObjectPool:: GetIndexOfObject(const Type &obj) const { assert(IsContained(obj)); - return(static_cast(&obj - &objects[0])); + return(static_cast(&obj - &objects_array_[0])); } template Type* ObjectPool::AllocateRaw() { bool val; - int allocated_index = p.Allocate(val); + int allocated_index = value_pool_.Allocate(val); if (allocated_index == -1) { return NULL; } else { - Type* ret_pointer = &(objects[allocated_index]); + Type* ret_pointer = &(objects_array_[allocated_index]); return ret_pointer; } @@ -112,15 +113,17 @@ Type* ObjectPool::AllocateRaw() { template size_t ObjectPool::GetCapacity() { - return capacity; + return capacity_; } template ObjectPool::ObjectPool(size_t capacity) : -capacity(capacity), - p(ReturningTrueIterator(0), ReturningTrueIterator(capacity)) { - // Allocate the objects (without construction, just get the memory) - objects = objectAllocator.allocate(capacity); + capacity_(capacity), + value_pool_size_( + ValuePool::GetMinimumElementCountForGuaranteedCapacity(capacity)), + value_pool_(ReturningTrueIterator(0), ReturningTrueIterator( + value_pool_size_)), + objects_array_(object_allocator_.allocate(value_pool_size_)) { } template @@ -128,7 +131,7 @@ void ObjectPool::Free(Type* obj) { int index = GetIndexOfObject(*obj); obj->~Type(); - p.Free(true, index); + value_pool_.Free(true, index); } template @@ -189,7 +192,7 @@ Type* ObjectPool::Allocate( template ObjectPool::~ObjectPool() { // Deallocate the objects - objectAllocator.deallocate(objects, capacity); + object_allocator_.deallocate(objects_array_, value_pool_size_); } } // namespace containers } // namespace embb diff --git a/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h b/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h index 1453f1f..049cc44 100644 --- a/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h +++ b/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -35,21 +35,21 @@ Free(Type element, int index) { assert(element != Undefined); // Just put back the element - pool[index].Store(element); + pool_array_[index].Store(element); } template int WaitFreeArrayValuePool:: Allocate(Type & element) { - for (int i = 0; i != size; ++i) { + for (int i = 0; i != size_; ++i) { Type expected; // If the memory cell is not available, go ahead - if (Undefined == (expected = pool[i].Load())) + if (Undefined == (expected = pool_array_[i].Load())) continue; // Try to get the memory cell - if (pool[i].CompareAndSwap(expected, Undefined)) { + if (pool_array_[i].CompareAndSwap(expected, Undefined)) { // When the CAS was successful, this element is ours element = expected; return i; @@ -64,23 +64,45 @@ WaitFreeArrayValuePool:: WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) { size_t dist = static_cast(std::distance(first, last)); - size = static_cast(dist); + size_ = static_cast(dist); + + // conversion may result in negative number. check! + assert(size_ >= 0); // Use the allocator to allocate an array of size dist - pool = allocator.allocate(dist); + pool_array_ = allocator_.allocate(dist); + + // invoke inplace new for each pool element + for ( size_t i = 0; i != dist; ++i ) { + new (&pool_array_[i]) embb::base::Atomic(); + } int i = 0; // Store the elements of the range for (ForwardIterator curIter(first); curIter != last; ++curIter) { - pool[i++] = *curIter; + pool_array_[i++] = *curIter; } } template WaitFreeArrayValuePool::~WaitFreeArrayValuePool() { - allocator.deallocate(pool, (size_t)size); + // invoke destructor for each pool element + for (int i = 0; i != size_; ++i) { + pool_array_[i].~Atomic(); + } + + // free memory + allocator_.deallocate(pool_array_, static_cast(size_)); } + +template +size_t WaitFreeArrayValuePool:: +GetMinimumElementCountForGuaranteedCapacity(size_t capacity) { + // for this value pool, this is just capacity... + return capacity; +} + } // namespace containers } // namespace embb diff --git a/containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h b/containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h index 352e6c8..cc605d4 100644 --- a/containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h +++ b/containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/include/embb/containers/lock_free_mpmc_queue.h b/containers_cpp/include/embb/containers/lock_free_mpmc_queue.h index 37c5439..93c07fb 100644 --- a/containers_cpp/include/embb/containers/lock_free_mpmc_queue.h +++ b/containers_cpp/include/embb/containers/lock_free_mpmc_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -113,8 +113,17 @@ class LockFreeMPMCQueue { * least as many elements, maybe more. */ size_t capacity; - // Do not change the ordering of class local variables. - // Important for initialization. + + /** + * The object pool, used for lock-free memory allocation. + * + * Warning: the objectPool has to be initialized before the hazardPointer + * object, to be sure that the hazardPointer object is destructed before the + * Pool as the hazardPointer object might return elements to the pool in its + * destructor. So the ordering of the members objectPool and hazardPointer is + * important here! + */ + ObjectPool< internal::LockFreeMPMCQueueNode, ValuePool > objectPool; /** * Callback to the method that is called by hazard pointers if a pointer is @@ -124,15 +133,17 @@ class LockFreeMPMCQueue { delete_pointer_callback; /** - * The hazard pointer object, used for memory management. + * Definition of the used hazard pointer type */ - embb::containers::internal::HazardPointer - < internal::LockFreeMPMCQueueNode* > hazardPointer; + typedef embb::containers::internal::HazardPointer + < internal::LockFreeMPMCQueueNode* > + MPMCQueueNodeHazardPointer_t; /** - * The object pool, used for lock-free memory allocation. + * The hazard pointer object, used for memory management. */ - ObjectPool< internal::LockFreeMPMCQueueNode, ValuePool > objectPool; + MPMCQueueNodeHazardPointer_t hazardPointer; + /** * Atomic pointer to the head node of the queue diff --git a/containers_cpp/include/embb/containers/lock_free_stack.h b/containers_cpp/include/embb/containers/lock_free_stack.h index fdcb70c..ebe2079 100644 --- a/containers_cpp/include/embb/containers/lock_free_stack.h +++ b/containers_cpp/include/embb/containers/lock_free_stack.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -187,11 +187,6 @@ class LockFreeStack { delete_pointer_callback; /** - * The hazard pointer object, used for memory management. - */ - internal::HazardPointer*> hazardPointer; - - /** * The callback function, used to cleanup non-hazardous pointers. * \see delete_pointer_callback */ @@ -199,10 +194,27 @@ class LockFreeStack { /** * The object pool, used for lock-free memory allocation. + * + * Warning: the objectPool has to be initialized before the hazardPointer + * object, to be sure that the hazardPointer object is destructed before the + * Pool as the hazardPointer object might return elements to the pool in its + * destructor. So the ordering of the members objectPool and hazardPointer is + * important here! */ ObjectPool< internal::LockFreeStackNode, ValuePool > objectPool; /** + * Definition of the used hazard pointer type + */ + typedef internal::HazardPointer < internal::LockFreeStackNode* > + StackNodeHazardPointer_t; + + /** + * The hazard pointer object, used for memory management. + */ + StackNodeHazardPointer_t hazardPointer; + + /** * Atomic pointer to the top node of the stack (element that is popped next) */ embb::base::Atomic*> top; diff --git a/containers_cpp/include/embb/containers/lock_free_tree_value_pool.h b/containers_cpp/include/embb/containers/lock_free_tree_value_pool.h index 2a14d4c..3dff4cc 100644 --- a/containers_cpp/include/embb/containers/lock_free_tree_value_pool.h +++ b/containers_cpp/include/embb/containers/lock_free_tree_value_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -123,22 +123,25 @@ class LockFreeTreeValuePool { LockFreeTreeValuePool& operator=(const LockFreeTreeValuePool&); // See algorithm description above - int size; + int size_; // See algorithm description above - int tree_size; + int tree_size_; // See algorithm description above - int real_size; + int real_size_; // The tree above the pool - embb::base::Atomic* tree; + embb::base::Atomic* tree_; // The actual pool - embb::base::Atomic* pool; + embb::base::Atomic* pool_; - PoolAllocator poolAllocator; - TreeAllocator treeAllocator; + // respective allocator + PoolAllocator pool_allocator_; + + // respective allocator + TreeAllocator tree_allocator_; /** * Computes smallest power of two fitting the specified value @@ -278,6 +281,18 @@ class LockFreeTreeValuePool { ); /** + * Due to concurrency effects, a pool might provide less elements than managed + * by it. However, usually one wants to guarantee a minimal capacity. The + * count of elements, that must be given to the pool when to guarantee \c + * capacity elements is computed using this function. + * + * \return count of indices the pool has to be initialized with + */ + static size_t GetMinimumElementCountForGuaranteedCapacity( + size_t capacity + /**< [IN] count of indices that shall be guaranteed */); + + /** * Destructs the pool. * * \notthreadsafe diff --git a/containers_cpp/include/embb/containers/object_pool.h b/containers_cpp/include/embb/containers/object_pool.h index 0a94708..f8b9e5c 100644 --- a/containers_cpp/include/embb/containers/object_pool.h +++ b/containers_cpp/include/embb/containers/object_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -35,7 +35,6 @@ namespace embb { namespace containers { - /** * \defgroup CPP_CONTAINERS_POOLS Pools * Concurrent pools @@ -62,22 +61,29 @@ class ObjectPool { /** * Allocator used to allocate elements of the object pool */ - ObjectAllocator objectAllocator; + ObjectAllocator object_allocator_; /** - * Array holding the allocated object + * Capacity of the object pool */ - Type* objects; + size_t capacity_; /** - * Capacity of the object pool + * The size of the underlying value pool. This is also the size of the object + * array in this class. It is assumed, that the valuepool manages indices in + * range [0;value_pool_size_-1]. */ - size_t capacity; + size_t value_pool_size_; /** * Underlying value pool */ - ValuePool p; + ValuePool value_pool_; + + /** + * Array holding the allocated object + */ + Type* objects_array_; /** * Helper providing a virtual iterator that just returns true in each diff --git a/containers_cpp/include/embb/containers/wait_free_array_value_pool.h b/containers_cpp/include/embb/containers/wait_free_array_value_pool.h index 8289ca6..c8a1d2f 100644 --- a/containers_cpp/include/embb/containers/wait_free_array_value_pool.h +++ b/containers_cpp/include/embb/containers/wait_free_array_value_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -39,12 +39,30 @@ namespace containers { * \ingroup CPP_CONCEPT * \{ * \par Description - * A value pool is a fixed-size multiset of elements, where each element has a - * unique index. The elements cannot be modified and are given at construction - * time (by providing first/last iterators). A value pool provides two - * operations: \c Allocate and \c Free. \c Allocate removes an element from the - * pool, and \c Free returns an element to the pool. It is only allowed to - * free elements that have previously been allocated. + * A value pool is a multi-set of elements, where each element has a unique, + * continuous (starting with 0) index. The elements cannot be modified and are + * given at construction time by providing first/last iterators. + * + * \par + * A value pool provides two primary operations: \c Allocate and \c Free. \c + * Allocate allocates an element/index "pair" (index via return, element via + * reference parameter) from the pool, and \c Free returns an element/index pair + * to the pool. To guarantee linearizability, \c element is not allowed to be + * modified between \c Allocate and \c Free. It is only allowed to free elements + * that have previously been allocated. The \c Allocate function does not + * guarantee an order on which indices are allocated. The count of elements that + * can be allocated with \c Allocate might be smaller than the count of + * elements, the pool is initialized with. This might be because of + * implementation details and respective concurrency effects: for example, if + * indices are managed within a queue, one has to protect queue elements from + * concurrency effects (reuse and access). As long as a thread potentially + * accesses a node (and with that an index), the respective index cannot not be + * given out to the user, even if being logically not part of the pool anymore. + * However, the user might want to guarantee a certain amount of indices to the + * user. Therefore, the static \c GetMinimumElementCountForGuaranteedCapacity + * method is used. The user passes the count of indices to this method, that + * shall be guaranteed by the pool. The method returns the count on indices, the + * pool has to be initialized with in order to guarantee this count on indices. * * \par Requirements * - Let \c Pool be the pool class @@ -54,6 +72,7 @@ namespace containers { * - Let \c i, j be forward iterators supporting \c std::distance. * - Let \c c be an object of type \c Type& * - Let \c e be a value of type \c int + * - Let \c f be a value of type \c int * * \par Valid Expressions * @@ -72,7 +91,7 @@ namespace containers { * the bottom element. The bottom element cannot be stored in the pool, it * is exclusively used to mark empty cells. The pool initially contains * \c std::distance(i, j) elements which are copied during construction from - * the range \c [i, j). A concrete class satisfying the value pool concept + * the range \c [i, j]. A concrete class satisfying the value pool concept * might provide additional template parameters for specifying allocators. * * @@ -80,9 +99,10 @@ namespace containers { * \code{.cpp} Allocate(c) \endcode * \c int * - * Gets an element from the pool. Returns -1, if no element is available, - * i.e., the pool is empty. Otherwise, returns the index of the element in - * the pool. The value of the pool element is written into reference \c c. + * Allocates an element/index "pair" from the pool. Returns -1, if no + * element is available, i.e., the pool is empty. Otherwise, returns the + * index of the element in the pool. The value of the pool element is + * written into parameter reference \c c. * * * @@ -93,6 +113,15 @@ namespace containers { * \c Allocate. For each allocated element, \c Free must be called exactly * once. * + * + * \code{.cpp} GetMinimumElementCountForGuaranteedCapacity(f) + * \endcode + * \c void + * Static method, returns the count of indices, the user has to + * initialize the pool with in order to guarantee a count of \c f elements + * (irrespective of concurrency effects). + * + * * * * \} @@ -116,10 +145,10 @@ template > > class WaitFreeArrayValuePool { private: - int size; - embb::base::Atomic* pool; + int size_; + embb::base::Atomic* pool_array_; WaitFreeArrayValuePool(); - Allocator allocator; + Allocator allocator_; // Prevent copy-construction WaitFreeArrayValuePool(const WaitFreeArrayValuePool&); @@ -150,6 +179,18 @@ class WaitFreeArrayValuePool { ); /** + * Due to concurrency effects, a pool might provide less elements than managed + * by it. However, usually one wants to guarantee a minimal capacity. The + * count of elements, that must be given to the pool when to guarantee \c + * capacity elements is computed using this function. + * + * \return count of indices the pool has to be initialized with + */ + static size_t GetMinimumElementCountForGuaranteedCapacity( + size_t capacity + /**< [IN] count of indices that shall be guaranteed */); + + /** * Destructs the pool. * * \notthreadsafe @@ -175,7 +216,7 @@ class WaitFreeArrayValuePool { * Returns an element to the pool. * * \note The element must have been allocated with Allocate(). - * + * * \waitfree * * \see CPP_CONCEPTS_VALUE_POOL diff --git a/containers_cpp/include/embb/containers/wait_free_spsc_queue.h b/containers_cpp/include/embb/containers/wait_free_spsc_queue.h index 30f7235..69eb8dc 100644 --- a/containers_cpp/include/embb/containers/wait_free_spsc_queue.h +++ b/containers_cpp/include/embb/containers/wait_free_spsc_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/src/dummy.cc b/containers_cpp/src/dummy.cc index e95756a..c4fd49d 100644 --- a/containers_cpp/src/dummy.cc +++ b/containers_cpp/src/dummy.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/hazard_pointer_test.cc b/containers_cpp/test/hazard_pointer_test.cc index ab2666c..7a401fc 100644 --- a/containers_cpp/test/hazard_pointer_test.cc +++ b/containers_cpp/test/hazard_pointer_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -31,24 +31,71 @@ namespace embb { namespace containers { namespace test { +IntObjectTestPool::IntObjectTestPool(unsigned int pool_size) : +poolSize(pool_size) { + simplePoolObjects = static_cast( + embb::base::Allocation::Allocate(sizeof(int)*pool_size)); + + simplePool = static_cast*> ( + embb::base::Allocation::Allocate(sizeof(embb::base::Atomic)* + pool_size)); + + for (unsigned int i = 0; i != pool_size; ++i) { + // in-place new for each array cell + new (&simplePool[i]) embb::base::Atomic; + } + + for (unsigned int i = 0; i != pool_size; ++i) { + simplePool[i] = FREE_MARKER; + simplePoolObjects[i] = 0; + } +} + +IntObjectTestPool::~IntObjectTestPool() { + embb::base::Allocation::Free(simplePoolObjects); + + for (unsigned int i = 0; i != poolSize; ++i) { + // in-place new for each array cell + simplePool[i].~Atomic(); + } + + embb::base::Allocation::Free(simplePool); +} + +int* IntObjectTestPool::Allocate() { + for (unsigned int i = 0; i != poolSize; ++i) { + int expected = FREE_MARKER; + if (simplePool[i].CompareAndSwap + (expected, ALLOCATED_MARKER)) { + return &simplePoolObjects[i]; + } + } + return 0; +} + +void IntObjectTestPool::Release(int* object_pointer) { + int cell = object_pointer - simplePoolObjects; + simplePool[cell].Store(FREE_MARKER); +} + HazardPointerTest::HazardPointerTest() : #ifdef EMBB_PLATFORM_COMPILER_MSVC #pragma warning(push) #pragma warning(disable:4355) #endif - delete_pointer_callback(*this, &HazardPointerTest::DeletePointerCallback), +delete_pointer_callback_(*this, &HazardPointerTest::DeletePointerCallback), #ifdef EMBB_PLATFORM_COMPILER_MSVC #pragma warning(pop) #endif - object_pool(NULL), - stack(NULL), - hp(NULL), -n_threads(static_cast + object_pool_(NULL), + stack_(NULL), + hazard_pointer_(NULL), + n_threads_(static_cast (partest::TestSuite::GetDefaultNumThreads())) { - n_elements_per_thread = 100; - n_elements = n_threads*n_elements_per_thread; + n_elements_per_thread_ = 100; + n_elements_ = n_threads_*n_elements_per_thread_; embb::base::Function < void, embb::base::Atomic* > - delete_pointer_callback( + deletePointerCallback( *this, &HazardPointerTest::DeletePointerCallback); @@ -59,41 +106,48 @@ n_threads(static_cast // placed, the pointer is not allowed to be deleted until the second thread // removes this guard. CreateUnit("HazardPointerTestThatGuardWorks"). - Pre(&HazardPointerTest::HazardPointerTest1_Pre, this). + Pre(&HazardPointerTest::HazardPointerTest1Pre, this). Add( - &HazardPointerTest::HazardPointerTest1_ThreadMethod, - this, static_cast(n_threads)). - Post(&HazardPointerTest::HazardPointerTest1_Post, this); + &HazardPointerTest::HazardPointerTest1ThreadMethod, + this, static_cast(n_threads_)). + Post(&HazardPointerTest::HazardPointerTest1Post, this); } -void HazardPointerTest::HazardPointerTest1_Pre() { +void HazardPointerTest::HazardPointerTest1Pre() { embb_internal_thread_index_reset(); - object_pool = new embb::containers::ObjectPool< embb::base::Atomic > - (static_cast(n_elements)); - stack = new embb::containers::LockFreeStack< embb::base::Atomic* > - (static_cast(n_elements)); - hp = new embb::containers::internal::HazardPointer< embb::base::Atomic*> - (delete_pointer_callback, - NULL, + + object_pool_ = + embb::base::Allocation:: + New > > + (static_cast(n_elements_)); + + stack_ = embb::base::Allocation:: + New* > > + (static_cast(n_elements_)); + + hazard_pointer_ = embb::base::Allocation:: + New* > > + (delete_pointer_callback_, + static_cast*>(NULL), 1); } -void HazardPointerTest::HazardPointerTest1_Post() { - delete object_pool; - delete stack; - delete hp; +void HazardPointerTest::HazardPointerTest1Post() { + embb::base::Allocation::Delete(hazard_pointer_); + embb::base::Allocation::Delete(object_pool_); + embb::base::Allocation::Delete(stack_); } -void HazardPointerTest::HazardPointerTest1_ThreadMethod() { +void HazardPointerTest::HazardPointerTest1ThreadMethod() { unsigned int thread_index; embb_internal_thread_index(&thread_index); - for (int i = 0; i != n_elements_per_thread; ++i) { - embb::base::Atomic* allocated_object = object_pool->Allocate(0); + for (int i = 0; i != n_elements_per_thread_; ++i) { + embb::base::Atomic* allocated_object = object_pool_->Allocate(0); - hp->GuardPointer(0, allocated_object); + hazard_pointer_->Guard(0, allocated_object); - bool success = stack->TryPush(allocated_object); + bool success = stack_->TryPush(allocated_object); PT_ASSERT(success == true); @@ -105,51 +159,366 @@ void HazardPointerTest::HazardPointerTest1_ThreadMethod() { bool success_pop; while ( - (success_pop = stack->TryPop(allocated_object_from_different_thread)) + (success_pop = stack_->TryPop(allocated_object_from_different_thread)) == true && allocated_object_from_different_thread == allocated_object ) { - //try to make it probable to get an element from a different thread - //however, can be the same. Try 10000 times to get a different element. + // try to make it probable to get an element from a different thread + // however, can be the same. Try 10000 times to get a different element. if (diff_count++ > 10000) { same = true; break; } - bool success = stack->TryPush(allocated_object_from_different_thread); + success = stack_->TryPush(allocated_object_from_different_thread); PT_ASSERT(success == true); } PT_ASSERT(success_pop == true); allocated_object->Store(1); - hp->EnqueuePointerForDeletion(allocated_object); + hazard_pointer_->EnqueueForDeletion(allocated_object); if (!same) { - hp->GuardPointer(0, allocated_object_from_different_thread); + hazard_pointer_->Guard(0, allocated_object_from_different_thread); // if this holds, we were successful in guarding... otherwise we // were to late, because the pointer has already been added // to the retired list. if (*allocated_object_from_different_thread == 0) { // the pointer must not be deleted here! - vector_mutex.Lock(); + vector_mutex_.Lock(); for (std::vector< embb::base::Atomic* >::iterator - it = deleted_vector.begin(); - it != deleted_vector.end(); + it = deleted_vector_.begin(); + it != deleted_vector_.end(); ++it) { PT_ASSERT(*it != allocated_object_from_different_thread); } - vector_mutex.Unlock(); + vector_mutex_.Unlock(); } - hp->GuardPointer(0, NULL); + hazard_pointer_->Guard(0, NULL); } } } void HazardPointerTest::DeletePointerCallback (embb::base::Atomic* to_delete) { - vector_mutex.Lock(); - deleted_vector.push_back(to_delete); - vector_mutex.Unlock(); + vector_mutex_.Lock(); + deleted_vector_.push_back(to_delete); + vector_mutex_.Unlock(); +} + +void HazardPointerTest2::DeletePointerCallback(int* to_delete) { + test_pool_->Release(to_delete); +} + +bool HazardPointerTest2::SetRelativeGuards() { + unsigned int thread_index; + embb_internal_thread_index(&thread_index); + + unsigned int my_begin = guards_per_phread_count_*thread_index; + int guard_number = 0; + unsigned int alreadyGuarded = 0; + + for (unsigned int i = my_begin; i != my_begin + guards_per_phread_count_; + ++i) { + if (shared_guarded_[i] != 0) { + alreadyGuarded++; + guard_number++; + continue; + } + + int * to_guard = shared_allocated_[i]; + if (to_guard) { + hazard_pointer_->Guard(guard_number, to_guard); + + // changed in the meantime? + if (to_guard == shared_allocated_[i].Load()) { + // guard was successful. Communicate to other threads. + shared_guarded_[i] = to_guard; + } else { + // reset the guard, couldn't guard... + hazard_pointer_->RemoveGuard(guard_number); + } + } + guard_number++; + } + return(alreadyGuarded == guards_per_phread_count_); +} + +void HazardPointerTest2::HazardPointerTest2Master() { + // while the hazard pointer guard array is not full + int** allocatedLocal = static_cast( + embb::base::Allocation::Allocate(sizeof(int*)*guaranteed_capacity_pool_)); + + bool full = false; + while (!full) { + full = true; + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + if (shared_guarded_[i] == 0) { + full = false; + break; + } + } + + // not all guards set + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + allocatedLocal[i] = test_pool_->Allocate(); + shared_allocated_[i].Store(allocatedLocal[i]); + } + + // set my hazards. We do not have to check, this must be successful + // here. + SetRelativeGuards(); + + // free + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + shared_allocated_[i].Store(0); + hazard_pointer_->EnqueueForDeletion(allocatedLocal[i]); + } + } + + embb::base::Allocation::Free(allocatedLocal); +} + +void HazardPointerTest2::HazardPointerTest2Slave() { + unsigned int thread_index; + embb_internal_thread_index(&thread_index); + + while (!SetRelativeGuards()) {} +} + +void HazardPointerTest2::HazardPointerTest2Pre() { + embb_internal_thread_index_reset(); + current_master_ = 0; + sync1_ = 0; + sync2_ = 0; + + // first the test pool has to be created + test_pool_ = embb::base::Allocation::New + (pool_size_using_hazard_pointer_); + + // after the pool has been created, we create the hp class + hazard_pointer_ = embb::base::Allocation::New < + embb::containers::internal::HazardPointer > + (delete_pointer_callback_, static_cast(NULL), + static_cast(guards_per_phread_count_), n_threads); + + shared_guarded_ = static_cast*>( + embb::base::Allocation::Allocate(sizeof(embb::base::Atomic)* + guaranteed_capacity_pool_)); + + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + // in-place new for each array cell + new (&shared_guarded_[i]) embb::base::Atomic < int* >; + } + + shared_allocated_ = static_cast*>( + embb::base::Allocation::Allocate(sizeof(embb::base::Atomic)* + guaranteed_capacity_pool_)); + + for (unsigned int i = 0; i != + guaranteed_capacity_pool_; ++i) { + // in-place new for each array cell + new (&shared_allocated_[i]) embb::base::Atomic < int* >; + } + + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + shared_guarded_[i] = 0; + shared_allocated_[i] = 0; + } +} + +void HazardPointerTest2::HazardPointerTest2Post() { + for (unsigned int i = 0; i != static_cast(n_threads); ++i) { + for (unsigned int i2 = 0; i2 != static_cast(n_threads)* + guards_per_phread_count_; ++i2) { + if (hazard_pointer_->thread_local_retired_lists_ + [i2 + i*n_threads*guards_per_phread_count_] == NULL) { + // all retired lists must be completely filled + PT_ASSERT(false); + } + } + } + + unsigned int checks = 0; + for (unsigned int i = 0; i != static_cast(n_threads); ++i) { + for (unsigned int i2 = 0; i2 != static_cast(n_threads)* + guards_per_phread_count_; ++i2) { + for (unsigned int j = 0; j != static_cast(n_threads); ++j) { + for (unsigned int j2 = 0; j2 != static_cast(n_threads)* + guards_per_phread_count_; ++j2) { + if (i2 == j2 && i == j) + continue; + + // all retired elements have to be disjoint + PT_ASSERT( + hazard_pointer_->thread_local_retired_lists_ + [i2 + i*n_threads*guards_per_phread_count_] != + hazard_pointer_->thread_local_retired_lists_ + [j2 + j*n_threads*guards_per_phread_count_]); + + checks++; + } + } + } + } + + // sanity check on the count of expected comparisons. + PT_ASSERT( + checks == + n_threads*n_threads*guards_per_phread_count_ * + (n_threads*n_threads*guards_per_phread_count_ - 1)); + + std::vector< int* > additionallyAllocated; + + // we should be able to still allocate the guaranteed capacity of + // elements from the pool. + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + int* allocated = test_pool_->Allocate(); + + // allocated is not allowed to be zero + PT_ASSERT(allocated != NULL); + + // push to vector, to check if elements are disjunctive and to release + // afterwards. + additionallyAllocated.push_back(allocated); + } + + // the pool should now be empty + PT_ASSERT(test_pool_->Allocate() == NULL); + + // release allocated elements... + for (unsigned int i = 0; i != additionallyAllocated.size(); ++i) { + test_pool_->Release(additionallyAllocated[i]); + } + + // the additionallyAllocated elements shall be disjoint + for (unsigned int i = 0; i != additionallyAllocated.size(); ++i) { + for (unsigned int i2 = 0; i2 != additionallyAllocated.size(); ++i2) { + if (i == i2) + continue; + PT_ASSERT(additionallyAllocated[i] != + additionallyAllocated[i2]); + } + } + + // no allocated element should be in any retired list... + for (unsigned int a = 0; a != additionallyAllocated.size(); ++a) { + for (unsigned int i = 0; i != static_cast(n_threads); ++i) { + for (unsigned int i2 = 0; i2 != static_cast(n_threads)* + guards_per_phread_count_; ++i2) { + PT_ASSERT( + hazard_pointer_->thread_local_retired_lists_ + [i2 + i*n_threads*guards_per_phread_count_] != + additionallyAllocated[a]); + } + } + } + + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + // in-place new for each array cell + shared_guarded_[i].~Atomic(); + } + + embb::base::Allocation::Free(shared_guarded_); + + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + // in-place new for each array cell + shared_allocated_[i].~Atomic(); + } + + embb::base::Allocation::Free(shared_allocated_); + embb::base::Allocation::Delete(hazard_pointer_); + + // after deleting the hazard pointer object, all retired pointers have + // to be returned to the pool! + std::vector elementsInPool; + + int* nextElement; + while ((nextElement = test_pool_->Allocate()) != NULL) { + for (unsigned int i = 0; i != elementsInPool.size(); ++i) { + // all elements need to be disjoint + PT_ASSERT(elementsInPool[i] != nextElement); + } + elementsInPool.push_back(nextElement); + } + + // all elements should have been returned by the hp object, so we should be + // able to acquire all elements. + PT_ASSERT(elementsInPool.size() == pool_size_using_hazard_pointer_); + + embb::base::Allocation::Delete(test_pool_); +} + +void HazardPointerTest2::HazardPointerTest2ThreadMethod() { + for (;;) { + unsigned int thread_index; + embb_internal_thread_index(&thread_index); + + if (thread_index == current_master_) { + HazardPointerTest2Master(); + } else { + HazardPointerTest2Slave(); + } + + sync1_.FetchAndAdd(1); + + // wait until cleanup thread signals to be finished + while (sync1_ != 0) { + int expected = n_threads; + int desired = FINISH_MARKER; + // select thread, responsible for cleanup + if (sync1_.CompareAndSwap(expected, desired)) { + // wipe arrays! + for (unsigned int i = 0; i != guaranteed_capacity_pool_; ++i) { + shared_guarded_[i] = 0; + shared_allocated_[i] = 0; + } + + // increase master + current_master_.FetchAndAdd(1); + sync2_ = 0; + sync1_.Store(0); + } + } + + // wait for all threads to reach this position + sync2_.FetchAndAdd(1); + while (sync2_ != static_cast(n_threads)) {} + + // if each thread was master once, terminate. + if (current_master_ == static_cast(n_threads)) { + return; + } + } +} + +HazardPointerTest2::HazardPointerTest2() : +n_threads(static_cast +(partest::TestSuite::GetDefaultNumThreads())), + +#ifdef EMBB_PLATFORM_COMPILER_MSVC +#pragma warning(push) +#pragma warning(disable:4355) +#endif + delete_pointer_callback_( + *this, + &HazardPointerTest2::DeletePointerCallback) +#ifdef EMBB_PLATFORM_COMPILER_MSVC +#pragma warning(pop) +#endif +{ + guards_per_phread_count_ = 5; + guaranteed_capacity_pool_ = guards_per_phread_count_*n_threads; + pool_size_using_hazard_pointer_ = guaranteed_capacity_pool_ + + guards_per_phread_count_*n_threads*n_threads; + + embb::base::Thread::GetThreadsMaxCount(); + CreateUnit("HazardPointerTestSimulateMemoryWorstCase"). + Pre(&HazardPointerTest2::HazardPointerTest2Pre, this). + Add( + &HazardPointerTest2::HazardPointerTest2ThreadMethod, + this, static_cast(n_threads)). + Post(&HazardPointerTest2::HazardPointerTest2Post, this); } -} // namespace test -} // namespace containers -} // namespace embb +} // namespace test +} // namespace containers +} // namespace embb diff --git a/containers_cpp/test/hazard_pointer_test.h b/containers_cpp/test/hazard_pointer_test.h index 3e02c6a..fe18def 100644 --- a/containers_cpp/test/hazard_pointer_test.h +++ b/containers_cpp/test/hazard_pointer_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -36,32 +36,112 @@ namespace embb { namespace containers { namespace test { -class HazardPointerTest : public partest::TestCase { +/** + * @brief a very simple wait-free object pool implementation to have tests + * being independent of the EMBB object pool implementation. + */ +class IntObjectTestPool { private: - embb::base::Function*> delete_pointer_callback; + int* simplePoolObjects; + embb::base::Atomic* simplePool; - //used to allocate random stuff, we will just use the pointers, not the - //contents - embb::containers::ObjectPool< embb::base::Atomic >* object_pool; + public: + static const int ALLOCATED_MARKER = 1; + static const int FREE_MARKER = 0; + unsigned int poolSize; - //used to move pointer between threads - embb::containers::LockFreeStack< embb::base::Atomic* >* stack; - embb::base::Mutex vector_mutex; - embb::containers::internal::HazardPointer*>* hp; - std::vector< embb::base::Atomic* > deleted_vector; - int n_threads; - int n_elements_per_thread; - int n_elements; + explicit IntObjectTestPool(unsigned int pool_size); + + ~IntObjectTestPool(); + + /** + * Allocate object from the pool + * + * @return the allocated object + */ + int* Allocate(); + /** + * Return an element to the pool + * + * @param objectPointer the object to be freed + */ + void Release(int* object_pointer); +}; + +class HazardPointerTest : public partest::TestCase { public: /** * Adds test methods. */ HazardPointerTest(); - void HazardPointerTest1_Pre(); - void HazardPointerTest1_Post(); - void HazardPointerTest1_ThreadMethod(); + void HazardPointerTest1Pre(); + void HazardPointerTest1Post(); + void HazardPointerTest1ThreadMethod(); void DeletePointerCallback(embb::base::Atomic* to_delete); + + private: + embb::base::Function*> delete_pointer_callback_; + + //used to allocate random stuff, we will just use the pointers, not the + //contents + embb::containers::ObjectPool< embb::base::Atomic >* object_pool_; + + //used to move pointer between threads + embb::containers::LockFreeStack< embb::base::Atomic* >* stack_; + embb::base::Mutex vector_mutex_; + embb::containers::internal::HazardPointer*>* + hazard_pointer_; + std::vector< embb::base::Atomic* > deleted_vector_; + int n_threads_; + int n_elements_per_thread_; + int n_elements_; +}; + +class HazardPointerTest2 : public partest::TestCase { + public: + void DeletePointerCallback(int* to_delete); + bool SetRelativeGuards(); + void HazardPointerTest2Master(); + void HazardPointerTest2Slave(); + + void HazardPointerTest2Pre(); + void HazardPointerTest2Post(); + + void HazardPointerTest2ThreadMethod(); + + HazardPointerTest2(); + + private: + // number of threads, participating in that test + int n_threads; + + embb::base::Function delete_pointer_callback_; + // the thread id of the master + embb::base::Atomic current_master_; + + // variables, to synchronize threads. At each point in time, one master, + // the master changes each round until each thread was assigned master once. + embb::base::Atomic sync1_; + embb::base::Atomic sync2_; + + unsigned int guards_per_phread_count_; + unsigned int guaranteed_capacity_pool_; + unsigned int pool_size_using_hazard_pointer_; + + // The threads write here, if they guarded an object successfully. Used to + // determine when all allocated objects were guarded successfully. + embb::base::Atomic* shared_guarded_; + + // This array is used by the master, to communicate and share what he has + // allocated with the slaves. + embb::base::Atomic* shared_allocated_; + + // Reference to the object pool + IntObjectTestPool* test_pool_; + + embb::containers::internal::HazardPointer* hazard_pointer_; + static const int FINISH_MARKER = -1; }; } // namespace test } // namespace containers diff --git a/containers_cpp/test/main.cc b/containers_cpp/test/main.cc index 0e26fee..d21dede 100644 --- a/containers_cpp/test/main.cc +++ b/containers_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -55,6 +55,7 @@ using embb::containers::test::HazardPointerTest; using embb::containers::test::QueueTest; using embb::containers::test::StackTest; using embb::containers::test::ObjectPoolTest; +using embb::containers::test::HazardPointerTest2; PT_MAIN("Data Structures C++") { unsigned int max_threads = static_cast( @@ -64,6 +65,7 @@ PT_MAIN("Data Structures C++") { PT_RUN(PoolTest< WaitFreeArrayValuePool >); PT_RUN(PoolTest< LockFreeTreeValuePool >); PT_RUN(HazardPointerTest); + PT_RUN(HazardPointerTest2); PT_RUN(QueueTest< WaitFreeSPSCQueue< ::std::pair > >); PT_RUN(QueueTest< LockFreeMPMCQueue< ::std::pair > COMMA true COMMA true >); diff --git a/containers_cpp/test/object_pool_test-inl.h b/containers_cpp/test/object_pool_test-inl.h index db340b2..cafe7e7 100644 --- a/containers_cpp/test/object_pool_test-inl.h +++ b/containers_cpp/test/object_pool_test-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/object_pool_test.cc b/containers_cpp/test/object_pool_test.cc index ccc91ac..6425154 100644 --- a/containers_cpp/test/object_pool_test.cc +++ b/containers_cpp/test/object_pool_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/object_pool_test.h b/containers_cpp/test/object_pool_test.h index 4c5c177..92fb9e8 100644 --- a/containers_cpp/test/object_pool_test.h +++ b/containers_cpp/test/object_pool_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/pool_test-inl.h b/containers_cpp/test/pool_test-inl.h index 2c74935..3208775 100644 --- a/containers_cpp/test/pool_test-inl.h +++ b/containers_cpp/test/pool_test-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -165,7 +165,6 @@ void PoolTest::PoolTestStatic() { //if we allocate again, we should get those elements for (int i = 0; i != static_cast(indexes_to_free.size()); i++) { - int element, index; index = ap.Allocate(element); PT_EXPECT((index != -1)); diff --git a/containers_cpp/test/pool_test.h b/containers_cpp/test/pool_test.h index 16fcbd9..63c1586 100644 --- a/containers_cpp/test/pool_test.h +++ b/containers_cpp/test/pool_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/queue_test-inl.h b/containers_cpp/test/queue_test-inl.h index 3e63930..ac96b48 100644 --- a/containers_cpp/test/queue_test-inl.h +++ b/containers_cpp/test/queue_test-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/queue_test.h b/containers_cpp/test/queue_test.h index 22b7381..95a1585 100644 --- a/containers_cpp/test/queue_test.h +++ b/containers_cpp/test/queue_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/stack_test-inl.h b/containers_cpp/test/stack_test-inl.h index 6e82d4d..18ef724 100644 --- a/containers_cpp/test/stack_test-inl.h +++ b/containers_cpp/test/stack_test-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/containers_cpp/test/stack_test.h b/containers_cpp/test/stack_test.h index 449ae7e..0ea801d 100644 --- a/containers_cpp/test/stack_test.h +++ b/containers_cpp/test/stack_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/dataflow.h b/dataflow_cpp/include/embb/dataflow/dataflow.h index 376206f..73d6151 100644 --- a/dataflow_cpp/include/embb/dataflow/dataflow.h +++ b/dataflow_cpp/include/embb/dataflow/dataflow.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/action.h b/dataflow_cpp/include/embb/dataflow/internal/action.h index 2b85680..61f4cfa 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/action.h +++ b/dataflow_cpp/include/embb/dataflow/internal/action.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -39,29 +39,22 @@ namespace internal { class Action { public: - Action() : node_(NULL), clock_(0), pending_(0) {} - Action(Node * node, int clock) : node_(node), clock_(clock), pending_(2) {} + Action() : node_(NULL), clock_(0) {} + Action(Node * node, int clock) : node_(node), clock_(clock) {} void RunSequential() { - pending_ = 1; node_->Run(clock_); - pending_ = 0; } void RunMTAPI(embb::tasks::TaskContext & /*context*/) { - pending_ = 1; node_->Run(clock_); - pending_ = 0; } - bool IsPending() const { return pending_ > 0; } - int GetClock() const { return clock_; } private: Node * node_; int clock_; - volatile int pending_; }; } // namespace internal diff --git a/dataflow_cpp/include/embb/dataflow/internal/clock_listener.h b/dataflow_cpp/include/embb/dataflow/internal/clock_listener.h index 5234740..deff2fc 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/clock_listener.h +++ b/dataflow_cpp/include/embb/dataflow/internal/clock_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/constant_source.h b/dataflow_cpp/include/embb/dataflow/internal/constant_source.h index 4ec14af..cb09293 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/constant_source.h +++ b/dataflow_cpp/include/embb/dataflow/internal/constant_source.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/in.h b/dataflow_cpp/include/embb/dataflow/internal/in.h index 71034cb..666146b 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/in.h +++ b/dataflow_cpp/include/embb/dataflow/internal/in.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -29,7 +29,7 @@ #if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY #include -#include +#include #endif #include @@ -80,7 +80,7 @@ class In { ClockListener * listener_; bool connected_; #if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY - SpinLock lock_; + embb::base::Spinlock lock_; std::vector history_; #endif diff --git a/dataflow_cpp/include/embb/dataflow/internal/inputs.h b/dataflow_cpp/include/embb/dataflow/internal/inputs.h index 7fc87b6..211fdb5 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/inputs.h +++ b/dataflow_cpp/include/embb/dataflow/internal/inputs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/node.h b/dataflow_cpp/include/embb/dataflow/internal/node.h index ab47fee..55c5526 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/node.h +++ b/dataflow_cpp/include/embb/dataflow/internal/node.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/out.h b/dataflow_cpp/include/embb/dataflow/internal/out.h index 9c2f1a1..d81dae0 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/out.h +++ b/dataflow_cpp/include/embb/dataflow/internal/out.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/outputs.h b/dataflow_cpp/include/embb/dataflow/internal/outputs.h index cf926b0..9710501 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/outputs.h +++ b/dataflow_cpp/include/embb/dataflow/internal/outputs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/process.h b/dataflow_cpp/include/embb/dataflow/internal/process.h index 4f5bc3f..4f6ea3e 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/process.h +++ b/dataflow_cpp/include/embb/dataflow/internal/process.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -102,8 +102,9 @@ class Process< Slices, Serial, Inputs, } template - void operator >> (T & target) { + T & operator >> (T & target) { GetOutput<0>() >> target.template GetInput<0>(); + return target; } virtual void OnClock(int clock) { diff --git a/dataflow_cpp/include/embb/dataflow/internal/process_executor.h b/dataflow_cpp/include/embb/dataflow/internal/process_executor.h index 4219cea..6020417 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/process_executor.h +++ b/dataflow_cpp/include/embb/dataflow/internal/process_executor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler.h index 5770217..9f86e96 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h index 8f1271e..9d26bfc 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -32,6 +32,8 @@ #include #include +#include + namespace embb { namespace dataflow { namespace internal { @@ -46,7 +48,9 @@ class SchedulerMTAPI : public Scheduler { group_[ii] = &group; } - queue_count_ = static_cast(node.GetWorkerThreadCount()); + queue_count_ = std::min( + static_cast(node.GetQueueCount()), + static_cast(node.GetWorkerThreadCount()) ); queue_ = reinterpret_cast( embb::base::Allocation::Allocate( sizeof(embb::tasks::Queue*)*queue_count_)); diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h index 919a3a3..575fea3 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/select.h b/dataflow_cpp/include/embb/dataflow/internal/select.h index f3a499f..85b288b 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/select.h +++ b/dataflow_cpp/include/embb/dataflow/internal/select.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -105,8 +105,9 @@ class Select } template - void operator >> (T & target) { + T & operator >> (T & target) { GetOutput<0>() >> target.template GetInput<0>(); + return target; } virtual void OnClock(int clock) { diff --git a/dataflow_cpp/include/embb/dataflow/internal/signal.h b/dataflow_cpp/include/embb/dataflow/internal/signal.h index dde39cc..4931681 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/signal.h +++ b/dataflow_cpp/include/embb/dataflow/internal/signal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/sink.h b/dataflow_cpp/include/embb/dataflow/internal/sink.h index 2c835ed..7b76c92 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/sink.h +++ b/dataflow_cpp/include/embb/dataflow/internal/sink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/sink_executor.h b/dataflow_cpp/include/embb/dataflow/internal/sink_executor.h index 447602d..75bf604 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/sink_executor.h +++ b/dataflow_cpp/include/embb/dataflow/internal/sink_executor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/source.h b/dataflow_cpp/include/embb/dataflow/internal/source.h index 72f198b..67bd37f 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/source.h +++ b/dataflow_cpp/include/embb/dataflow/internal/source.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -27,6 +27,8 @@ #ifndef EMBB_DATAFLOW_INTERNAL_SOURCE_H_ #define EMBB_DATAFLOW_INTERNAL_SOURCE_H_ +#include + #include #include #include @@ -81,14 +83,15 @@ class Source< Slices, Outputs > } template - void operator >> (T & target) { + T & operator >> (T & target) { GetOutput<0>() >> target.template GetInput<0>(); + return target; } private: OutputsType outputs_; ExecutorType executor_; - volatile bool not_done_; + embb::base::Atomic not_done_; }; } // namespace internal diff --git a/dataflow_cpp/include/embb/dataflow/internal/source_executor.h b/dataflow_cpp/include/embb/dataflow/internal/source_executor.h index 1461285..bf26ae0 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/source_executor.h +++ b/dataflow_cpp/include/embb/dataflow/internal/source_executor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -53,7 +53,9 @@ class SourceExecutor< Outputs > { Outputs & outputs) { O1 o1; bool result = function_(o1); - outputs.template Get<0>().Send(Signal(clock, o1)); + if (result) { + outputs.template Get<0>().Send(Signal(clock, o1)); + } return result; } @@ -78,8 +80,10 @@ class SourceExecutor< Outputs > { O1 o1; O2 o2; bool result = function_(o1, o2); - outputs.template Get<0>().Send(Signal(clock, o1)); - outputs.template Get<1>().Send(Signal(clock, o2)); + if (result) { + outputs.template Get<0>().Send(Signal(clock, o1)); + outputs.template Get<1>().Send(Signal(clock, o2)); + } return result; } @@ -106,9 +110,11 @@ class SourceExecutor< Outputs > { O2 o2; O3 o3; bool result = function_(o1, o2, o3); - outputs.template Get<0>().Send(Signal(clock, o1)); - outputs.template Get<1>().Send(Signal(clock, o2)); - outputs.template Get<2>().Send(Signal(clock, o3)); + if (result) { + outputs.template Get<0>().Send(Signal(clock, o1)); + outputs.template Get<1>().Send(Signal(clock, o2)); + outputs.template Get<2>().Send(Signal(clock, o3)); + } return result; } @@ -137,10 +143,12 @@ class SourceExecutor< Outputs > { O3 o3; O4 o4; bool result = function_(o1, o2, o3, o4); - outputs.template Get<0>().Send(Signal(clock, o1)); - outputs.template Get<1>().Send(Signal(clock, o2)); - outputs.template Get<2>().Send(Signal(clock, o3)); - outputs.template Get<3>().Send(Signal(clock, o4)); + if (result) { + outputs.template Get<0>().Send(Signal(clock, o1)); + outputs.template Get<1>().Send(Signal(clock, o2)); + outputs.template Get<2>().Send(Signal(clock, o3)); + outputs.template Get<3>().Send(Signal(clock, o4)); + } return result; } @@ -172,11 +180,13 @@ class SourceExecutor< Outputs > { O4 o4; O5 o5; bool result = function_(o1, o2, o3, o4, o5); - outputs.template Get<0>().Send(Signal(clock, o1)); - outputs.template Get<1>().Send(Signal(clock, o2)); - outputs.template Get<2>().Send(Signal(clock, o3)); - outputs.template Get<3>().Send(Signal(clock, o4)); - outputs.template Get<4>().Send(Signal(clock, o5)); + if (result) { + outputs.template Get<0>().Send(Signal(clock, o1)); + outputs.template Get<1>().Send(Signal(clock, o2)); + outputs.template Get<2>().Send(Signal(clock, o3)); + outputs.template Get<3>().Send(Signal(clock, o4)); + outputs.template Get<4>().Send(Signal(clock, o5)); + } return result; } diff --git a/dataflow_cpp/include/embb/dataflow/internal/switch.h b/dataflow_cpp/include/embb/dataflow/internal/switch.h index 3bf36ee..caecc20 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/switch.h +++ b/dataflow_cpp/include/embb/dataflow/internal/switch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -103,8 +103,9 @@ class Switch } template - void operator >> (T & target) { + T & operator >> (T & target) { GetOutput<0>() >> target.template GetInput<0>(); + return target; } virtual void OnClock(int clock) { diff --git a/dataflow_cpp/include/embb/dataflow/internal/tuple.h b/dataflow_cpp/include/embb/dataflow/internal/tuple.h index f03f9ff..c5f7981 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/tuple.h +++ b/dataflow_cpp/include/embb/dataflow/internal/tuple.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/internal/typelist.h b/dataflow_cpp/include/embb/dataflow/internal/typelist.h index 4c25272..a193909 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/typelist.h +++ b/dataflow_cpp/include/embb/dataflow/internal/typelist.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/include/embb/dataflow/network.h b/dataflow_cpp/include/embb/dataflow/network.h index 33dbaff..94a2e1a 100644 --- a/dataflow_cpp/include/embb/dataflow/network.h +++ b/dataflow_cpp/include/embb/dataflow/network.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/src/node.cc b/dataflow_cpp/src/node.cc index 55b91c7..cc5e031 100644 --- a/dataflow_cpp/src/node.cc +++ b/dataflow_cpp/src/node.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/test/dataflow_cpp_test_simple.cc b/dataflow_cpp/test/dataflow_cpp_test_simple.cc index b434625..20ac9b3 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_simple.cc +++ b/dataflow_cpp/test/dataflow_cpp_test_simple.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -56,12 +56,16 @@ embb::base::Atomic source_counter; int source_array[TEST_COUNT]; bool sourceFunc(int & out) { - out = source_counter; + if (source_counter < TEST_COUNT) { + out = source_counter; - source_array[source_counter] = out; - source_counter++; + source_array[source_counter] = out; + source_counter++; - return source_counter < TEST_COUNT; + return true; + } else { + return false; + } } embb::base::Atomic pred_counter; @@ -149,14 +153,13 @@ SimpleTest::SimpleTest() { void SimpleTest::TestBasic() { // All available cores embb::base::CoreSet core_set(true); - unsigned int num_cores = core_set.Count(); embb::tasks::Node::Initialize( MTAPI_DOMAIN_ID, MTAPI_NODE_ID, core_set, 1024, // max tasks (default: 1024) 128, // max groups (default: 128) - num_cores, // max queues (default: 16) + 2, // max queues (default: 16) 1024, // queue capacity (default: 1024) 4); // num priorities (default: 4) @@ -189,11 +192,14 @@ void SimpleTest::TestBasic() { source.GetOutput<0>() >> sw.GetInput<1>(); - source.GetOutput<0>() >> pred.GetInput<0>(); - pred.GetOutput<0>() >> sw.GetInput<0>(); + // connection chain representing the commented single connections below + source >> pred >> sw >> filter; + + //source.GetOutput<0>() >> pred.GetInput<0>(); + //pred.GetOutput<0>() >> sw.GetInput<0>(); pred.GetOutput<0>() >> sel.GetInput<0>(); - sw.GetOutput<0>() >> filter.GetInput<0>(); + //sw.GetOutput<0>() >> filter.GetInput<0>(); filter.GetOutput<0>() >> sel.GetInput<1>(); constant.GetOutput<0>() >> mult.GetInput<0>(); diff --git a/dataflow_cpp/test/dataflow_cpp_test_simple.h b/dataflow_cpp/test/dataflow_cpp_test_simple.h index b1ffea9..d4fc9c1 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_simple.h +++ b/dataflow_cpp/test/dataflow_cpp_test_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/test/dataflow_cpp_test_tuple.cc b/dataflow_cpp/test/dataflow_cpp_test_tuple.cc index 0d54432..640b37f 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_tuple.cc +++ b/dataflow_cpp/test/dataflow_cpp_test_tuple.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/test/dataflow_cpp_test_tuple.h b/dataflow_cpp/test/dataflow_cpp_test_tuple.h index 31bc3bb..3013d50 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_tuple.h +++ b/dataflow_cpp/test/dataflow_cpp_test_tuple.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/dataflow_cpp/test/main.cc b/dataflow_cpp/test/main.cc index 0db1d7c..7e09ac1 100644 --- a/dataflow_cpp/test/main.cc +++ b/dataflow_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/CMakeLists.txt b/doc/examples/CMakeLists.txt index d68a8a3..31c07d2 100644 --- a/doc/examples/CMakeLists.txt +++ b/doc/examples/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/../../base_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_network_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_plugins_c/mtapi_network_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../tasks_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../../tasks_cpp/include @@ -21,12 +21,12 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../dataflow_cpp/include ) -if(OpenCL_FOUND) +if(BUILD_OPENCL_PLUGIN STREQUAL ON) # used in source code, to include opencl code add_definitions(-DEMBB_WITH_OPENCL) # add opencl includes include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_opencl_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_plugins_c/mtapi_opencl_c/include ) # later used, to link opencl to target... set (EMBB_MTAPI_OPENCL_C_CONDITIONAL "embb_mtapi_opencl_c") diff --git a/doc/examples/algorithms/counting/counting-fragmented.cc b/doc/examples/algorithms/counting/counting-fragmented.cc index a621d8b..63a4846 100644 --- a/doc/examples/algorithms/counting/counting-fragmented.cc +++ b/doc/examples/algorithms/counting/counting-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/algorithms/for_each/for_each-fragmented.cc b/doc/examples/algorithms/for_each/for_each-fragmented.cc index ab80a0c..99aeea4 100644 --- a/doc/examples/algorithms/for_each/for_each-fragmented.cc +++ b/doc/examples/algorithms/for_each/for_each-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/algorithms/invoke/invoke-fragmented.cc b/doc/examples/algorithms/invoke/invoke-fragmented.cc index 94cddd2..925dbaa 100644 --- a/doc/examples/algorithms/invoke/invoke-fragmented.cc +++ b/doc/examples/algorithms/invoke/invoke-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/algorithms/reduce/reduce-fragmented.cc b/doc/examples/algorithms/reduce/reduce-fragmented.cc index 4c9f1df..5fad70c 100644 --- a/doc/examples/algorithms/reduce/reduce-fragmented.cc +++ b/doc/examples/algorithms/reduce/reduce-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/algorithms/scan/scan-fragmented.cc b/doc/examples/algorithms/scan/scan-fragmented.cc index 3a9c1d3..cf1e84f 100644 --- a/doc/examples/algorithms/scan/scan-fragmented.cc +++ b/doc/examples/algorithms/scan/scan-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/algorithms/sorting/sorting-fragmented.cc b/doc/examples/algorithms/sorting/sorting-fragmented.cc index 36cb1ed..5872b63 100644 --- a/doc/examples/algorithms/sorting/sorting-fragmented.cc +++ b/doc/examples/algorithms/sorting/sorting-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/containers/object_pool-fragmented.cc b/doc/examples/containers/object_pool-fragmented.cc index fb7ee1b..2be5dd5 100644 --- a/doc/examples/containers/object_pool-fragmented.cc +++ b/doc/examples/containers/object_pool-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/containers/queues-fragmented.cc b/doc/examples/containers/queues-fragmented.cc index 0b6eaff..89f3a73 100644 --- a/doc/examples/containers/queues-fragmented.cc +++ b/doc/examples/containers/queues-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/containers/queues-snippet.h b/doc/examples/containers/queues-snippet.h index 951f5c3..4e3a24b 100644 --- a/doc/examples/containers/queues-snippet.h +++ b/doc/examples/containers/queues-snippet.h @@ -4,12 +4,12 @@ int i, j; bool result = queue.TryDequeue(i); //@\label{lst:queue_lst1:fail_pop}@ assert(result == false); -for (int i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop1}@ +for (i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop1}@ result = queue.TryEnqueue(i); //@\label{lst:queue_lst1:push}@ assert(result == true); } -for (int i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop2}@ +for (i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop2}@ result = queue.TryDequeue(j); //@\label{lst:queue_lst1:pop}@ assert(result == true && i == j); //@\label{lst:queue_lst1:assert}@ } \ No newline at end of file diff --git a/doc/examples/containers/stack-fragmented.cc b/doc/examples/containers/stack-fragmented.cc index 31adda7..5da21d4 100644 --- a/doc/examples/containers/stack-fragmented.cc +++ b/doc/examples/containers/stack-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/containers/stack-snippet.h b/doc/examples/containers/stack-snippet.h index dce744f..057ebe5 100644 --- a/doc/examples/containers/stack-snippet.h +++ b/doc/examples/containers/stack-snippet.h @@ -4,12 +4,12 @@ int i, j; bool result = stack.TryPop(i); //@\label{lst:stack_lst1:fail_pop}@ assert(result == false); -for (int i = 0; i <= 4; ++i) {//@\label{lst:stack_lst1:loop1}@ +for (i = 0; i <= 4; ++i) {//@\label{lst:stack_lst1:loop1}@ result = stack.TryPush(i); //@\label{lst:stack_lst1:push}@ assert(result == true); } -for (int i = 4; i >= 0; --i) { //@\label{lst:stack_lst1:loop2}@ +for (i = 4; i >= 0; --i) { //@\label{lst:stack_lst1:loop2}@ result = stack.TryPop(j); //@\label{lst:stack_lst1:pop}@ assert(result == true && i == j); //@\label{lst:stack_lst1:assert}@ } \ No newline at end of file diff --git a/doc/examples/dataflow/dataflow_connect-snippet.h b/doc/examples/dataflow/dataflow_connect-snippet.h index 6660f53..7c7537e 100644 --- a/doc/examples/dataflow/dataflow_connect-snippet.h +++ b/doc/examples/dataflow/dataflow_connect-snippet.h @@ -1,2 +1 @@ - read >> replace; - replace >> write; + read >> replace >> write; diff --git a/doc/examples/dataflow/dataflow_linear-fragmented.cc b/doc/examples/dataflow/dataflow_linear-fragmented.cc index 25bdacd..66c6fcc 100644 --- a/doc/examples/dataflow/dataflow_linear-fragmented.cc +++ b/doc/examples/dataflow/dataflow_linear-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/dataflow/dataflow_nonlinear-fragmented.cc b/doc/examples/dataflow/dataflow_nonlinear-fragmented.cc index e7f419d..e3e664a 100644 --- a/doc/examples/dataflow/dataflow_nonlinear-fragmented.cc +++ b/doc/examples/dataflow/dataflow_nonlinear-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/dataflow/dataflow_producer-snippet.h b/doc/examples/dataflow/dataflow_producer-snippet.h index ffaf79e..f76065c 100644 --- a/doc/examples/dataflow/dataflow_producer-snippet.h +++ b/doc/examples/dataflow/dataflow_producer-snippet.h @@ -3,10 +3,14 @@ class Producer { public: explicit Producer(int seed) : seed_(seed), count_(4) {} bool Run(T& x) { - // produce a new value x - x = SimpleRand(seed_); - count_--; - return count_ >= 0; + if (count_ >= 0) { + // produce a new value x + x = SimpleRand(seed_); + count_--; + return true; + } else { + return false; + } } private: diff --git a/doc/examples/dataflow/dataflow_source_function-snippet.h b/doc/examples/dataflow/dataflow_source_function-snippet.h index 6c1cdea..1afc660 100644 --- a/doc/examples/dataflow/dataflow_source_function-snippet.h +++ b/doc/examples/dataflow/dataflow_source_function-snippet.h @@ -1,4 +1,8 @@ bool SourceFunction(std::string & str) { - std::getline(file, str); - return !file.eof(); + if (!file.eof()) { + std::getline(file, str); + return true; + } else { + return false; + } } diff --git a/doc/examples/main.cc b/doc/examples/main.cc index 7888d4b..80b9c3c 100644 --- a/doc/examples/main.cc +++ b/doc/examples/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/mtapi/mtapi_c-fragmented.cc b/doc/examples/mtapi/mtapi_c-fragmented.cc index d543e12..735d30a 100644 --- a/doc/examples/mtapi/mtapi_c-fragmented.cc +++ b/doc/examples/mtapi/mtapi_c-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/mtapi/mtapi_c_network-fragmented.cc b/doc/examples/mtapi/mtapi_c_network-fragmented.cc index 777e74c..0cc5026 100644 --- a/doc/examples/mtapi/mtapi_c_network-fragmented.cc +++ b/doc/examples/mtapi/mtapi_c_network-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/mtapi/mtapi_c_opencl-fragmented.cc b/doc/examples/mtapi/mtapi_c_opencl-fragmented.cc index 074744a..ea0f67b 100644 --- a/doc/examples/mtapi/mtapi_c_opencl-fragmented.cc +++ b/doc/examples/mtapi/mtapi_c_opencl-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/mtapi/mtapi_c_plugin-fragmented.cc b/doc/examples/mtapi/mtapi_c_plugin-fragmented.cc index b072164..bbbcc70 100644 --- a/doc/examples/mtapi/mtapi_c_plugin-fragmented.cc +++ b/doc/examples/mtapi/mtapi_c_plugin-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/mtapi/mtapi_cpp-fragmented.cc b/doc/examples/mtapi/mtapi_cpp-fragmented.cc index d211fd9..427039e 100644 --- a/doc/examples/mtapi/mtapi_cpp-fragmented.cc +++ b/doc/examples/mtapi/mtapi_cpp-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/stl_for_each/stl_for_each-fragmented.cc b/doc/examples/stl_for_each/stl_for_each-fragmented.cc index ecff00b..bd5aa21 100644 --- a/doc/examples/stl_for_each/stl_for_each-fragmented.cc +++ b/doc/examples/stl_for_each/stl_for_each-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/examples/tasks/tasks_cpp-fragmented.cc b/doc/examples/tasks/tasks_cpp-fragmented.cc index 4e13885..5443760 100644 --- a/doc/examples/tasks/tasks_cpp-fragmented.cc +++ b/doc/examples/tasks/tasks_cpp-fragmented.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/doc/reference/Doxyfile.in b/doc/reference/Doxyfile.in index 8ab6642..c240844 100644 --- a/doc/reference/Doxyfile.in +++ b/doc/reference/Doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: @@ -153,8 +153,8 @@ INPUT = "@CMAKE_SOURCE_DIR@/doc/reference/embb.dox" \ "@CMAKE_SOURCE_DIR@/base_cpp/include" \ "@CMAKE_SOURCE_DIR@/mtapi_c/include" \ "@CMAKE_SOURCE_DIR@/base_c/include" \ - "@CMAKE_SOURCE_DIR@/mtapi_opencl_c/include" \ - "@CMAKE_SOURCE_DIR@/mtapi_network_c/include" + "@CMAKE_SOURCE_DIR@/mtapi_plugins_c/mtapi_opencl_c/include" \ + "@CMAKE_SOURCE_DIR@/mtapi_plugins_c/mtapi_network_c/include" INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.h \ diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index 4e969e1..39e3c12 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -81,7 +81,7 @@ % 1st paramter: a square(!) picture % 2nd parameter: short tile (one line) % 3rd parameter: long title (up to two lines) -\gentitlepage{pics/chicago-square.jpg}{\LARGE Siemens Corporate Technology | \monthword{\month} 2015}{\scalebox{0.9}{Embedded Multicore Building Blocks}\\\scalebox{0.9}{Introduction and Tutorial}} +\gentitlepage{pics/chicago-square.jpg}{\LARGE Siemens Corporate Technology | \monthword{\month} 2016}{\scalebox{0.9}{Embedded Multicore Building Blocks}\\\scalebox{0.9}{Introduction and Tutorial}} % List the authors and contributors on the second page, right after the cover page % 1st parameter: contributors (optional) diff --git a/mtapi_c/include/mtapi.h b/mtapi_c/include/mtapi.h index e25eb56..7ac0853 100644 --- a/mtapi_c/include/mtapi.h +++ b/mtapi_c/include/mtapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_action_t.c b/mtapi_c/src/embb_mtapi_action_t.c index c062bdd..dff3606 100644 --- a/mtapi_c/src/embb_mtapi_action_t.c +++ b/mtapi_c/src/embb_mtapi_action_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_action_t.h b/mtapi_c/src/embb_mtapi_action_t.h index 0d6848f..7fd7533 100644 --- a/mtapi_c/src/embb_mtapi_action_t.h +++ b/mtapi_c/src/embb_mtapi_action_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_action_t_fwd.h b/mtapi_c/src/embb_mtapi_action_t_fwd.h index 27944d7..f8a4a66 100644 --- a/mtapi_c/src/embb_mtapi_action_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_action_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_alloc.c b/mtapi_c/src/embb_mtapi_alloc.c index 7a5d397..5b02614 100644 --- a/mtapi_c/src/embb_mtapi_alloc.c +++ b/mtapi_c/src/embb_mtapi_alloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_alloc.h b/mtapi_c/src/embb_mtapi_alloc.h index f5a2ec1..6644444 100644 --- a/mtapi_c/src/embb_mtapi_alloc.h +++ b/mtapi_c/src/embb_mtapi_alloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_attr.c b/mtapi_c/src/embb_mtapi_attr.c index ca05372..fc14074 100644 --- a/mtapi_c/src/embb_mtapi_attr.c +++ b/mtapi_c/src/embb_mtapi_attr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_attr.h b/mtapi_c/src/embb_mtapi_attr.h index 46e4626..467ae09 100644 --- a/mtapi_c/src/embb_mtapi_attr.h +++ b/mtapi_c/src/embb_mtapi_attr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_group_t.c b/mtapi_c/src/embb_mtapi_group_t.c index 9e3b0a5..4702756 100644 --- a/mtapi_c/src/embb_mtapi_group_t.c +++ b/mtapi_c/src/embb_mtapi_group_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -55,7 +55,7 @@ void embb_mtapi_group_initialize(embb_mtapi_group_t * that) { assert(MTAPI_NULL != that); that->group_id = MTAPI_GROUP_ID_NONE; - that->deleted = MTAPI_FALSE; + embb_atomic_store_int(&that->deleted, MTAPI_FALSE); that->num_tasks.internal_variable = 0; embb_mtapi_task_queue_initialize(&that->queue); } @@ -67,7 +67,7 @@ void embb_mtapi_group_initialize_with_node( assert(MTAPI_NULL != node); that->group_id = MTAPI_GROUP_ID_NONE; - that->deleted = MTAPI_FALSE; + embb_atomic_store_int(&that->deleted, MTAPI_FALSE); that->num_tasks.internal_variable = 0; embb_mtapi_task_queue_initialize_with_capacity( &that->queue, node->attributes.queue_limit); @@ -76,7 +76,7 @@ void embb_mtapi_group_initialize_with_node( void embb_mtapi_group_finalize(embb_mtapi_group_t * that) { assert(MTAPI_NULL != that); - that->deleted = MTAPI_TRUE; + embb_atomic_store_int(&that->deleted, MTAPI_TRUE); that->num_tasks.internal_variable = 0; embb_mtapi_task_queue_finalize(&that->queue); } @@ -372,7 +372,7 @@ void mtapi_group_delete( embb_mtapi_group_pool_get_storage_for_handle( node->group_pool, group); - if (local_group->deleted) { + if (embb_atomic_load_int(&local_group->deleted)) { local_status = MTAPI_ERR_GROUP_INVALID; } else { embb_mtapi_group_finalize(local_group); diff --git a/mtapi_c/src/embb_mtapi_group_t.h b/mtapi_c/src/embb_mtapi_group_t.h index 9f4a401..9bf2932 100644 --- a/mtapi_c/src/embb_mtapi_group_t.h +++ b/mtapi_c/src/embb_mtapi_group_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -55,7 +55,7 @@ struct embb_mtapi_group_struct { mtapi_group_hndl_t handle; mtapi_group_id_t group_id; - volatile mtapi_boolean_t deleted; + embb_atomic_int deleted; embb_atomic_int num_tasks; mtapi_group_attributes_t attributes; embb_mtapi_task_queue_t queue; diff --git a/mtapi_c/src/embb_mtapi_group_t_fwd.h b/mtapi_c/src/embb_mtapi_group_t_fwd.h index 66233b3..6b40ec8 100644 --- a/mtapi_c/src/embb_mtapi_group_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_group_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_id_pool_t.c b/mtapi_c/src/embb_mtapi_id_pool_t.c index 184a9f6..37416e9 100644 --- a/mtapi_c/src/embb_mtapi_id_pool_t.c +++ b/mtapi_c/src/embb_mtapi_id_pool_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -29,6 +29,7 @@ #include #include #include +#include void embb_mtapi_id_pool_initialize( embb_mtapi_id_pool_t * that, @@ -45,7 +46,7 @@ void embb_mtapi_id_pool_initialize( that->ids_available = capacity; that->put_id_position = 0; that->get_id_position = 1; - embb_mtapi_spinlock_initialize(&that->lock); + embb_spin_init(&that->lock); } void embb_mtapi_id_pool_finalize(embb_mtapi_id_pool_t * that) { @@ -55,7 +56,7 @@ void embb_mtapi_id_pool_finalize(embb_mtapi_id_pool_t * that) { that->put_id_position = 0; embb_mtapi_alloc_deallocate(that->id_buffer); that->id_buffer = NULL; - embb_mtapi_spinlock_finalize(&that->lock); + embb_spin_destroy(&that->lock); } mtapi_uint_t embb_mtapi_id_pool_allocate(embb_mtapi_id_pool_t * that) { @@ -63,7 +64,7 @@ mtapi_uint_t embb_mtapi_id_pool_allocate(embb_mtapi_id_pool_t * that) { assert(MTAPI_NULL != that); - if (embb_mtapi_spinlock_acquire(&that->lock)) { + if (embb_spin_lock(&that->lock) == EMBB_SUCCESS) { if (0 < that->ids_available) { /* take away one id */ that->ids_available--; @@ -81,7 +82,7 @@ mtapi_uint_t embb_mtapi_id_pool_allocate(embb_mtapi_id_pool_t * that) { /* make id entry invalid just in case */ that->id_buffer[id_position] = EMBB_MTAPI_IDPOOL_INVALID_ID; } - embb_mtapi_spinlock_release(&that->lock); + embb_spin_unlock(&that->lock); } return id; @@ -92,7 +93,7 @@ void embb_mtapi_id_pool_deallocate( mtapi_uint_t id) { assert(MTAPI_NULL != that); - if (embb_mtapi_spinlock_acquire(&that->lock)) { + if (embb_spin_lock(&that->lock) == EMBB_SUCCESS) { if (that->capacity > that->ids_available) { /* acquire position to put id to */ mtapi_uint_t id_position = that->put_id_position; @@ -107,7 +108,7 @@ void embb_mtapi_id_pool_deallocate( /* make it available */ that->ids_available++; } - embb_mtapi_spinlock_release(&that->lock); + embb_spin_unlock(&that->lock); } else { embb_mtapi_log_error( "could not acquire lock in embb_mtapi_IdPool_deallocate\n"); diff --git a/mtapi_c/src/embb_mtapi_id_pool_t.h b/mtapi_c/src/embb_mtapi_id_pool_t.h index 9d06f98..d3f2616 100644 --- a/mtapi_c/src/embb_mtapi_id_pool_t.h +++ b/mtapi_c/src/embb_mtapi_id_pool_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -29,8 +29,7 @@ #include #include - -#include +#include #ifdef __cplusplus extern "C" { @@ -51,7 +50,7 @@ struct embb_mtapi_id_pool_struct { mtapi_uint_t ids_available; mtapi_uint_t get_id_position; mtapi_uint_t put_id_position; - embb_mtapi_spinlock_t lock; + embb_spinlock_t lock; }; /** diff --git a/mtapi_c/src/embb_mtapi_job_t.c b/mtapi_c/src/embb_mtapi_job_t.c index 227666e..3908991 100644 --- a/mtapi_c/src/embb_mtapi_job_t.c +++ b/mtapi_c/src/embb_mtapi_job_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_job_t.h b/mtapi_c/src/embb_mtapi_job_t.h index 9e2ec88..0ca4d47 100644 --- a/mtapi_c/src/embb_mtapi_job_t.h +++ b/mtapi_c/src/embb_mtapi_job_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_job_t_fwd.h b/mtapi_c/src/embb_mtapi_job_t_fwd.h index c986a86..1e1bc21 100644 --- a/mtapi_c/src/embb_mtapi_job_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_job_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_log.h b/mtapi_c/src/embb_mtapi_log.h index 8f98eaf..00a521a 100644 --- a/mtapi_c/src/embb_mtapi_log.h +++ b/mtapi_c/src/embb_mtapi_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_node_t.c b/mtapi_c/src/embb_mtapi_node_t.c index 327cd21..9b1d2d3 100644 --- a/mtapi_c/src/embb_mtapi_node_t.c +++ b/mtapi_c/src/embb_mtapi_node_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -41,7 +41,6 @@ static embb_mtapi_node_t* embb_mtapi_node_instance = NULL; -extern embb_atomic_int embb_mtapi_spinlock_spins; /* ---- CLASS MEMBERS ------------------------------------------------------ */ @@ -87,8 +86,6 @@ void mtapi_initialize( /* out of memory! */ local_status = MTAPI_ERR_UNKNOWN; } else { - embb_atomic_store_int(&embb_mtapi_spinlock_spins, 0); - node = embb_mtapi_node_instance; node->domain_id = domain_id; @@ -184,9 +181,6 @@ void mtapi_finalize(MTAPI_OUT mtapi_status_t* status) { embb_mtapi_alloc_deallocate(node); embb_mtapi_node_instance = MTAPI_NULL; - embb_mtapi_log_info("mtapi spinlock spun %d times.\n", - embb_atomic_load_int(&embb_mtapi_spinlock_spins)); - local_status = MTAPI_SUCCESS; } else { local_status = MTAPI_ERR_NODE_NOTINIT; diff --git a/mtapi_c/src/embb_mtapi_node_t.h b/mtapi_c/src/embb_mtapi_node_t.h index 22fca86..be16101 100644 --- a/mtapi_c/src/embb_mtapi_node_t.h +++ b/mtapi_c/src/embb_mtapi_node_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_node_t_fwd.h b/mtapi_c/src/embb_mtapi_node_t_fwd.h index 78ee823..f9a7e19 100644 --- a/mtapi_c/src/embb_mtapi_node_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_node_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_pool_template-inl.h b/mtapi_c/src/embb_mtapi_pool_template-inl.h index 5366972..75b607b 100644 --- a/mtapi_c/src/embb_mtapi_pool_template-inl.h +++ b/mtapi_c/src/embb_mtapi_pool_template-inl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_pool_template.h b/mtapi_c/src/embb_mtapi_pool_template.h index 1bace62..088eeaf 100644 --- a/mtapi_c/src/embb_mtapi_pool_template.h +++ b/mtapi_c/src/embb_mtapi_pool_template.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_queue_t.c b/mtapi_c/src/embb_mtapi_queue_t.c index 8288dab..1a32406 100644 --- a/mtapi_c/src/embb_mtapi_queue_t.c +++ b/mtapi_c/src/embb_mtapi_queue_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_queue_t.h b/mtapi_c/src/embb_mtapi_queue_t.h index ff0abef..1f3fc35 100644 --- a/mtapi_c/src/embb_mtapi_queue_t.h +++ b/mtapi_c/src/embb_mtapi_queue_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -31,7 +31,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/mtapi_c/src/embb_mtapi_queue_t_fwd.h b/mtapi_c/src/embb_mtapi_queue_t_fwd.h index 0fb3824..23c49f4 100644 --- a/mtapi_c/src/embb_mtapi_queue_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_queue_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_scheduler_t.c b/mtapi_c/src/embb_mtapi_scheduler_t.c index acae760..1d124e8 100644 --- a/mtapi_c/src/embb_mtapi_scheduler_t.c +++ b/mtapi_c/src/embb_mtapi_scheduler_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -302,7 +302,7 @@ int embb_mtapi_scheduler_worker(void * arg) { node->queue_pool, task->queue); } - switch (task->state) { + switch (embb_atomic_load_int(&task->state)) { case MTAPI_TASK_SCHEDULED: /* multi-instance task, another instance might be running */ case MTAPI_TASK_RUNNING: @@ -398,10 +398,12 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( node->scheduler); /* now wait and schedule new tasks if we are on a worker */ + mtapi_task_state_t task_state = + (mtapi_task_state_t)embb_atomic_load_int(&task->state); while ( - (MTAPI_TASK_SCHEDULED == task->state) || - (MTAPI_TASK_RUNNING == task->state) || - (MTAPI_TASK_RETAINED == task->state) ) { + (MTAPI_TASK_SCHEDULED == task_state) || + (MTAPI_TASK_RUNNING == task_state) || + (MTAPI_TASK_RETAINED == task_state) ) { if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); @@ -416,6 +418,8 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( node->scheduler, node, context); + + task_state = (mtapi_task_state_t)embb_atomic_load_int(&task->state); } return MTAPI_TRUE; diff --git a/mtapi_c/src/embb_mtapi_scheduler_t.h b/mtapi_c/src/embb_mtapi_scheduler_t.h index 9b340d2..ac94a0d 100644 --- a/mtapi_c/src/embb_mtapi_scheduler_t.h +++ b/mtapi_c/src/embb_mtapi_scheduler_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_scheduler_t_fwd.h b/mtapi_c/src/embb_mtapi_scheduler_t_fwd.h index 454c471..09fab76 100644 --- a/mtapi_c/src/embb_mtapi_scheduler_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_scheduler_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_spinlock_t.c b/mtapi_c/src/embb_mtapi_spinlock_t.c deleted file mode 100644 index 0b3efa9..0000000 --- a/mtapi_c/src/embb_mtapi_spinlock_t.c +++ /dev/null @@ -1,70 +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. - */ - -#include - -void embb_mtapi_spinlock_initialize(embb_mtapi_spinlock_t * that) { - embb_atomic_store_int(that, 0); -} - -void embb_mtapi_spinlock_finalize(embb_mtapi_spinlock_t * that) { - embb_atomic_store_int(that, 0); -} - -embb_atomic_int embb_mtapi_spinlock_spins = { 0 }; - -mtapi_boolean_t embb_mtapi_spinlock_acquire(embb_mtapi_spinlock_t * that) { - int expected = 0; - while (0 == embb_atomic_compare_and_swap_int(that, &expected, 1)) { - /* empty */ - embb_atomic_fetch_and_add_int(&embb_mtapi_spinlock_spins, 1); - expected = 0; - } - return MTAPI_TRUE; -} - -mtapi_boolean_t embb_mtapi_spinlock_acquire_with_spincount( - embb_mtapi_spinlock_t * that, - mtapi_uint_t max_spin_count) { - int expected = 0; - mtapi_uint_t spin_count = max_spin_count; - while (0 == embb_atomic_compare_and_swap_int(that, &expected, 1)) { - embb_atomic_fetch_and_add_int(&embb_mtapi_spinlock_spins, 1); - spin_count--; - if (0 == spin_count) { - return MTAPI_FALSE; - } - expected = 0; - } - - return MTAPI_TRUE; -} - -mtapi_boolean_t embb_mtapi_spinlock_release(embb_mtapi_spinlock_t * that) { - int expected = 1; - return embb_atomic_compare_and_swap_int(that, &expected, 0) ? - MTAPI_TRUE : MTAPI_FALSE; -} diff --git a/mtapi_c/src/embb_mtapi_spinlock_t.h b/mtapi_c/src/embb_mtapi_spinlock_t.h deleted file mode 100644 index 012cb1d..0000000 --- a/mtapi_c/src/embb_mtapi_spinlock_t.h +++ /dev/null @@ -1,55 +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 MTAPI_C_SRC_EMBB_MTAPI_SPINLOCK_T_H_ -#define MTAPI_C_SRC_EMBB_MTAPI_SPINLOCK_T_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* ---- CLASS DECLARATION -------------------------------------------------- */ - -typedef embb_atomic_int embb_mtapi_spinlock_t; - -void embb_mtapi_spinlock_initialize(embb_mtapi_spinlock_t * that); -void embb_mtapi_spinlock_finalize(embb_mtapi_spinlock_t * that); -mtapi_boolean_t embb_mtapi_spinlock_acquire(embb_mtapi_spinlock_t * that); -mtapi_boolean_t embb_mtapi_spinlock_acquire_with_spincount( - embb_mtapi_spinlock_t * that, - mtapi_uint_t max_spin_count); -mtapi_boolean_t embb_mtapi_spinlock_release(embb_mtapi_spinlock_t * that); - - -#ifdef __cplusplus -} -#endif - -#endif // MTAPI_C_SRC_EMBB_MTAPI_SPINLOCK_T_H_ diff --git a/mtapi_c/src/embb_mtapi_task_context_t.c b/mtapi_c/src/embb_mtapi_task_context_t.c index a74088a..9ca279a 100644 --- a/mtapi_c/src/embb_mtapi_task_context_t.c +++ b/mtapi_c/src/embb_mtapi_task_context_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -187,7 +187,8 @@ mtapi_task_state_t mtapi_context_taskstate_get( &(task_context->thread_context->tss_id)); if (local_context == task_context->thread_context) { - task_state = task_context->task->state; + task_state = (mtapi_task_state_t)embb_atomic_load_int( + &task_context->task->state); local_status = MTAPI_SUCCESS; } else { local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT; diff --git a/mtapi_c/src/embb_mtapi_task_context_t.h b/mtapi_c/src/embb_mtapi_task_context_t.h index 8763b44..26f33f6 100644 --- a/mtapi_c/src/embb_mtapi_task_context_t.h +++ b/mtapi_c/src/embb_mtapi_task_context_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_task_context_t_fwd.h b/mtapi_c/src/embb_mtapi_task_context_t_fwd.h index 0ecfb4e..a7c2b42 100644 --- a/mtapi_c/src/embb_mtapi_task_context_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_task_context_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_task_queue_t.c b/mtapi_c/src/embb_mtapi_task_queue_t.c index d52a2bf..8bb9f7f 100644 --- a/mtapi_c/src/embb_mtapi_task_queue_t.c +++ b/mtapi_c/src/embb_mtapi_task_queue_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -46,7 +46,7 @@ void embb_mtapi_task_queue_initialize(embb_mtapi_task_queue_t* that) { that->get_task_position = 0; that->put_task_position = 0; mtapi_queueattr_init(&that->attributes, MTAPI_NULL); - embb_mtapi_spinlock_initialize(&that->lock); + embb_spin_init(&that->lock); } void embb_mtapi_task_queue_initialize_with_capacity( @@ -61,7 +61,7 @@ void embb_mtapi_task_queue_initialize_with_capacity( that->put_task_position = 0; mtapi_queueattr_init(&that->attributes, MTAPI_NULL); that->attributes.limit = capacity; - embb_mtapi_spinlock_initialize(&that->lock); + embb_spin_init(&that->lock); } void embb_mtapi_task_queue_finalize(embb_mtapi_task_queue_t* that) { @@ -70,7 +70,7 @@ void embb_mtapi_task_queue_finalize(embb_mtapi_task_queue_t* that) { embb_mtapi_task_queue_initialize(that); - embb_mtapi_spinlock_finalize(&that->lock); + embb_spin_destroy(&that->lock); } embb_mtapi_task_t * embb_mtapi_task_queue_pop(embb_mtapi_task_queue_t* that) { @@ -78,7 +78,7 @@ embb_mtapi_task_t * embb_mtapi_task_queue_pop(embb_mtapi_task_queue_t* that) { assert(MTAPI_NULL != that); - if (embb_mtapi_spinlock_acquire_with_spincount(&that->lock, 128)) { + if (embb_spin_try_lock(&that->lock, 128) == EMBB_SUCCESS) { if (0 < that->tasks_available) { /* take away one task */ that->tasks_available--; @@ -96,7 +96,7 @@ embb_mtapi_task_t * embb_mtapi_task_queue_pop(embb_mtapi_task_queue_t* that) { /* make task entry invalid just in case */ that->task_buffer[task_position] = MTAPI_NULL; } - embb_mtapi_spinlock_release(&that->lock); + embb_spin_unlock(&that->lock); } return task; @@ -109,7 +109,7 @@ mtapi_boolean_t embb_mtapi_task_queue_push( assert(MTAPI_NULL != that); - if (embb_mtapi_spinlock_acquire(&that->lock)) { + if (embb_spin_lock(&that->lock) == EMBB_SUCCESS) { if (that->attributes.limit > that->tasks_available) { /* acquire position to put task into */ mtapi_uint_t task_position = that->put_task_position; @@ -126,7 +126,7 @@ mtapi_boolean_t embb_mtapi_task_queue_push( result = MTAPI_TRUE; } - embb_mtapi_spinlock_release(&that->lock); + embb_spin_unlock(&that->lock); } return result; @@ -143,7 +143,7 @@ mtapi_boolean_t embb_mtapi_task_queue_process( assert(MTAPI_NULL != that); assert(MTAPI_NULL != process); - if (embb_mtapi_spinlock_acquire(&that->lock)) { + if (embb_spin_lock(&that->lock) == EMBB_SUCCESS) { idx = that->get_task_position; for (ii = 0; ii < that->tasks_available; ii++) { result = process(that->task_buffer[ii], user_data); @@ -152,7 +152,7 @@ mtapi_boolean_t embb_mtapi_task_queue_process( } idx = (idx + 1) % that->attributes.limit; } - embb_mtapi_spinlock_release(&that->lock); + embb_spin_unlock(&that->lock); } return result; diff --git a/mtapi_c/src/embb_mtapi_task_queue_t.h b/mtapi_c/src/embb_mtapi_task_queue_t.h index bd18fa7..10df771 100644 --- a/mtapi_c/src/embb_mtapi_task_queue_t.h +++ b/mtapi_c/src/embb_mtapi_task_queue_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -30,7 +30,7 @@ #include #include -#include +#include #include #ifdef __cplusplus @@ -57,7 +57,7 @@ struct embb_mtapi_task_queue_struct { mtapi_uint_t get_task_position; mtapi_uint_t put_task_position; mtapi_queue_attributes_t attributes; - embb_mtapi_spinlock_t lock; + embb_spinlock_t lock; }; #include diff --git a/mtapi_c/src/embb_mtapi_task_queue_t_fwd.h b/mtapi_c/src/embb_mtapi_task_queue_t_fwd.h index f313556..5ad9b0d 100644 --- a/mtapi_c/src/embb_mtapi_task_queue_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_task_queue_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_task_t.c b/mtapi_c/src/embb_mtapi_task_t.c index ce6511b..4323a13 100644 --- a/mtapi_c/src/embb_mtapi_task_t.c +++ b/mtapi_c/src/embb_mtapi_task_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -79,20 +79,20 @@ void embb_mtapi_task_initialize(embb_mtapi_task_t* that) { that->action.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->job.id = EMBB_MTAPI_IDPOOL_INVALID_ID; - that->state = MTAPI_TASK_ERROR; + embb_atomic_store_int(&that->state, MTAPI_TASK_ERROR); that->task_id = MTAPI_TASK_ID_NONE; that->group.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->queue.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->error_code = MTAPI_SUCCESS; embb_atomic_store_unsigned_int(&that->current_instance, 0); - embb_mtapi_spinlock_initialize(&that->state_lock); + embb_spin_init(&that->state_lock); } void embb_mtapi_task_finalize(embb_mtapi_task_t* that) { assert(MTAPI_NULL != that); embb_mtapi_task_initialize(that); - embb_mtapi_spinlock_finalize(&that->state_lock); + embb_spin_destroy(&that->state_lock); } mtapi_boolean_t embb_mtapi_task_execute( @@ -158,10 +158,10 @@ void embb_mtapi_task_set_state( mtapi_task_state_t state) { assert(MTAPI_NULL != that); - embb_mtapi_spinlock_acquire(&that->state_lock); - that->state = state; + embb_spin_lock(&that->state_lock); + embb_atomic_store_int(&that->state, state); embb_atomic_memory_barrier(); - embb_mtapi_spinlock_release(&that->state_lock); + embb_spin_unlock(&that->state_lock); } static mtapi_task_hndl_t embb_mtapi_task_start( diff --git a/mtapi_c/src/embb_mtapi_task_t.h b/mtapi_c/src/embb_mtapi_task_t.h index f5dadc5..2abf41c 100644 --- a/mtapi_c/src/embb_mtapi_task_t.h +++ b/mtapi_c/src/embb_mtapi_task_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -31,7 +31,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -65,8 +65,8 @@ struct embb_mtapi_task_struct { mtapi_queue_hndl_t queue; mtapi_action_hndl_t action; - embb_mtapi_spinlock_t state_lock; - volatile mtapi_task_state_t state; + embb_spinlock_t state_lock; + embb_atomic_int state; embb_atomic_unsigned_int current_instance; embb_atomic_unsigned_int instances_todo; diff --git a/mtapi_c/src/embb_mtapi_task_t_fwd.h b/mtapi_c/src/embb_mtapi_task_t_fwd.h index f44bba4..3c3f170 100644 --- a/mtapi_c/src/embb_mtapi_task_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_task_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_task_visitor_function_t.h b/mtapi_c/src/embb_mtapi_task_visitor_function_t.h index 54d2b8c..ee2b3e4 100644 --- a/mtapi_c/src/embb_mtapi_task_visitor_function_t.h +++ b/mtapi_c/src/embb_mtapi_task_visitor_function_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.c b/mtapi_c/src/embb_mtapi_thread_context_t.c index 2a7bdc4..a8745f8 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.c +++ b/mtapi_c/src/embb_mtapi_thread_context_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.h b/mtapi_c/src/embb_mtapi_thread_context_t.h index a207886..9fa588f 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.h +++ b/mtapi_c/src/embb_mtapi_thread_context_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/embb_mtapi_thread_context_t_fwd.h b/mtapi_c/src/embb_mtapi_thread_context_t_fwd.h index dc19293..cc05d15 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t_fwd.h +++ b/mtapi_c/src/embb_mtapi_thread_context_t_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_action_attributes_t.c b/mtapi_c/src/mtapi_action_attributes_t.c index 9cbbfce..e5db243 100644 --- a/mtapi_c/src/mtapi_action_attributes_t.c +++ b/mtapi_c/src/mtapi_action_attributes_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_affinity_t.c b/mtapi_c/src/mtapi_affinity_t.c index cfb0b9f..3705a4b 100644 --- a/mtapi_c/src/mtapi_affinity_t.c +++ b/mtapi_c/src/mtapi_affinity_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_group_attributes_t.c b/mtapi_c/src/mtapi_group_attributes_t.c index 5342bcd..c41d45c 100644 --- a/mtapi_c/src/mtapi_group_attributes_t.c +++ b/mtapi_c/src/mtapi_group_attributes_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_node_attributes_t.c b/mtapi_c/src/mtapi_node_attributes_t.c index 53ebf4c..18ed2c5 100644 --- a/mtapi_c/src/mtapi_node_attributes_t.c +++ b/mtapi_c/src/mtapi_node_attributes_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_queue_attributes_t.c b/mtapi_c/src/mtapi_queue_attributes_t.c index 6f39b0c..f41fe3c 100644 --- a/mtapi_c/src/mtapi_queue_attributes_t.c +++ b/mtapi_c/src/mtapi_queue_attributes_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_status_t.h b/mtapi_c/src/mtapi_status_t.h index 39fe780..c7f3c98 100644 --- a/mtapi_c/src/mtapi_status_t.h +++ b/mtapi_c/src/mtapi_status_t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/src/mtapi_task_attributes_t.c b/mtapi_c/src/mtapi_task_attributes_t.c index 43d9004..135b948 100644 --- a/mtapi_c/src/mtapi_task_attributes_t.c +++ b/mtapi_c/src/mtapi_task_attributes_t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_config.h b/mtapi_c/test/embb_mtapi_test_config.h index fb08d64..6577c16 100644 --- a/mtapi_c/test/embb_mtapi_test_config.h +++ b/mtapi_c/test/embb_mtapi_test_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_error.cc b/mtapi_c/test/embb_mtapi_test_error.cc index 6b3450a..d7d8d91 100644 --- a/mtapi_c/test/embb_mtapi_test_error.cc +++ b/mtapi_c/test/embb_mtapi_test_error.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_error.h b/mtapi_c/test/embb_mtapi_test_error.h index 3759bdd..3061bb9 100644 --- a/mtapi_c/test/embb_mtapi_test_error.h +++ b/mtapi_c/test/embb_mtapi_test_error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_group.cc b/mtapi_c/test/embb_mtapi_test_group.cc index 37f17d9..445f9be 100644 --- a/mtapi_c/test/embb_mtapi_test_group.cc +++ b/mtapi_c/test/embb_mtapi_test_group.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_group.h b/mtapi_c/test/embb_mtapi_test_group.h index 578a34e..e6501d6 100644 --- a/mtapi_c/test/embb_mtapi_test_group.h +++ b/mtapi_c/test/embb_mtapi_test_group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_id_pool.cc b/mtapi_c/test/embb_mtapi_test_id_pool.cc index f7c7855..0ba6e62 100644 --- a/mtapi_c/test/embb_mtapi_test_id_pool.cc +++ b/mtapi_c/test/embb_mtapi_test_id_pool.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_id_pool.h b/mtapi_c/test/embb_mtapi_test_id_pool.h index a85a284..626bb4f 100644 --- a/mtapi_c/test/embb_mtapi_test_id_pool.h +++ b/mtapi_c/test/embb_mtapi_test_id_pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_init_finalize.cc b/mtapi_c/test/embb_mtapi_test_init_finalize.cc index 710d6c1..226919f 100644 --- a/mtapi_c/test/embb_mtapi_test_init_finalize.cc +++ b/mtapi_c/test/embb_mtapi_test_init_finalize.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_init_finalize.h b/mtapi_c/test/embb_mtapi_test_init_finalize.h index 519ba18..974237c 100644 --- a/mtapi_c/test/embb_mtapi_test_init_finalize.h +++ b/mtapi_c/test/embb_mtapi_test_init_finalize.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_queue.cc b/mtapi_c/test/embb_mtapi_test_queue.cc index 08a0933..4de48f9 100644 --- a/mtapi_c/test/embb_mtapi_test_queue.cc +++ b/mtapi_c/test/embb_mtapi_test_queue.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_queue.h b/mtapi_c/test/embb_mtapi_test_queue.h index 1e123f9..91aea99 100644 --- a/mtapi_c/test/embb_mtapi_test_queue.h +++ b/mtapi_c/test/embb_mtapi_test_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/embb_mtapi_test_task.cc b/mtapi_c/test/embb_mtapi_test_task.cc index 8d04992..9431862 100644 --- a/mtapi_c/test/embb_mtapi_test_task.cc +++ b/mtapi_c/test/embb_mtapi_test_task.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -107,7 +107,7 @@ void TaskTest::TestBasic() { mtapi_action_hndl_t action; mtapi_job_hndl_t job; mtapi_task_hndl_t task[100]; - int ii; + mtapi_uint_t ii; embb_mtapi_log_info("running testTask...\n"); @@ -169,9 +169,9 @@ void TaskTest::TestBasic() { job = mtapi_job_get(JOB_TEST_TASK, THIS_DOMAIN_ID, &status); MTAPI_CHECK_STATUS(status); - for (ii = 0; ii < 100; ii++) { + for (ii = 0; ii < 100u; ii++) { status = MTAPI_ERR_UNKNOWN; - int arg = ii; + mtapi_uint_t arg = ii; task[ii] = mtapi_task_start( TASK_TEST_ID, job, @@ -187,7 +187,7 @@ void TaskTest::TestBasic() { testDoSomethingElse(); - for (ii = 0; ii < 100; ii++) { + for (ii = 0; ii < 100u; ii++) { status = MTAPI_ERR_UNKNOWN; mtapi_task_wait(task[ii], 100000, &status); MTAPI_CHECK_STATUS(status); @@ -227,7 +227,7 @@ void TaskTest::TestBasic() { MTAPI_CHECK_STATUS(status); mtapi_uint_t result[kTaskInstances]; - for (mtapi_uint_t ii = 0; ii < kTaskInstances; ii++) { + for (ii = 0; ii < kTaskInstances; ii++) { result[ii] = kTaskInstances + 1; } @@ -245,7 +245,7 @@ void TaskTest::TestBasic() { mtapi_task_wait(multiinstance_task, MTAPI_INFINITE, &status); MTAPI_CHECK_STATUS(status); - for (mtapi_uint_t ii = 0; ii < kTaskInstances; ii++) { + for (ii = 0; ii < kTaskInstances; ii++) { PT_EXPECT_EQ(result[ii], ii); } diff --git a/mtapi_c/test/embb_mtapi_test_task.h b/mtapi_c/test/embb_mtapi_test_task.h index 19ab8c8..bc379e7 100644 --- a/mtapi_c/test/embb_mtapi_test_task.h +++ b/mtapi_c/test/embb_mtapi_test_task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_c/test/main.cc b/mtapi_c/test/main.cc index 85b2e57..6fb351e 100644 --- a/mtapi_c/test/main.cc +++ b/mtapi_c/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/action.h b/mtapi_cpp/include/embb/mtapi/action.h index 50f8d75..564ab49 100644 --- a/mtapi_cpp/include/embb/mtapi/action.h +++ b/mtapi_cpp/include/embb/mtapi/action.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/action_attributes.h b/mtapi_cpp/include/embb/mtapi/action_attributes.h index 70f798b..f4bbf4b 100644 --- a/mtapi_cpp/include/embb/mtapi/action_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/action_attributes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/affinity.h b/mtapi_cpp/include/embb/mtapi/affinity.h index c2e0cfe..1496d48 100644 --- a/mtapi_cpp/include/embb/mtapi/affinity.h +++ b/mtapi_cpp/include/embb/mtapi/affinity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/group.h b/mtapi_cpp/include/embb/mtapi/group.h index 8fefc53..6d47598 100644 --- a/mtapi_cpp/include/embb/mtapi/group.h +++ b/mtapi_cpp/include/embb/mtapi/group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/group_attributes.h b/mtapi_cpp/include/embb/mtapi/group_attributes.h index 3f254f2..e77d661 100644 --- a/mtapi_cpp/include/embb/mtapi/group_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/group_attributes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/internal/check_status.h b/mtapi_cpp/include/embb/mtapi/internal/check_status.h index 5176a4d..3a7b47a 100644 --- a/mtapi_cpp/include/embb/mtapi/internal/check_status.h +++ b/mtapi_cpp/include/embb/mtapi/internal/check_status.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/job.h b/mtapi_cpp/include/embb/mtapi/job.h index 50eeec9..7b4c0f9 100644 --- a/mtapi_cpp/include/embb/mtapi/job.h +++ b/mtapi_cpp/include/embb/mtapi/job.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/mtapi.h b/mtapi_cpp/include/embb/mtapi/mtapi.h index 8ceb6e9..35e6d26 100644 --- a/mtapi_cpp/include/embb/mtapi/mtapi.h +++ b/mtapi_cpp/include/embb/mtapi/mtapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/node.h b/mtapi_cpp/include/embb/mtapi/node.h index 071cfff..115e48c 100644 --- a/mtapi_cpp/include/embb/mtapi/node.h +++ b/mtapi_cpp/include/embb/mtapi/node.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/node_attributes.h b/mtapi_cpp/include/embb/mtapi/node_attributes.h index 1dc104e..ae03fa7 100644 --- a/mtapi_cpp/include/embb/mtapi/node_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/node_attributes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/queue.h b/mtapi_cpp/include/embb/mtapi/queue.h index 43e957b..718fac3 100644 --- a/mtapi_cpp/include/embb/mtapi/queue.h +++ b/mtapi_cpp/include/embb/mtapi/queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/queue_attributes.h b/mtapi_cpp/include/embb/mtapi/queue_attributes.h index e5050b0..ee701d7 100644 --- a/mtapi_cpp/include/embb/mtapi/queue_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/queue_attributes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/status_exception.h b/mtapi_cpp/include/embb/mtapi/status_exception.h index 5f1504b..95e7ad5 100644 --- a/mtapi_cpp/include/embb/mtapi/status_exception.h +++ b/mtapi_cpp/include/embb/mtapi/status_exception.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/task.h b/mtapi_cpp/include/embb/mtapi/task.h index 40f3aaf..eaacc0c 100644 --- a/mtapi_cpp/include/embb/mtapi/task.h +++ b/mtapi_cpp/include/embb/mtapi/task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/task_attributes.h b/mtapi_cpp/include/embb/mtapi/task_attributes.h index e743279..7c16094 100644 --- a/mtapi_cpp/include/embb/mtapi/task_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/task_attributes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/include/embb/mtapi/task_context.h b/mtapi_cpp/include/embb/mtapi/task_context.h index 73df784..3b8982d 100644 --- a/mtapi_cpp/include/embb/mtapi/task_context.h +++ b/mtapi_cpp/include/embb/mtapi/task_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/src/check_status.cc b/mtapi_cpp/src/check_status.cc index 7af10ae..50c1c2d 100644 --- a/mtapi_cpp/src/check_status.cc +++ b/mtapi_cpp/src/check_status.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/src/node.cc b/mtapi_cpp/src/node.cc index 80e9406..9b77f2c 100644 --- a/mtapi_cpp/src/node.cc +++ b/mtapi_cpp/src/node.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/main.cc b/mtapi_cpp/test/main.cc index 4cd6b97..2e5d7f5 100644 --- a/mtapi_cpp/test/main.cc +++ b/mtapi_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_config.h b/mtapi_cpp/test/mtapi_cpp_test_config.h index 4b3c2d7..31c5f2c 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_config.h +++ b/mtapi_cpp/test/mtapi_cpp_test_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_group.cc b/mtapi_cpp/test/mtapi_cpp_test_group.cc index 610d58d..1378311 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_group.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_group.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_group.h b/mtapi_cpp/test/mtapi_cpp_test_group.h index 7a1cf2c..d80973f 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_group.h +++ b/mtapi_cpp/test/mtapi_cpp_test_group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_queue.cc b/mtapi_cpp/test/mtapi_cpp_test_queue.cc index 91a8884..8e17abf 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_queue.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_queue.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_queue.h b/mtapi_cpp/test/mtapi_cpp_test_queue.h index 9659ae2..42c6c8e 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_queue.h +++ b/mtapi_cpp/test/mtapi_cpp_test_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_task.cc b/mtapi_cpp/test/mtapi_cpp_test_task.cc index b21ddf7..fa3de4e 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_task.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_task.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_cpp/test/mtapi_cpp_test_task.h b/mtapi_cpp/test/mtapi_cpp_test_task.h index f86b6fe..f40c3bd 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_task.h +++ b/mtapi_cpp/test/mtapi_cpp_test_task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/mtapi_network_c/CMakeLists.txt b/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt similarity index 87% rename from mtapi_network_c/CMakeLists.txt rename to mtapi_plugins_c/mtapi_network_c/CMakeLists.txt index c5b8fc2..a23a903 100644 --- a/mtapi_network_c/CMakeLists.txt +++ b/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt @@ -26,17 +26,17 @@ GroupSourcesMSVC(test) set (EMBB_MTAPI_NETWORK_INCLUDE_DIRS "include" "src" "test") include_directories(${EMBB_MTAPI_NETWORK_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include - ${CMAKE_CURRENT_BINARY_DIR}/../base_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/src + ${CMAKE_CURRENT_SOURCE_DIR}/../../base_c/include + ${CMAKE_CURRENT_BINARY_DIR}/../../base_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src ) add_library(embb_mtapi_network_c ${EMBB_MTAPI_NETWORK_C_SOURCES} ${EMBB_MTAPI_NETWORK_C_HEADERS}) target_link_libraries(embb_mtapi_network_c embb_mtapi_c embb_base_c) if (BUILD_TESTS STREQUAL ON) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) + include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../partest/include) add_executable (embb_mtapi_network_c_test ${EMBB_MTAPI_NETWORK_TEST_SOURCES}) target_link_libraries(embb_mtapi_network_c_test embb_mtapi_network_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_NETWORK_C_LIBS}) CopyBin(BIN embb_mtapi_network_c_test DEST ${local_install_dir}) diff --git a/mtapi_network_c/include/embb/mtapi/c/mtapi_network.h b/mtapi_plugins_c/mtapi_network_c/include/embb/mtapi/c/mtapi_network.h similarity index 100% rename from mtapi_network_c/include/embb/mtapi/c/mtapi_network.h rename to mtapi_plugins_c/mtapi_network_c/include/embb/mtapi/c/mtapi_network.h diff --git a/mtapi_network_c/src/embb_mtapi_network.c b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.c similarity index 96% rename from mtapi_network_c/src/embb_mtapi_network.c rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.c index 598fe75..73a5585 100644 --- a/mtapi_network_c/src/embb_mtapi_network.c +++ b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.c @@ -162,7 +162,8 @@ static void embb_mtapi_network_task_complete( send_buf, (int32_t)local_task->result_size); assert(err == 4); err = embb_mtapi_network_buffer_push_back_rawdata( - send_buf, (int32_t)local_task->result_size, local_task->result_buffer); + send_buf, (int32_t)local_task->result_size, + local_task->result_buffer); assert(err == (int)local_task->result_size); err = embb_mtapi_network_socket_sendbuffer( @@ -303,7 +304,8 @@ static int embb_mtapi_network_thread(void * args) { mtapi_taskattr_set(&task_attr, MTAPI_TASK_COMPLETE_FUNCTION, func_void, 0, &local_status); assert(local_status == MTAPI_SUCCESS); - job_hndl = mtapi_job_get((mtapi_job_id_t)job_id, (mtapi_domain_t)domain_id, &local_status); + job_hndl = mtapi_job_get((mtapi_job_id_t)job_id, + (mtapi_domain_t)domain_id, &local_status); assert(local_status == MTAPI_SUCCESS); mtapi_task_start( MTAPI_TASK_ID_NONE, job_hndl, @@ -377,7 +379,7 @@ static int embb_mtapi_network_thread(void * args) { assert(err == results_size); local_task->error_code = (mtapi_status_t)task_status; - local_task->state = MTAPI_TASK_COMPLETED; + embb_atomic_store_int(&local_task->state, MTAPI_TASK_COMPLETED); embb_atomic_fetch_and_add_int(&local_action->num_tasks, -1); /* is task associated with a group? */ @@ -530,7 +532,7 @@ static void network_task_start( assert(err == send_buf->size); embb_atomic_fetch_and_add_int(&local_action->num_tasks, 1); - local_task->state = MTAPI_TASK_RUNNING; + embb_atomic_store_int(&local_task->state, MTAPI_TASK_RUNNING); embb_mtapi_network_buffer_clear(send_buf); diff --git a/mtapi_network_c/src/embb_mtapi_network.h b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.h similarity index 91% rename from mtapi_network_c/src/embb_mtapi_network.h rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.h index cc524f8..4bc5b12 100644 --- a/mtapi_network_c/src/embb_mtapi_network.h +++ b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ -#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ #include @@ -43,4 +43,4 @@ void embb_mtapi_network_finalize(); } #endif -#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ diff --git a/mtapi_network_c/src/embb_mtapi_network_buffer.c b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_buffer.c similarity index 100% rename from mtapi_network_c/src/embb_mtapi_network_buffer.c rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_buffer.c diff --git a/mtapi_network_c/src/embb_mtapi_network_buffer.h b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_buffer.h similarity index 96% rename from mtapi_network_c/src/embb_mtapi_network_buffer.h rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_buffer.h index 64d6c13..2d5c306 100644 --- a/mtapi_network_c/src/embb_mtapi_network_buffer.h +++ b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_buffer.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ -#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ #include @@ -103,4 +103,4 @@ int embb_mtapi_network_buffer_pop_front_rawdata( } #endif -#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ diff --git a/mtapi_network_c/src/embb_mtapi_network_socket.c b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_socket.c similarity index 100% rename from mtapi_network_c/src/embb_mtapi_network_socket.c rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_socket.c diff --git a/mtapi_network_c/src/embb_mtapi_network_socket.h b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_socket.h similarity index 96% rename from mtapi_network_c/src/embb_mtapi_network_socket.h rename to mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_socket.h index 7ce7282..db568bf 100644 --- a/mtapi_network_c/src/embb_mtapi_network_socket.h +++ b/mtapi_plugins_c/mtapi_network_c/src/embb_mtapi_network_socket.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ -#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ #include #include @@ -101,4 +101,4 @@ int embb_mtapi_network_socket_recvbuffer_sized( } #endif -#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ diff --git a/mtapi_network_c/test/embb_mtapi_network_test_buffer.cc b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_buffer.cc similarity index 100% rename from mtapi_network_c/test/embb_mtapi_network_test_buffer.cc rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_buffer.cc diff --git a/mtapi_network_c/test/embb_mtapi_network_test_buffer.h b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_buffer.h similarity index 91% rename from mtapi_network_c/test/embb_mtapi_network_test_buffer.h rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_buffer.h index abd34bd..4c7769d 100644 --- a/mtapi_network_c/test/embb_mtapi_network_test_buffer.h +++ b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_buffer.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ -#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ #include @@ -37,4 +37,4 @@ class NetworkBufferTest : public partest::TestCase { void TestBasic(); }; -#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ diff --git a/mtapi_network_c/test/embb_mtapi_network_test_socket.cc b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_socket.cc similarity index 100% rename from mtapi_network_c/test/embb_mtapi_network_test_socket.cc rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_socket.cc diff --git a/mtapi_network_c/test/embb_mtapi_network_test_socket.h b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_socket.h similarity index 91% rename from mtapi_network_c/test/embb_mtapi_network_test_socket.h rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_socket.h index 6150a62..3c9ca02 100644 --- a/mtapi_network_c/test/embb_mtapi_network_test_socket.h +++ b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_socket.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ -#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ #include @@ -37,4 +37,4 @@ class NetworkSocketTest : public partest::TestCase { void TestBasic(); }; -#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ diff --git a/mtapi_network_c/test/embb_mtapi_network_test_task.cc b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_task.cc similarity index 100% rename from mtapi_network_c/test/embb_mtapi_network_test_task.cc rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_task.cc diff --git a/mtapi_network_c/test/embb_mtapi_network_test_task.h b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_task.h similarity index 91% rename from mtapi_network_c/test/embb_mtapi_network_test_task.h rename to mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_task.h index 5cfbe8a..8162679 100644 --- a/mtapi_network_c/test/embb_mtapi_network_test_task.h +++ b/mtapi_plugins_c/mtapi_network_c/test/embb_mtapi_network_test_task.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ -#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ +#define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ #include @@ -37,4 +37,4 @@ class NetworkTaskTest : public partest::TestCase { void TestBasic(); }; -#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ diff --git a/mtapi_network_c/test/main.cc b/mtapi_plugins_c/mtapi_network_c/test/main.cc similarity index 100% rename from mtapi_network_c/test/main.cc rename to mtapi_plugins_c/mtapi_network_c/test/main.cc diff --git a/mtapi_opencl_c/CMakeLists.txt b/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt similarity index 87% rename from mtapi_opencl_c/CMakeLists.txt rename to mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt index 6fe7561..7dd94de 100644 --- a/mtapi_opencl_c/CMakeLists.txt +++ b/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt @@ -26,17 +26,17 @@ GroupSourcesMSVC(test) set (EMBB_MTAPI_OPENCL_INCLUDE_DIRS "include" "src" "test") include_directories(${EMBB_MTAPI_OPENCL_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include - ${CMAKE_CURRENT_BINARY_DIR}/../base_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/src + ${CMAKE_CURRENT_SOURCE_DIR}/../../base_c/include + ${CMAKE_CURRENT_BINARY_DIR}/../../base_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src ) add_library(embb_mtapi_opencl_c ${EMBB_MTAPI_OPENCL_C_SOURCES} ${EMBB_MTAPI_OPENCL_C_HEADERS}) target_link_libraries(embb_mtapi_opencl_c embb_mtapi_c embb_base_c) if (BUILD_TESTS STREQUAL ON) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) + include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../partest/include) add_executable (embb_mtapi_opencl_c_test ${EMBB_MTAPI_OPENCL_TEST_SOURCES}) target_link_libraries(embb_mtapi_opencl_c_test embb_mtapi_opencl_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_OPENCL_C_LIBS}) CopyBin(BIN embb_mtapi_opencl_c_test DEST ${local_install_dir}) diff --git a/mtapi_opencl_c/include/embb/mtapi/c/mtapi_opencl.h b/mtapi_plugins_c/mtapi_opencl_c/include/embb/mtapi/c/mtapi_opencl.h similarity index 100% rename from mtapi_opencl_c/include/embb/mtapi/c/mtapi_opencl.h rename to mtapi_plugins_c/mtapi_opencl_c/include/embb/mtapi/c/mtapi_opencl.h diff --git a/mtapi_opencl_c/src/CL/cl.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/cl.h similarity index 100% rename from mtapi_opencl_c/src/CL/cl.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/cl.h diff --git a/mtapi_opencl_c/src/CL/cl_ext.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_ext.h similarity index 100% rename from mtapi_opencl_c/src/CL/cl_ext.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_ext.h diff --git a/mtapi_opencl_c/src/CL/cl_gl.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_gl.h similarity index 100% rename from mtapi_opencl_c/src/CL/cl_gl.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_gl.h diff --git a/mtapi_opencl_c/src/CL/cl_gl_ext.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_gl_ext.h similarity index 100% rename from mtapi_opencl_c/src/CL/cl_gl_ext.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_gl_ext.h diff --git a/mtapi_opencl_c/src/CL/cl_platform.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_platform.h similarity index 100% rename from mtapi_opencl_c/src/CL/cl_platform.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/cl_platform.h diff --git a/mtapi_opencl_c/src/CL/opencl.h b/mtapi_plugins_c/mtapi_opencl_c/src/CL/opencl.h similarity index 100% rename from mtapi_opencl_c/src/CL/opencl.h rename to mtapi_plugins_c/mtapi_opencl_c/src/CL/opencl.h diff --git a/mtapi_opencl_c/src/embb_mtapi_opencl.c b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl.c similarity index 90% rename from mtapi_opencl_c/src/embb_mtapi_opencl.c rename to mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl.c index a4b7e19..c435e73 100644 --- a/mtapi_opencl_c/src/embb_mtapi_opencl.c +++ b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl.c @@ -174,30 +174,40 @@ static void opencl_task_start( err = clSetKernelArg(opencl_action->kernel, 0, sizeof(cl_mem), (const void*)&opencl_task->arguments); - err = clSetKernelArg(opencl_action->kernel, 1, sizeof(cl_int), + err |= clSetKernelArg(opencl_action->kernel, 1, sizeof(cl_int), (const void*)&opencl_task->arguments_size); - err = clSetKernelArg(opencl_action->kernel, 2, sizeof(cl_mem), + err |= clSetKernelArg(opencl_action->kernel, 2, sizeof(cl_mem), (const void*)&opencl_task->result_buffer); - err = clSetKernelArg(opencl_action->kernel, 3, sizeof(cl_int), + err |= clSetKernelArg(opencl_action->kernel, 3, sizeof(cl_int), (const void*)&opencl_task->result_buffer_size); - err = clEnqueueWriteBuffer(plugin->command_queue, + err |= clEnqueueWriteBuffer(plugin->command_queue, opencl_task->arguments, CL_FALSE, 0, - (size_t)opencl_task->arguments_size, local_task->arguments, 0, NULL, NULL); - err = clEnqueueNDRangeKernel(plugin->command_queue, - opencl_action->kernel, 1, NULL, - &global_work_size, &opencl_action->local_work_size, 0, NULL, NULL); - err = clEnqueueReadBuffer(plugin->command_queue, - opencl_task->result_buffer, CL_FALSE, 0, - (size_t)opencl_task->result_buffer_size, local_task->result_buffer, - 0, NULL, &opencl_task->kernel_finish_event); - err = clSetEventCallback(opencl_task->kernel_finish_event, - CL_COMPLETE, opencl_task_complete, opencl_task); - err = clFlush(plugin->command_queue); - - embb_mtapi_task_set_state(local_task, MTAPI_TASK_RUNNING); - local_status = MTAPI_SUCCESS; + (size_t)opencl_task->arguments_size, local_task->arguments, + 0, NULL, NULL); + + if (CL_SUCCESS == err) { + embb_mtapi_task_set_state(local_task, MTAPI_TASK_RUNNING); + + err |= clEnqueueNDRangeKernel(plugin->command_queue, + opencl_action->kernel, 1, NULL, + &global_work_size, &opencl_action->local_work_size, 0, NULL, NULL); + err |= clEnqueueReadBuffer(plugin->command_queue, + opencl_task->result_buffer, CL_FALSE, 0, + (size_t)opencl_task->result_buffer_size, local_task->result_buffer, + 0, NULL, &opencl_task->kernel_finish_event); + err |= clSetEventCallback(opencl_task->kernel_finish_event, + CL_COMPLETE, opencl_task_complete, opencl_task); + } + + err |= clFlush(plugin->command_queue); + if (CL_SUCCESS != err) { + embb_mtapi_task_set_state(local_task, MTAPI_TASK_ERROR); + local_status = MTAPI_ERR_ACTION_FAILED; + } else { + local_status = MTAPI_SUCCESS; + } } } } @@ -259,7 +269,11 @@ void mtapi_opencl_plugin_initialize( embb_mtapi_opencl_plugin_t * plugin = &embb_mtapi_opencl_plugin; err = embb_mtapi_opencl_link_at_runtime(); - if (err != 0) { + if (err <= 0) { + // OpenCL not available, or wrong version + local_status = MTAPI_ERR_FUNC_NOT_IMPLEMENTED; + } else { + // all good, go ahead err = clGetPlatformIDs(1, &plugin->platform_id, NULL); if (CL_SUCCESS == err) { err = clGetDeviceIDs(plugin->platform_id, CL_DEVICE_TYPE_DEFAULT, diff --git a/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c similarity index 99% rename from mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c rename to mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c index 9396a5b..e96f9d9 100644 --- a/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c +++ b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.c @@ -263,7 +263,7 @@ int embb_mtapi_opencl_link_at_runtime() { void * opencl_dll_handle = dlopen("libOpenCL.so", RTLD_LAZY); #endif if (opencl_dll_handle == 0) - return 0; + return -1; #ifdef EMBB_PLATFORM_COMPILER_MSVC #pragma warning(push) diff --git a/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h similarity index 91% rename from mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h rename to mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h index 7fc4256..47f7828 100644 --- a/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h +++ b/mtapi_plugins_c/mtapi_opencl_c/src/embb_mtapi_opencl_runtimelinker.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ -#define MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ +#define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ #ifdef __cplusplus extern "C" { @@ -37,4 +37,4 @@ int embb_mtapi_opencl_link_at_runtime(); } #endif -#endif // MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ diff --git a/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc similarity index 94% rename from mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc rename to mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc index 83a81e7..246c3a4 100644 --- a/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc +++ b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.cc @@ -34,5 +34,7 @@ LinkerTest::LinkerTest() { } void LinkerTest::TestBasic() { - PT_EXPECT(embb_mtapi_opencl_link_at_runtime() != 0); + int result = embb_mtapi_opencl_link_at_runtime(); + bool success = result != 0; + PT_EXPECT(success); } diff --git a/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h similarity index 91% rename from mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h rename to mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h index e8c4a84..5654dd5 100644 --- a/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h +++ b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_linker.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ -#define MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ +#define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ #include @@ -37,4 +37,4 @@ class LinkerTest : public partest::TestCase { void TestBasic(); }; -#endif // MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ diff --git a/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc similarity index 98% rename from mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc rename to mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc index 61ddd31..0a922da 100644 --- a/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc +++ b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.cc @@ -75,6 +75,10 @@ void TaskTest::TestBasic() { } mtapi_opencl_plugin_initialize(&status); + if (status == MTAPI_ERR_FUNC_NOT_IMPLEMENTED) { + // OpenCL unavailable + return; + } MTAPI_CHECK_STATUS(status); mtapi_initialize( diff --git a/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h similarity index 91% rename from mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h rename to mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h index ca7545f..09f42fd 100644 --- a/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h +++ b/mtapi_plugins_c/mtapi_opencl_c/test/embb_mtapi_opencl_test_task.h @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ -#define MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ +#ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ +#define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ #include @@ -37,4 +37,4 @@ class TaskTest : public partest::TestCase { void TestBasic(); }; -#endif // MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ +#endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ diff --git a/mtapi_opencl_c/test/main.cc b/mtapi_plugins_c/mtapi_opencl_c/test/main.cc similarity index 100% rename from mtapi_opencl_c/test/main.cc rename to mtapi_plugins_c/mtapi_opencl_c/test/main.cc diff --git a/scripts/create_tarball.sh b/scripts/create_tarball.sh index a91846d..0088e8b 100755 --- a/scripts/create_tarball.sh +++ b/scripts/create_tarball.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/insert_license.sh b/scripts/insert_license.sh index 3239574..973f137 100755 --- a/scripts/insert_license.sh +++ b/scripts/insert_license.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/license.txt b/scripts/license.txt index e95756a..c4fd49d 100644 --- a/scripts/license.txt +++ b/scripts/license.txt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/scripts/license_scripts.txt b/scripts/license_scripts.txt index f6c8ca4..800b0ac 100644 --- a/scripts/license_scripts.txt +++ b/scripts/license_scripts.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/remove_license.sh b/scripts/remove_license.sh index a01d8d4..c1d08de 100755 --- a/scripts/remove_license.sh +++ b/scripts/remove_license.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/run_cpplint.sh b/scripts/run_cpplint.sh index 174414f..cec5393 100755 --- a/scripts/run_cpplint.sh +++ b/scripts/run_cpplint.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: @@ -79,7 +79,7 @@ retval=0 ##Excluded files RAND_FILES=( embb_mtapi_test_group.cc embb_mtapi_test_queue.cc embb_mtapi_test_task.cc queue_test-inl.h ) -for project in base_c mtapi_c mtapi_network_c mtapi_opencl_c base_cpp mtapi_cpp tasks_cpp algorithms_cpp containers_cpp dataflow_cpp +for project in base_c mtapi_c mtapi_plugins_c/mtapi_network_c mtapi_plugins_c/mtapi_opencl_c base_cpp mtapi_cpp tasks_cpp algorithms_cpp containers_cpp dataflow_cpp do echo "-> Doing project: $project" dir=$d/$project diff --git a/scripts/run_tests_cygwin.sh.cmake b/scripts/run_tests_cygwin.sh.cmake index 2fce866..fbbc568 100755 --- a/scripts/run_tests_cygwin.sh.cmake +++ b/scripts/run_tests_cygwin.sh.cmake @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/run_tests_unix.sh.cmake b/scripts/run_tests_unix.sh.cmake index b668b9b..70c591a 100755 --- a/scripts/run_tests_unix.sh.cmake +++ b/scripts/run_tests_unix.sh.cmake @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015, Siemens AG. All rights reserved. +# Copyright (c) 2014-2016, 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: diff --git a/scripts/run_tests_windows.bat.cmake b/scripts/run_tests_windows.bat.cmake index c3d4a44..a0a1d74 100644 --- a/scripts/run_tests_windows.bat.cmake +++ b/scripts/run_tests_windows.bat.cmake @@ -1,4 +1,4 @@ -:: Copyright (c) 2014-2015, Siemens AG. All rights reserved. +:: Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/action.h b/tasks_cpp/include/embb/tasks/action.h index 34c22db..e034cbf 100644 --- a/tasks_cpp/include/embb/tasks/action.h +++ b/tasks_cpp/include/embb/tasks/action.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/continuation.h b/tasks_cpp/include/embb/tasks/continuation.h index 666df75..30c2922 100644 --- a/tasks_cpp/include/embb/tasks/continuation.h +++ b/tasks_cpp/include/embb/tasks/continuation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/execution_policy.h b/tasks_cpp/include/embb/tasks/execution_policy.h index 8a9a019..5248900 100644 --- a/tasks_cpp/include/embb/tasks/execution_policy.h +++ b/tasks_cpp/include/embb/tasks/execution_policy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/group.h b/tasks_cpp/include/embb/tasks/group.h index 039fe1d..700f09e 100644 --- a/tasks_cpp/include/embb/tasks/group.h +++ b/tasks_cpp/include/embb/tasks/group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in b/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in index 400139a..bb4ead5 100644 --- a/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in +++ b/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/node.h b/tasks_cpp/include/embb/tasks/node.h index 094b34d..666cab1 100644 --- a/tasks_cpp/include/embb/tasks/node.h +++ b/tasks_cpp/include/embb/tasks/node.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -120,6 +121,15 @@ class Node { static void Finalize(); /** + * Returns the number of available queues. + * \return The number of available queues + * \waitfree + */ + mtapi_uint_t GetQueueCount() const { + return queue_count_; + } + + /** * Returns the number of available cores. * \return The number of available cores * \waitfree @@ -218,11 +228,14 @@ class Node { mtapi_size_t node_local_data_size, mtapi_task_context_t * context); + mtapi_uint_t queue_count_; mtapi_uint_t core_count_; mtapi_uint_t worker_thread_count_; mtapi_action_hndl_t action_handle_; std::list queues_; std::list groups_; + embb::base::Spinlock queue_lock_; + embb::base::Spinlock group_lock_; }; } // namespace tasks diff --git a/tasks_cpp/include/embb/tasks/queue.h b/tasks_cpp/include/embb/tasks/queue.h index df9f303..a4f1479 100644 --- a/tasks_cpp/include/embb/tasks/queue.h +++ b/tasks_cpp/include/embb/tasks/queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/task.h b/tasks_cpp/include/embb/tasks/task.h index fd86b40..c78d6d1 100644 --- a/tasks_cpp/include/embb/tasks/task.h +++ b/tasks_cpp/include/embb/tasks/task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/task_context.h b/tasks_cpp/include/embb/tasks/task_context.h index ecb416e..9aaa663 100644 --- a/tasks_cpp/include/embb/tasks/task_context.h +++ b/tasks_cpp/include/embb/tasks/task_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/include/embb/tasks/tasks.h b/tasks_cpp/include/embb/tasks/tasks.h index 11e8d12..bb3e3d5 100644 --- a/tasks_cpp/include/embb/tasks/tasks.h +++ b/tasks_cpp/include/embb/tasks/tasks.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/continuation.cc b/tasks_cpp/src/continuation.cc index 35b9d65..330fae3 100644 --- a/tasks_cpp/src/continuation.cc +++ b/tasks_cpp/src/continuation.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/continuationstage.h b/tasks_cpp/src/continuationstage.h index 9c1f5b0..79d260f 100644 --- a/tasks_cpp/src/continuationstage.h +++ b/tasks_cpp/src/continuationstage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/execution_policy.cc b/tasks_cpp/src/execution_policy.cc index bb25954..b7e9b96 100644 --- a/tasks_cpp/src/execution_policy.cc +++ b/tasks_cpp/src/execution_policy.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -35,7 +35,7 @@ namespace tasks { ExecutionPolicy::ExecutionPolicy() : priority_(DefaultPriority) { -#if MTAPI_CPP_AUTOMATIC_INITIALIZE +#if TASKS_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -48,7 +48,7 @@ ExecutionPolicy::ExecutionPolicy() : ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) :priority_(priority) { -#if MTAPI_CPP_AUTOMATIC_INITIALIZE +#if TASKS_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -62,7 +62,7 @@ ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) :priority_(priority) { -#if MTAPI_CPP_AUTOMATIC_INITIALIZE +#if TASKS_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -75,7 +75,7 @@ ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(bool initial_affinity) :priority_(DefaultPriority) { -#if MTAPI_CPP_AUTOMATIC_INITIALIZE +#if TASKS_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; diff --git a/tasks_cpp/src/group.cc b/tasks_cpp/src/group.cc index 709290f..04971a8 100644 --- a/tasks_cpp/src/group.cc +++ b/tasks_cpp/src/group.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/node.cc b/tasks_cpp/src/node.cc index 362252c..67a9425 100644 --- a/tasks_cpp/src/node.cc +++ b/tasks_cpp/src/node.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -31,6 +31,7 @@ #include #include +#include #include #if TASKS_CPP_AUTOMATIC_INITIALIZE #include @@ -74,6 +75,9 @@ Node::Node( EMBB_THROW(embb::base::ErrorException, "mtapi::Node could not initialize mtapi"); } + mtapi_node_get_attribute(node_id, MTAPI_NODE_MAX_QUEUES, &queue_count_, + sizeof(queue_count_), &status); + assert(MTAPI_SUCCESS == status); core_count_ = info.hardware_concurrency; worker_thread_count_ = embb_core_set_count(&attr->core_affinity); action_handle_ = mtapi_action_create(TASKS_CPP_JOB, action_func, @@ -234,7 +238,11 @@ void Node::Finalize() { Group & Node::CreateGroup() { Group * group = embb::base::Allocation::New(); + while (!group_lock_.TryLock(1024)) { + embb::base::Thread::CurrentYield(); + } groups_.push_back(group); + group_lock_.Unlock(); return *group; } @@ -249,7 +257,11 @@ void Node::DestroyGroup(Group & group) { Queue & Node::CreateQueue(mtapi_uint_t priority, bool ordered) { Queue * queue = embb::base::Allocation::New(priority, ordered); + while (!queue_lock_.TryLock(1024)) { + embb::base::Thread::CurrentYield(); + } queues_.push_back(queue); + queue_lock_.Unlock(); return *queue; } diff --git a/tasks_cpp/src/queue.cc b/tasks_cpp/src/queue.cc index 098f379..efc574a 100644 --- a/tasks_cpp/src/queue.cc +++ b/tasks_cpp/src/queue.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/task.cc b/tasks_cpp/src/task.cc index eaba40d..518b637 100644 --- a/tasks_cpp/src/task.cc +++ b/tasks_cpp/src/task.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/src/task_context.cc b/tasks_cpp/src/task_context.cc index bba9312..f863715 100644 --- a/tasks_cpp/src/task_context.cc +++ b/tasks_cpp/src/task_context.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/main.cc b/tasks_cpp/test/main.cc index f46b112..2f17af7 100644 --- a/tasks_cpp/test/main.cc +++ b/tasks_cpp/test/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_config.h b/tasks_cpp/test/tasks_cpp_test_config.h index b7244c3..cae2208 100644 --- a/tasks_cpp/test/tasks_cpp_test_config.h +++ b/tasks_cpp/test/tasks_cpp_test_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_group.cc b/tasks_cpp/test/tasks_cpp_test_group.cc index 2e12fae..75cab3a 100644 --- a/tasks_cpp/test/tasks_cpp_test_group.cc +++ b/tasks_cpp/test/tasks_cpp_test_group.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_group.h b/tasks_cpp/test/tasks_cpp_test_group.h index cc6c4fe..fe212ea 100644 --- a/tasks_cpp/test/tasks_cpp_test_group.h +++ b/tasks_cpp/test/tasks_cpp_test_group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_queue.cc b/tasks_cpp/test/tasks_cpp_test_queue.cc index 17514ca..eb6bc87 100644 --- a/tasks_cpp/test/tasks_cpp_test_queue.cc +++ b/tasks_cpp/test/tasks_cpp_test_queue.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_queue.h b/tasks_cpp/test/tasks_cpp_test_queue.h index 88770ca..5c86795 100644 --- a/tasks_cpp/test/tasks_cpp_test_queue.h +++ b/tasks_cpp/test/tasks_cpp_test_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: diff --git a/tasks_cpp/test/tasks_cpp_test_task.cc b/tasks_cpp/test/tasks_cpp_test_task.cc index 103098d..69c56db 100644 --- a/tasks_cpp/test/tasks_cpp_test_task.cc +++ b/tasks_cpp/test/tasks_cpp_test_task.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: @@ -78,13 +78,19 @@ void TaskTest::TestBasic() { PT_EXPECT_EQ(policy.GetPriority(), 0u); policy.AddWorker(0u); PT_EXPECT_EQ(policy.GetAffinity(), 1u); - policy.AddWorker(1u); - PT_EXPECT_EQ(policy.GetAffinity(), 3u); + + if (policy.GetCoreCount() > 1) { + policy.AddWorker(1u); + PT_EXPECT_EQ(policy.GetAffinity(), 3u); + } + policy.RemoveWorker(0u); - PT_EXPECT_EQ(policy.GetAffinity(), 2u); PT_EXPECT_EQ(policy.IsSetWorker(0), false); - PT_EXPECT_EQ(policy.IsSetWorker(1), true); + if (policy.GetCoreCount() > 1) { + PT_EXPECT_EQ(policy.GetAffinity(), 2u); + PT_EXPECT_EQ(policy.IsSetWorker(1), true); + } std::string test; embb::tasks::Task task = node.Spawn( embb::base::Bind( diff --git a/tasks_cpp/test/tasks_cpp_test_task.h b/tasks_cpp/test/tasks_cpp_test_task.h index cbffac1..16f683b 100644 --- a/tasks_cpp/test/tasks_cpp_test_task.h +++ b/tasks_cpp/test/tasks_cpp_test_task.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, Siemens AG. All rights reserved. + * Copyright (c) 2014-2016, 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: