Commit 426360eb by Marcus Winter

Merge remote-tracking branch 'origin/development' into mtapi_distributed

Conflicts:
	mtapi_c/test/main.cc
parents fd503025 030d515c
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
language: cpp language: cpp
......
Embedded Multicore Building Blocks (EMB²) Embedded Multicore Building Blocks (EMB²)
========================================= =========================================
Version 0.2.2
-------------
### Bug fixes:
- Fixed 64bit problem in atomics
- Fixed bug in dataflow_cpp causing network to hang
- Fixed bug in conversion of core_set
- Fixed fetch-and-add implementation to support armv7-a
- Fixed missing freeing of mutex attributes in case of error
- Fixed bug where closure was allocated with Allocation::New but deleted with operator delete
- Fixed inconsistent naming of unit test cases
- Fixed memory allocation in hazard pointer implementation by replacing calls to new and delete with EMB²-specific functions
- Fixed memory leak in tests for containers
- Fixed affinity implementation for FreeBSD
### Changes and improvements:
- Added checks for memory leaks in tests
- Added block size support in MergeSort
- Renamed all platform specific defines to EMBB_PLATFORM_*
- Changed all checks for platform specific defines to checks for EMBB_* defines
- Replaced C++11 initializer lists in examples with C++03 compliant statements
- Extended unit tests for MPMC queue with checks for relative order
- Added check for result of pthread_attr_destroy
- Added assert in embb_tss_get
- Moved ExecutionPolicy from algorithms to mtapi_cpp, removed Affinity
### Features:
- None
### Build system:
- Removed cppcheck warnings
- Removed cpplint warnings
### Documentation:
- Improved documentation of default values and priorities
- Revised template argument names in base_cpp and containers_cpp
- Moved ExecutionPolicy to CPP_MTAPI and Identity to CPP_ALGORITHMS Doxygen group
- Fixed description of token limit in tutorial
- Added Clang support to README
- Mentioned the ability to cross compile in README
- Added link to release files in README
- Minor corrections in README
- Updated copyright notice
- Changed year in tutorial.tex to 2015
Version 0.2.1 Version 0.2.1
------------- -------------
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
......
# Copyright (c) 2014, Siemens AG. All rights reserved. # Copyright (c) 2014-2015, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
...@@ -28,7 +28,7 @@ cmake_minimum_required (VERSION 2.8.9) ...@@ -28,7 +28,7 @@ cmake_minimum_required (VERSION 2.8.9)
# Version number # Version number
set (EMBB_BASE_VERSION_MAJOR 0) set (EMBB_BASE_VERSION_MAJOR 0)
set (EMBB_BASE_VERSION_MINOR 2) set (EMBB_BASE_VERSION_MINOR 2)
set (EMBB_BASE_VERSION_PATCH 1) set (EMBB_BASE_VERSION_PATCH 2)
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING set(CMAKE_BUILD_TYPE "Release" CACHE STRING
...@@ -54,6 +54,7 @@ option(BUILD_EXAMPLES "Specify whether examples should be built" OFF) ...@@ -54,6 +54,7 @@ option(BUILD_EXAMPLES "Specify whether examples should be built" OFF)
option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON) option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON)
option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" 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(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)
## LOCAL INSTALLATION OF SUBPROJECT BINARIES ## LOCAL INSTALLATION OF SUBPROJECT BINARIES
# #
......
Embedded Multicore Building Blocks (EMB²) Embedded Multicore Building Blocks (EMB²)
========================================= =========================================
Overview Overview
...@@ -13,7 +13,7 @@ license (see file include\embb\mtapi\c\mtapi.h). ...@@ -13,7 +13,7 @@ license (see file include\embb\mtapi\c\mtapi.h).
License License
------- -------
Copyright (c) 2014, Siemens AG. All rights reserved. Copyright (c) 2014-2015, Siemens AG. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
...@@ -35,4 +35,4 @@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ...@@ -35,4 +35,4 @@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
...@@ -120,9 +120,9 @@ data structures for storing object in an organized and thread-safe way. ...@@ -120,9 +120,9 @@ data structures for storing object in an organized and thread-safe way.
Build and Installation Build and Installation
---------------------- ----------------------
Note: It is recommended to build from a packaged release file and not from a Note: It is recommended to build from a release file and not from a repository
snapshot of the repository in order to get the documentation and the examples snapshot in order to get the documentation and the examples out-of-the box.
out-of-the box. The release files can be found at https://github.com/siemens/embb/releases.
EMB² is built using CMake (version 2.8.9 or higher). CMake is a build file EMB² is built using CMake (version 2.8.9 or higher). CMake is a build file
generator which allows to abstract from the concrete build tools. To generate generator which allows to abstract from the concrete build tools. To generate
...@@ -159,11 +159,24 @@ use: ...@@ -159,11 +159,24 @@ use:
cmake .. -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang cmake .. -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang
In the same way you may cross compile to another platform. For example, to cross
compile to ARM Linux using GCC, you need to specify the cross compiler itself and
the target architecture as an argument to the compiler:
cmake .. -DCMAKE_CXX_COMPILER=arm-linux-gnueabi-gcc++
-DCMAKE_CXX_FLAGS=-march=armv7-a
-DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc
-DCMAKE_C_FLAGS=-march=armv7-a
EMB² can be built with and without C++ exception handling, which has to be EMB² can be built with and without C++ exception handling, which has to be
specified on build file generation. When exceptions are turned off, an error specified on build file generation. When exceptions are turned off, an error
message is emitted and the program aborts in case of an exception within EMB². message is emitted and the program aborts in case of an exception within EMB².
To disable exceptions, add the option -DUSE_EXCEPTIONS=OFF. To disable exceptions, add the option -DUSE_EXCEPTIONS=OFF.
Similarly, automatic initialization of the task scheduler by the MTAPI C++
interface can be disabled with -DUSE_AUTOMATIC_INITIALIZATION=OFF. This way,
unexpected delays after startup can be avoided, e.g. for timing measurements.
The tutorial of EMB² comes with example source files in doc/examples/. These The tutorial of EMB² comes with example source files in doc/examples/. These
can be built with the other source files using CMake option -DBUILD_EXAMPLES=ON can be built with the other source files using CMake option -DBUILD_EXAMPLES=ON
in the generation step. Note, however, that the examples use C++11 features and in the generation step. Note, however, that the examples use C++11 features and
...@@ -175,6 +188,10 @@ For a Linux Debug build with exception handling, type ...@@ -175,6 +188,10 @@ For a Linux Debug build with exception handling, type
cmake -G "Unix Makefiles" .. -DCMAKE_BUILD_TYPE=Debug cmake -G "Unix Makefiles" .. -DCMAKE_BUILD_TYPE=Debug
For a default Linux build without automatic MTAPI C++ initialization, type
cmake .. -DUSE_AUTOMATIC_INITIALIZATION=OFF
For a Windows build (VS 2013, x86) without exception handling, type For a Windows build (VS 2013, x86) without exception handling, type
cmake -G "Visual Studio 12" .. -DUSE_EXCEPTIONS=OFF cmake -G "Visual Studio 12" .. -DUSE_EXCEPTIONS=OFF
...@@ -275,9 +292,13 @@ The C header files can be included as follows: ...@@ -275,9 +292,13 @@ The C header files can be included as follows:
Documentation Documentation
------------- -------------
EMB² comes with a tutorial, example programs, and an HTML reference The release files of EMB² come with a tutorial, example programs, and a
documentation describing the APIs, which can be found in the "doc" folder. reference manual (HTML) describing the APIs. All documentation is contained in
The root document of the HTML reference is "doc/reference/index.html". the "doc" folder. The root document of the HTML reference is
"doc/reference/index.html". Note that generated documentation files are not
under version control and hence not contained in the repository. As mentioned
above, it is therefore recommended to download one of the packaged release
files in order to have ready-to-use documentation.
Code Quality Code Quality
...@@ -310,6 +331,42 @@ The EMB² team welcomes all kinds of contributions, preferably as pull requests ...@@ -310,6 +331,42 @@ The EMB² team welcomes all kinds of contributions, preferably as pull requests
or patches via the development mailing lists (see above). If possible, please or patches via the development mailing lists (see above). If possible, please
refer to a current snapshot of the development branch. refer to a current snapshot of the development branch.
EMB² is supposed to be easily portable to platforms unsupported so far. Almost
all platform specific code is located in the base_c and base_cpp modules. All
existing platform specific code is fenced by EMBB_PLATFORM_* defines.
To distinguish between compilers, EMB² currently uses the following defines:
- EMBB_PLATFORM_COMPILER_GNUC
- EMBB_PLATFORM_COMPILER_MSVC
- EMBB_PLATFORM_COMPILER_UNKNOWN
Different architectures are distinguished using:
- EMBB_PLATFORM_ARCH_X86
- EMBB_PLATFORM_ARCH_X86_32
- EMBB_PLATFORM_ARCH_X86_64
- EMBB_PLATFORM_ARCH_ARM
- EMBB_PLATFORM_ARCH_UNKNOWN
Threading APIs are switched by:
- EMBB_PLATFORM_THREADING_WINTHREADS
- EMBB_PLATFORM_THREADING_POSIXTHREADS
Please use these defines for new platform specific code. If additional defines
are needed, they can be defined in the config.h or cmake_config.h.in files.
Important Notes
---------------
- The MTAPI C++ interface supports automatic initialization, which allows for
easy usage of the MTAPI C++, Algorithms, and Dataflow components. For
performance measurements, explicit initialization is strongly recommended
since the measurements will otherwise include the initialization time of
MTAPI.
Links Links
----- -----
......
...@@ -17,7 +17,8 @@ include_directories(${EMBB_ALGORITHMS_CPP_INCLUDE_DIRS} ...@@ -17,7 +17,8 @@ include_directories(${EMBB_ALGORITHMS_CPP_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include
${CMAKE_CURRENT_BINARY_DIR}/../base_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../base_cpp/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_cpp/include) ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_cpp/include
${CMAKE_CURRENT_BINARY_DIR}/../mtapi_cpp/include)
add_library(embb_algorithms_cpp ${EMBB_ALGORITHMS_CPP_SOURCES} add_library(embb_algorithms_cpp ${EMBB_ALGORITHMS_CPP_SOURCES}
${EMBB_ALGORITHMS_CPP_HEADERS}) ${EMBB_ALGORITHMS_CPP_HEADERS})
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
*/ */
#include <embb/algorithms/count.h> #include <embb/algorithms/count.h>
#include <embb/algorithms/execution_policy.h>
#include <embb/algorithms/for_each.h> #include <embb/algorithms/for_each.h>
#include <embb/algorithms/identity.h> #include <embb/algorithms/identity.h>
#include <embb/algorithms/invoke.h> #include <embb/algorithms/invoke.h>
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
#ifndef EMBB_ALGORITHMS_COUNT_H_ #ifndef EMBB_ALGORITHMS_COUNT_H_
#define EMBB_ALGORITHMS_COUNT_H_ #define EMBB_ALGORITHMS_COUNT_H_
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <iterator>
namespace embb { namespace embb {
namespace algorithms { namespace algorithms {
...@@ -55,7 +56,7 @@ namespace algorithms { ...@@ -55,7 +56,7 @@ namespace algorithms {
* while the algorithm is executed. * while the algorithm is executed.
* \note No guarantee is given on the execution order of the comparison * \note No guarantee is given on the execution order of the comparison
* operations. * operations.
* \see CountIf(), ExecutionPolicy * \see CountIf(), embb::mtapi::ExecutionPolicy
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam ValueType Type of \c value that is compared to the elements in the * \tparam ValueType Type of \c value that is compared to the elements in the
* range using the \c operator==. * range using the \c operator==.
...@@ -70,8 +71,8 @@ typename std::iterator_traits<RAI>::difference_type Count( ...@@ -70,8 +71,8 @@ typename std::iterator_traits<RAI>::difference_type Count(
const ValueType& value, const ValueType& value,
/**< [IN] Value that the elements in the range are compared to using /**< [IN] Value that the elements in the range are compared to using
\c operator== */ \c operator== */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the counting algorithm */ /**< [IN] embb::mtapi::ExecutionPolicy for the counting algorithm */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are sorted in parallel. Partitioning of a block stops if its size are sorted in parallel. Partitioning of a block stops if its size
...@@ -95,7 +96,7 @@ typename std::iterator_traits<RAI>::difference_type Count( ...@@ -95,7 +96,7 @@ typename std::iterator_traits<RAI>::difference_type Count(
* while the algorithm is executed. * while the algorithm is executed.
* \note No guarantee is given on the execution order of the comparison * \note No guarantee is given on the execution order of the comparison
* function. * function.
* \see Count(), ExecutionPolicy * \see Count(), embb::mtapi::ExecutionPolicy
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam ComparisonFunction Unary predicate with argument of type * \tparam ComparisonFunction Unary predicate with argument of type
* <tt>std::iterator_traits<RAI>::value_type</tt>. * <tt>std::iterator_traits<RAI>::value_type</tt>.
...@@ -110,8 +111,8 @@ typename std::iterator_traits<RAI>::difference_type CountIf( ...@@ -110,8 +111,8 @@ typename std::iterator_traits<RAI>::difference_type CountIf(
ComparisonFunction comparison, ComparisonFunction comparison,
/**< [IN] Unary predicate used to test the elements in the range. Elements for /**< [IN] Unary predicate used to test the elements in the range. Elements for
which \c comparison returns true are counted. */ which \c comparison returns true are counted. */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the counting algorithm */ /**< [IN] embb::mtapi::ExecutionPolicy for the counting algorithm */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are sorted in parallel. Partitioning of a block stops if its size are sorted in parallel. Partitioning of a block stops if its size
...@@ -124,6 +125,18 @@ typename std::iterator_traits<RAI>::difference_type CountIf( ...@@ -124,6 +125,18 @@ typename std::iterator_traits<RAI>::difference_type CountIf(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename ValueType>
typename std::iterator_traits<RAI>::difference_type Count(
RAI first,
RAI last,
const ValueType& value,
const embb::mtapi::ExecutionPolicy& policy,
size_t block_size
);
/**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAI, typename ValueType> template<typename RAI, typename ValueType>
...@@ -132,7 +145,7 @@ typename std::iterator_traits<RAI>::difference_type Count( ...@@ -132,7 +145,7 @@ typename std::iterator_traits<RAI>::difference_type Count(
RAI last, RAI last,
const ValueType& value const ValueType& value
) { ) {
return Count(first, last, value, ExecutionPolicy(), 0); return Count(first, last, value, embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -143,7 +156,7 @@ typename std::iterator_traits<RAI>::difference_type Count( ...@@ -143,7 +156,7 @@ typename std::iterator_traits<RAI>::difference_type Count(
RAI first, RAI first,
RAI last, RAI last,
const ValueType& value, const ValueType& value,
const ExecutionPolicy& policy const embb::mtapi::ExecutionPolicy& policy
) { ) {
return Count(first, last, value, policy, 0); return Count(first, last, value, policy, 0);
} }
...@@ -151,12 +164,12 @@ typename std::iterator_traits<RAI>::difference_type Count( ...@@ -151,12 +164,12 @@ typename std::iterator_traits<RAI>::difference_type Count(
/** /**
* Overload of above described Doxygen dummy. * Overload of above described Doxygen dummy.
*/ */
template<typename RAI, typename ValueType> template<typename RAI, typename ComparisonFunction>
typename std::iterator_traits<RAI>::difference_type Count( typename std::iterator_traits<RAI>::difference_type CountIf(
RAI first, RAI first,
RAI last, RAI last,
const ValueType& value, ComparisonFunction comparison,
const ExecutionPolicy& policy, const embb::mtapi::ExecutionPolicy& policy,
size_t block_size size_t block_size
); );
...@@ -169,7 +182,7 @@ typename std::iterator_traits<RAI>::difference_type CountIf( ...@@ -169,7 +182,7 @@ typename std::iterator_traits<RAI>::difference_type CountIf(
RAI last, RAI last,
ComparisonFunction comparison ComparisonFunction comparison
) { ) {
return CountIf(first, last, comparison, ExecutionPolicy(), 0); return CountIf(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -180,23 +193,11 @@ typename std::iterator_traits<RAI>::difference_type CountIf( ...@@ -180,23 +193,11 @@ typename std::iterator_traits<RAI>::difference_type CountIf(
RAI first, RAI first,
RAI last, RAI last,
ComparisonFunction comparison, ComparisonFunction comparison,
const ExecutionPolicy& policy const embb::mtapi::ExecutionPolicy& policy
) { ) {
return CountIf(first, last, comparison, policy, 0); return CountIf(first, last, comparison, policy, 0);
} }
/**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename ComparisonFunction>
typename std::iterator_traits<RAI>::difference_type CountIf(
RAI first,
RAI last,
ComparisonFunction comparison,
const ExecutionPolicy& policy,
size_t block_size
);
#endif // else DOXYGEN #endif // else DOXYGEN
/** /**
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef EMBB_ALGORITHMS_FOR_EACH_H_ #ifndef EMBB_ALGORITHMS_FOR_EACH_H_
#define EMBB_ALGORITHMS_FOR_EACH_H_ #define EMBB_ALGORITHMS_FOR_EACH_H_
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
namespace embb { namespace embb {
namespace algorithms { namespace algorithms {
...@@ -53,7 +53,7 @@ namespace algorithms { ...@@ -53,7 +53,7 @@ namespace algorithms {
* while the algorithm is executed. * while the algorithm is executed.
* \note No guarantee is given on the order in which the function is applied to * \note No guarantee is given on the order in which the function is applied to
* the elements. * the elements.
* \see ExecutionPolicy, ZipIterator * \see embb::mtapi::ExecutionPolicy, ZipIterator
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam Function Unary function with argument of type * \tparam Function Unary function with argument of type
* <tt>std::iterator_traits<RAI>::value_type</tt>. * <tt>std::iterator_traits<RAI>::value_type</tt>.
...@@ -67,8 +67,8 @@ void ForEach( ...@@ -67,8 +67,8 @@ void ForEach(
range */ range */
Function unary, Function unary,
/**< [IN] Unary function applied to each element in the range */ /**< [IN] Unary function applied to each element in the range */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the foreach loop execution */ /**< [IN] embb::mtapi::ExecutionPolicy for the foreach loop execution */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are treated in parallel. Partitioning of a block stops if its size are treated in parallel. Partitioning of a block stops if its size
...@@ -81,16 +81,16 @@ void ForEach( ...@@ -81,16 +81,16 @@ void ForEach(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy.
*/ */
template<typename RAI, typename Function> template<typename RAI, typename Function>
void ForEach( void ForEach(
RAI first, RAI first,
RAI last, RAI last,
Function unary Function unary,
) { const embb::mtapi::ExecutionPolicy& policy,
ForEach(first, last, unary, ExecutionPolicy(), 0); size_t block_size
} );
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
...@@ -99,23 +99,23 @@ template<typename RAI, typename Function> ...@@ -99,23 +99,23 @@ template<typename RAI, typename Function>
void ForEach( void ForEach(
RAI first, RAI first,
RAI last, RAI last,
Function unary, Function unary
const ExecutionPolicy& policy
) { ) {
ForEach(first, last, unary, policy, 0); ForEach(first, last, unary, embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
* Overload of above described Doxygen dummy. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAI, typename Function> template<typename RAI, typename Function>
void ForEach( void ForEach(
RAI first, RAI first,
RAI last, RAI last,
Function unary, Function unary,
const ExecutionPolicy& policy, const embb::mtapi::ExecutionPolicy& policy
size_t block_size ) {
); ForEach(first, last, unary, policy, 0);
}
#endif // else DOXYGEN #endif // else DOXYGEN
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -37,42 +37,45 @@ namespace internal { ...@@ -37,42 +37,45 @@ namespace internal {
template<typename ValueType> template<typename ValueType>
class ValueComparisonFunction{ class ValueComparisonFunction{
public: public:
explicit ValueComparisonFunction(const ValueType &value) explicit ValueComparisonFunction(const ValueType& value)
:value_(value) {} : value_(value) {}
ValueComparisonFunction(const ValueComparisonFunction &other) ValueComparisonFunction(const ValueComparisonFunction& other)
:value_(other.value_) {} : value_(other.value_) {}
template<typename ElementType> template<typename ElementType>
int operator()(ElementType element) { int operator()(ElementType element) {
if(element == value_) if (element == value_) {
return 1; return 1;
else } else {
return 0; return 0;
}
} }
private: private:
const ValueType &value_; const ValueType &value_;
ValueComparisonFunction &operator=(const ValueComparisonFunction &other); ValueComparisonFunction &operator=(
const ValueComparisonFunction& other);
}; };
template<typename Function> template<typename Function>
class FunctionComparisonFunction{ class FunctionComparisonFunction{
public: public:
explicit FunctionComparisonFunction(Function function) explicit FunctionComparisonFunction(Function function)
:function_(function) {} : function_(function) {}
FunctionComparisonFunction(const FunctionComparisonFunction &other) FunctionComparisonFunction(const FunctionComparisonFunction &other)
:function_(other.function_) {} : function_(other.function_) {}
template<typename ElementType> template<typename ElementType>
int operator()(ElementType element) { int operator()(ElementType element) {
if(function_(element)) if (function_(element)) {
return 1; return 1;
else } else {
return 0; return 0;
}
} }
private: private:
Function function_; Function function_;
FunctionComparisonFunction &operator=(const FunctionComparisonFunction & FunctionComparisonFunction &operator=(
other); const FunctionComparisonFunction& other);
}; };
} // namespace internal } // namespace internal
...@@ -80,7 +83,7 @@ class FunctionComparisonFunction{ ...@@ -80,7 +83,7 @@ class FunctionComparisonFunction{
template<typename RAI, typename ValueType> template<typename RAI, typename ValueType>
typename std::iterator_traits<RAI>::difference_type typename std::iterator_traits<RAI>::difference_type
Count(RAI first, RAI last, const ValueType& value, Count(RAI first, RAI last, const ValueType& value,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy, size_t block_size) {
typedef typename std::iterator_traits<RAI>::difference_type Difference; typedef typename std::iterator_traits<RAI>::difference_type Difference;
return Reduce(first, last, Difference(0), std::plus<Difference>(), return Reduce(first, last, Difference(0), std::plus<Difference>(),
internal::ValueComparisonFunction<ValueType>(value), policy, internal::ValueComparisonFunction<ValueType>(value), policy,
...@@ -90,7 +93,7 @@ typename std::iterator_traits<RAI>::difference_type ...@@ -90,7 +93,7 @@ typename std::iterator_traits<RAI>::difference_type
template<typename RAI, typename ComparisonFunction> template<typename RAI, typename ComparisonFunction>
typename std::iterator_traits<RAI>::difference_type typename std::iterator_traits<RAI>::difference_type
CountIf(RAI first, RAI last, ComparisonFunction comparison, CountIf(RAI first, RAI last, ComparisonFunction comparison,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy, size_t block_size) {
typedef typename std::iterator_traits<RAI>::difference_type Difference; typedef typename std::iterator_traits<RAI>::difference_type Difference;
return Reduce(first, last, Difference(0), std::plus<Difference>(), return Reduce(first, last, Difference(0), std::plus<Difference>(),
internal::FunctionComparisonFunction<ComparisonFunction> internal::FunctionComparisonFunction<ComparisonFunction>
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -45,44 +45,54 @@ class ForEachFunctor { ...@@ -45,44 +45,54 @@ class ForEachFunctor {
/** /**
* Constructs a for-each functor with arguments. * Constructs a for-each functor with arguments.
*/ */
ForEachFunctor(RAI first, RAI last, Function unary, ForEachFunctor(size_t chunk_first, size_t chunk_last, Function unary,
const ExecutionPolicy& policy, size_t block_size) const embb::mtapi::ExecutionPolicy& policy,
: first_(first), last_(last), unary_(unary), policy_(policy), const BlockSizePartitioner<RAI>& partitioner)
block_size_(block_size) { : chunk_first_(chunk_first), chunk_last_(chunk_last),
unary_(unary), policy_(policy), partitioner_(partitioner) {
} }
void Action(mtapi::TaskContext&) { void Action(mtapi::TaskContext&) {
size_t distance = static_cast<size_t>(std::distance(first_, last_)); if (chunk_first_ == chunk_last_) {
if (distance == 0) return; // Leaf case, recursed to single chunk. Do work on chunk:
if (distance <= block_size_) { // leaf case -> do work ChunkDescriptor<RAI> chunk = partitioner_[chunk_first_];
for (RAI curIter(first_); curIter != last_; ++curIter) { RAI first = chunk.GetFirst();
unary_(*curIter); RAI last = chunk.GetLast();
for (RAI it = first; it != last; ++it) {
unary_(*it);
} }
} else { // recurse further } else {
ChunkPartitioner<RAI> partitioner(first_, last_, 2); // Recurse further:
ForEachFunctor<RAI, Function> functorL(partitioner[0].GetFirst(), size_t chunk_split_index = (chunk_first_ + chunk_last_) / 2;
partitioner[0].GetLast(), unary_, policy_, block_size_); // Split chunks into left / right branches:
ForEachFunctor<RAI, Function> functorR(partitioner[1].GetFirst(), self_t functor_l(chunk_first_,
partitioner[1].GetLast(), unary_, policy_, block_size_); chunk_split_index,
unary_, policy_, partitioner_);
mtapi::Node& node = mtapi::Node::GetInstance(); self_t functor_r(chunk_split_index + 1,
mtapi::Task taskL = node.Spawn(mtapi::Action(base::MakeFunction( chunk_last_,
functorL, &ForEachFunctor<RAI, Function>::Action), unary_, policy_, partitioner_);
policy_.GetAffinity()), policy_.GetPriority()); mtapi::Task task_l = mtapi::Node::GetInstance().Spawn(
mtapi::Task taskR = node.Spawn(mtapi::Action(base::MakeFunction( mtapi::Action(
functorR, &ForEachFunctor<RAI, Function>::Action), base::MakeFunction(functor_l, &self_t::Action),
policy_.GetAffinity()), policy_.GetPriority()); policy_));
taskL.Wait(MTAPI_INFINITE); mtapi::Task task_r = mtapi::Node::GetInstance().Spawn(
taskR.Wait(MTAPI_INFINITE); mtapi::Action(
base::MakeFunction(functor_r, &self_t::Action),
policy_));
task_l.Wait(MTAPI_INFINITE);
task_r.Wait(MTAPI_INFINITE);
} }
} }
private: private:
RAI first_; typedef ForEachFunctor<RAI, Function> self_t;
RAI last_;
private:
size_t chunk_first_;
size_t chunk_last_;
Function unary_; Function unary_;
const ExecutionPolicy& policy_; const embb::mtapi::ExecutionPolicy& policy_;
size_t block_size_; const BlockSizePartitioner<RAI>& partitioner_;
/** /**
* Disables assignment. * Disables assignment.
...@@ -92,34 +102,44 @@ class ForEachFunctor { ...@@ -92,34 +102,44 @@ class ForEachFunctor {
template<typename RAI, typename Function> template<typename RAI, typename Function>
void ForEachRecursive(RAI first, RAI last, Function unary, void ForEachRecursive(RAI first, RAI last, Function unary,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy, size_t block_size) {
typedef typename std::iterator_traits<RAI>::difference_type difference_type; typedef typename std::iterator_traits<RAI>::difference_type difference_type;
difference_type distance = std::distance(first, last); difference_type distance = std::distance(first, last);
assert(distance > 0); if (distance == 0) {
return;
}
unsigned int num_cores = policy.GetCoreCount();
if (num_cores == 0) {
EMBB_THROW(embb::base::ErrorException, "No cores in execution policy");
}
mtapi::Node& node = mtapi::Node::GetInstance(); mtapi::Node& node = mtapi::Node::GetInstance();
// Determine actually used block size // Determine actually used block size
if (block_size == 0) { if (block_size == 0) {
block_size = (static_cast<size_t>(distance) / node.GetCoreCount()); block_size = (static_cast<size_t>(distance) / num_cores);
if (block_size == 0) { if (block_size == 0) {
block_size = 1; block_size = 1;
} }
} }
// Perform check of task number sufficiency // Check task number sufficiency
if (((distance / block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) { if (((distance / block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) {
EMBB_THROW(embb::base::ErrorException, "Not enough MTAPI tasks available " EMBB_THROW(embb::base::ErrorException,
"to perform the parallel foreach loop"); "Not enough MTAPI tasks available for parallel foreach");
} }
ForEachFunctor<RAI, Function> functor(first, last, unary, policy, block_size);
BlockSizePartitioner<RAI> partitioner(first, last, block_size);
ForEachFunctor<RAI, Function> functor(0,
partitioner.Size() - 1,
unary, policy, partitioner);
mtapi::Task task = node.Spawn(mtapi::Action( mtapi::Task task = node.Spawn(mtapi::Action(
base::MakeFunction(functor, base::MakeFunction(functor,
&ForEachFunctor<RAI, Function>::Action), &ForEachFunctor<RAI, Function>::Action),
policy.GetAffinity()), policy.GetPriority()); policy));
task.Wait(MTAPI_INFINITE); task.Wait(MTAPI_INFINITE);
} }
template<typename RAI, typename Function> template<typename RAI, typename Function>
void ForEachIteratorCheck(RAI first, RAI last, Function unary, void ForEachIteratorCheck(RAI first, RAI last, Function unary,
const ExecutionPolicy& policy, size_t block_size, const embb::mtapi::ExecutionPolicy& policy, size_t block_size,
std::random_access_iterator_tag) { std::random_access_iterator_tag) {
return ForEachRecursive(first, last, unary, policy, block_size); return ForEachRecursive(first, last, unary, policy, block_size);
} }
...@@ -127,8 +147,8 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary, ...@@ -127,8 +147,8 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary,
} // namespace internal } // namespace internal
template<typename RAI, typename Function> template<typename RAI, typename Function>
void ForEach(RAI first, RAI last, Function unary, const ExecutionPolicy& policy, void ForEach(RAI first, const RAI last, Function unary,
size_t block_size) { const embb::mtapi::ExecutionPolicy& policy, size_t block_size) {
typename std::iterator_traits<RAI>::iterator_category category; typename std::iterator_traits<RAI>::iterator_category category;
internal::ForEachIteratorCheck(first, last, unary, policy, block_size, internal::ForEachIteratorCheck(first, last, unary, policy, block_size,
category); category);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -71,8 +71,8 @@ const ChunkDescriptor<ForwardIterator> ...@@ -71,8 +71,8 @@ const ChunkDescriptor<ForwardIterator>
ForwardIterator last_new = first_new; ForwardIterator last_new = first_new;
if (index == elements_count / chunkSize) { if (index >= chunks - 1) {
std::advance(last_new, elements_count % chunkSize); last_new = last;
} else { } else {
std::advance(last_new, chunkSize); std::advance(last_new, chunkSize);
} }
...@@ -94,7 +94,7 @@ ChunkPartitioner<ForwardIterator>::ChunkPartitioner(ForwardIterator first, ...@@ -94,7 +94,7 @@ ChunkPartitioner<ForwardIterator>::ChunkPartitioner(ForwardIterator first,
} else { } else {
// if no concrete chunk size was given, use number of cores... // if no concrete chunk size was given, use number of cores...
mtapi::Node& node = mtapi::Node::GetInstance(); mtapi::Node& node = mtapi::Node::GetInstance();
size = node.GetCoreCount(); size = node.GetWorkerThreadCount();
} }
elements_count = static_cast<size_t>(std::distance(first, last)); elements_count = static_cast<size_t>(std::distance(first, last));
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -48,7 +48,7 @@ class QuickSortFunctor { ...@@ -48,7 +48,7 @@ class QuickSortFunctor {
* Constructs a functor. * Constructs a functor.
*/ */
QuickSortFunctor(RAI first, RAI last, ComparisonFunction comparison, QuickSortFunctor(RAI first, RAI last, ComparisonFunction comparison,
const ExecutionPolicy& policy, size_t block_size) const embb::mtapi::ExecutionPolicy& policy, size_t block_size)
: first_(first), last_(last), comparison_(comparison), policy_(policy), : first_(first), last_(last), comparison_(comparison), policy_(policy),
block_size_(block_size) { block_size_(block_size) {
} }
...@@ -87,7 +87,7 @@ class QuickSortFunctor { ...@@ -87,7 +87,7 @@ class QuickSortFunctor {
RAI first_; RAI first_;
RAI last_; RAI last_;
ComparisonFunction comparison_; ComparisonFunction comparison_;
const ExecutionPolicy& policy_; const embb::mtapi::ExecutionPolicy& policy_;
size_t block_size_; size_t block_size_;
typedef typename std::iterator_traits<RAI>::difference_type Difference; typedef typename std::iterator_traits<RAI>::difference_type Difference;
...@@ -190,12 +190,19 @@ class QuickSortFunctor { ...@@ -190,12 +190,19 @@ class QuickSortFunctor {
template <typename RAI, typename ComparisonFunction> template <typename RAI, typename ComparisonFunction>
void QuickSort(RAI first, RAI last, ComparisonFunction comparison, void QuickSort(RAI first, RAI last, ComparisonFunction comparison,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy, size_t block_size) {
embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); embb::mtapi::Node& node = embb::mtapi::Node::GetInstance();
typename std::iterator_traits<RAI>::difference_type distance = last - first; typedef typename std::iterator_traits<RAI>::difference_type difference_type;
assert(distance > 0); difference_type distance = std::distance(first, last);
if (distance <= 0) {
return;
}
unsigned int num_cores = policy.GetCoreCount();
if (num_cores == 0) {
EMBB_THROW(embb::base::ErrorException, "No cores in execution policy");
}
if (block_size == 0) { if (block_size == 0) {
block_size= (static_cast<size_t>(distance) / node.GetCoreCount()); block_size = (static_cast<size_t>(distance) / num_cores);
if (block_size == 0) if (block_size == 0)
block_size = 1; block_size = 1;
} }
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -42,47 +42,55 @@ template<typename RAI, typename ReturnType, typename ReductionFunction, ...@@ -42,47 +42,55 @@ template<typename RAI, typename ReturnType, typename ReductionFunction,
typename TransformationFunction> typename TransformationFunction>
class ReduceFunctor { class ReduceFunctor {
public: public:
ReduceFunctor(RAI first, RAI last, ReturnType neutral, ReduceFunctor(size_t chunk_first, size_t chunk_last,
ReturnType neutral,
ReductionFunction reduction, ReductionFunction reduction,
TransformationFunction transformation, TransformationFunction transformation,
const ExecutionPolicy &policy, size_t block_size, const embb::mtapi::ExecutionPolicy& policy,
const BlockSizePartitioner<RAI>& partitioner,
ReturnType& result) ReturnType& result)
: : chunk_first_(chunk_first), chunk_last_(chunk_last), neutral_(neutral),
first_(first), last_(last), neutral_(neutral), reduction_(reduction), reduction_(reduction), transformation_(transformation), policy_(policy),
transformation_(transformation), policy_(policy), partitioner_(partitioner), result_(result) {
block_size_(block_size), result_(result) {
} }
void Action(mtapi::TaskContext&) { void Action(mtapi::TaskContext&) {
if (first_ == last_) { if (chunk_first_ == chunk_last_) {
return; // Leaf case, recursed to single chunk. Do work on chunk:
} ChunkDescriptor<RAI> chunk = partitioner_[chunk_first_];
size_t distance = static_cast<size_t>(std::distance(first_, last_)); RAI first = chunk.GetFirst();
if (distance <= block_size_) { // leaf case -> do work RAI last = chunk.GetLast();
ReturnType result(neutral_); ReturnType result(neutral_);
for (RAI iter = first_; iter != last_; ++iter) { for (RAI it = first; it != last; ++it) {
result = reduction_(result, transformation_(*iter)); result = reduction_(result, transformation_(*it));
} }
result_ = result; result_ = result;
} else { // recurse further } else {
internal::ChunkPartitioner<RAI> partitioner(first_, last_, 2); // Recurse further:
size_t chunk_split_index = (chunk_first_ + chunk_last_) / 2;
// Split chunks into left / right branches:
ReturnType result_l(neutral_); ReturnType result_l(neutral_);
ReturnType result_r(neutral_); ReturnType result_r(neutral_);
ReduceFunctor functor_l(partitioner[0].GetFirst(), self_t functor_l(chunk_first_,
partitioner[0].GetLast(), chunk_split_index,
neutral_, reduction_, transformation_, policy_, neutral_, reduction_, transformation_, policy_,
block_size_, result_l); partitioner_,
ReduceFunctor functor_r(partitioner[1].GetFirst(), result_l);
partitioner[1].GetLast(), self_t functor_r(chunk_split_index + 1,
neutral_, reduction_, transformation_, policy_, chunk_last_,
block_size_, result_r); neutral_, reduction_, transformation_, policy_,
mtapi::Node& node = mtapi::Node::GetInstance(); partitioner_,
mtapi::Task task_l = node.Spawn(mtapi::Action(base::MakeFunction( result_r);
functor_l, &ReduceFunctor::Action), policy_.GetAffinity()), mtapi::Task task_l = mtapi::Node::GetInstance().Spawn(
policy_.GetPriority()); mtapi::Action(
mtapi::Task task_r = node.Spawn(mtapi::Action(base::MakeFunction( base::MakeFunction(
functor_r, &ReduceFunctor::Action), policy_.GetAffinity()), functor_l, &self_t::Action),
policy_.GetPriority()); policy_));
mtapi::Task task_r = mtapi::Node::GetInstance().Spawn(
mtapi::Action(
base::MakeFunction(
functor_r, &self_t::Action),
policy_));
task_l.Wait(MTAPI_INFINITE); task_l.Wait(MTAPI_INFINITE);
task_r.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE);
result_ = reduction_(result_l, result_r); result_ = reduction_(result_l, result_r);
...@@ -90,15 +98,23 @@ class ReduceFunctor { ...@@ -90,15 +98,23 @@ class ReduceFunctor {
} }
private: private:
RAI first_; typedef ReduceFunctor<RAI, ReturnType,
RAI last_; ReductionFunction,
TransformationFunction> self_t;
private:
size_t chunk_first_;
size_t chunk_last_;
ReturnType neutral_; ReturnType neutral_;
ReductionFunction reduction_; ReductionFunction reduction_;
TransformationFunction transformation_; TransformationFunction transformation_;
const ExecutionPolicy& policy_; const embb::mtapi::ExecutionPolicy& policy_;
size_t block_size_; const BlockSizePartitioner<RAI>& partitioner_;
ReturnType& result_; ReturnType& result_;
/**
* Disables assignment and copy-construction.
*/
ReduceFunctor& operator=(const ReduceFunctor&); ReduceFunctor& operator=(const ReduceFunctor&);
ReduceFunctor(const ReduceFunctor&); ReduceFunctor(const ReduceFunctor&);
}; };
...@@ -108,31 +124,45 @@ template<typename RAI, typename ReturnType, typename ReductionFunction, ...@@ -108,31 +124,45 @@ template<typename RAI, typename ReturnType, typename ReductionFunction,
ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral, ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral,
ReductionFunction reduction, ReductionFunction reduction,
TransformationFunction transformation, TransformationFunction transformation,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy,
size_t block_size) {
typedef typename std::iterator_traits<RAI>::difference_type difference_type; typedef typename std::iterator_traits<RAI>::difference_type difference_type;
difference_type distance = std::distance(first, last); difference_type distance = std::distance(first, last);
assert(distance > 0); if (distance == 0) {
EMBB_THROW(embb::base::ErrorException, "Distance for Reduce is 0");
}
unsigned int num_cores = policy.GetCoreCount();
if (num_cores == 0) {
EMBB_THROW(embb::base::ErrorException, "No cores in execution policy");
}
mtapi::Node& node = mtapi::Node::GetInstance(); mtapi::Node& node = mtapi::Node::GetInstance();
size_t used_block_size = block_size; // Determine actually used block size
if (used_block_size == 0) { if (block_size == 0) {
used_block_size = static_cast<size_t>(distance) / node.GetCoreCount(); block_size = (static_cast<size_t>(distance) / num_cores);
if (used_block_size == 0) used_block_size = 1; if (block_size == 0) {
block_size = 1;
}
} }
// Perform check of task number sufficiency
if (((distance / used_block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) { if (((distance / block_size) * 2) + 1 > MTAPI_NODE_MAX_TASKS_DEFAULT) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"Number of computation tasks required in reduction would " "Number of computation tasks required in reduction would "
"exceed MTAPI maximum number of tasks"); "exceed MTAPI maximum number of tasks");
} }
ReturnType result = neutral;
typedef ReduceFunctor<RAI, ReturnType, ReductionFunction, typedef ReduceFunctor<RAI, ReturnType, ReductionFunction,
TransformationFunction> Functor; TransformationFunction> Functor;
Functor functor(first, last, neutral, reduction, transformation, policy, BlockSizePartitioner<RAI> partitioner(first, last, block_size);
used_block_size, result); ReturnType result = neutral;
mtapi::Task task = node.Spawn(mtapi::Action(base::MakeFunction( Functor functor(0,
functor, &Functor::Action), policy.GetAffinity()), policy.GetPriority()); partitioner.Size() - 1,
neutral,
reduction, transformation,
policy,
partitioner,
result);
mtapi::Task task = node.Spawn(
mtapi::Action(base::MakeFunction(
functor, &Functor::Action), policy));
task.Wait(MTAPI_INFINITE); task.Wait(MTAPI_INFINITE);
return result; return result;
} }
...@@ -142,7 +172,8 @@ template<typename RAI, typename TransformationFunction, ...@@ -142,7 +172,8 @@ template<typename RAI, typename TransformationFunction,
ReturnType ReduceIteratorCheck(RAI first, RAI last, ReductionFunction reduction, ReturnType ReduceIteratorCheck(RAI first, RAI last, ReductionFunction reduction,
TransformationFunction transformation, TransformationFunction transformation,
ReturnType neutral, ReturnType neutral,
const ExecutionPolicy& policy, size_t block_size, const embb::mtapi::ExecutionPolicy& policy,
size_t block_size,
std::random_access_iterator_tag) { std::random_access_iterator_tag) {
return ReduceRecursive(first, last, neutral, reduction, transformation, return ReduceRecursive(first, last, neutral, reduction, transformation,
policy, block_size); policy, block_size);
...@@ -155,7 +186,8 @@ template<typename RAI, typename ReturnType, typename ReductionFunction, ...@@ -155,7 +186,8 @@ template<typename RAI, typename ReturnType, typename ReductionFunction,
ReturnType Reduce(RAI first, RAI last, ReturnType neutral, ReturnType Reduce(RAI first, RAI last, ReturnType neutral,
ReductionFunction reduction, ReductionFunction reduction,
TransformationFunction transformation, TransformationFunction transformation,
const ExecutionPolicy& policy, size_t block_size) { const embb::mtapi::ExecutionPolicy& policy,
size_t block_size) {
typename std::iterator_traits<RAI>::iterator_category category; typename std::iterator_traits<RAI>::iterator_category category;
return internal::ReduceIteratorCheck(first, last, reduction, transformation, return internal::ReduceIteratorCheck(first, last, reduction, transformation,
neutral, policy, block_size, category); neutral, policy, block_size, category);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define EMBB_ALGORITHMS_MERGE_SORT_H_ #define EMBB_ALGORITHMS_MERGE_SORT_H_
#include <functional> #include <functional>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <embb/base/memory_allocation.h> #include <embb/base/memory_allocation.h>
namespace embb { namespace embb {
...@@ -59,7 +59,7 @@ namespace algorithms { ...@@ -59,7 +59,7 @@ namespace algorithms {
* modified by another thread while the algorithm is executed. * modified by another thread while the algorithm is executed.
* \note No guarantee is given on the execution order of the comparison * \note No guarantee is given on the execution order of the comparison
operations. operations.
* \see ExecutionPolicy, MergeSort() * \see embb::mtapi::ExecutionPolicy, MergeSort()
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam ComparisonFunction Binary predicate with both arguments of type * \tparam ComparisonFunction Binary predicate with both arguments of type
* <tt>std::iterator_traits<RAI>::value_type</tt>. * <tt>std::iterator_traits<RAI>::value_type</tt>.
...@@ -77,8 +77,8 @@ void MergeSortAllocate( ...@@ -77,8 +77,8 @@ void MergeSortAllocate(
\c a appears before an element \c b in the sorted range if \c a appears before an element \c b in the sorted range if
<tt>comparison(a, b) == true</tt>. The default value uses the <tt>comparison(a, b) == true</tt>. The default value uses the
less-than relation. */ less-than relation. */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the merge sort algorithm */ /**< [IN] embb::mtapi::ExecutionPolicy for the merge sort algorithm */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are sorted in parallel. Partitioning of a block stops if its size are sorted in parallel. Partitioning of a block stops if its size
...@@ -105,7 +105,7 @@ void MergeSortAllocate( ...@@ -105,7 +105,7 @@ void MergeSortAllocate(
* modified by another thread while the algorithm is executed. * modified by another thread while the algorithm is executed.
* \note No guarantee is given on the execution order of the comparison * \note No guarantee is given on the execution order of the comparison
* operations. * operations.
* \see ExecutionPolicy, MergeSortAllocate() * \see embb::mtapi::ExecutionPolicy, MergeSortAllocate()
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam RAITemp Random access iterator for temporary memory. Has to have the * \tparam RAITemp Random access iterator for temporary memory. Has to have the
* same value type as RAI. * same value type as RAI.
...@@ -127,8 +127,8 @@ void MergeSort( ...@@ -127,8 +127,8 @@ void MergeSort(
\c a appears before an element \c b in the sorted range if \c a appears before an element \c b in the sorted range if
<tt>comparison(a, b) == true</tt>. The default value uses the <tt>comparison(a, b) == true</tt>. The default value uses the
less-than relation. */ less-than relation. */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the merge sort algorithm */ /**< [IN] embb::mtapi::ExecutionPolicy for the merge sort algorithm */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are sorted in parallel. Partitioning of a block stops if its size are sorted in parallel. Partitioning of a block stops if its size
...@@ -141,28 +141,49 @@ void MergeSort( ...@@ -141,28 +141,49 @@ void MergeSort(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy.
*/ */
template<typename RAI> template<typename RAI, typename RAITemp, typename ComparisonFunction>
void MergeSort(
RAI first,
RAI last,
RAITemp temporary_first,
ComparisonFunction comparison,
const embb::mtapi::ExecutionPolicy& policy,
size_t block_size
);
/**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename ComparisonFunction>
void MergeSortAllocate( void MergeSortAllocate(
RAI first, RAI first,
RAI last RAI last,
ComparisonFunction comparison,
const embb::mtapi::ExecutionPolicy& policy,
size_t block_size
) { ) {
MergeSortAllocate(first, last, typedef base::Allocation Alloc;
std::less<typename std::iterator_traits<RAI>::value_type>(), typename std::iterator_traits<RAI>::difference_type distance = last - first;
ExecutionPolicy(), 0); typedef typename std::iterator_traits<RAI>::value_type value_type;
value_type* temporary = static_cast<value_type*>(
Alloc::Allocate(distance * sizeof(value_type)));
MergeSort(first, last, temporary, comparison, policy, block_size);
Alloc::Free(temporary);
} }
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAI, typename ComparisonFunction> template<typename RAI>
void MergeSortAllocate( void MergeSortAllocate(
RAI first, RAI first,
RAI last, RAI last
ComparisonFunction comparison
) { ) {
MergeSortAllocate(first, last, comparison, ExecutionPolicy(), 0); MergeSortAllocate(first, last,
std::less<typename std::iterator_traits<RAI>::value_type>(),
embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -172,30 +193,22 @@ template<typename RAI, typename ComparisonFunction> ...@@ -172,30 +193,22 @@ template<typename RAI, typename ComparisonFunction>
void MergeSortAllocate( void MergeSortAllocate(
RAI first, RAI first,
RAI last, RAI last,
ComparisonFunction comparison, ComparisonFunction comparison
const ExecutionPolicy& policy
) { ) {
MergeSortAllocate(first, last, comparison, policy, 0); MergeSortAllocate(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
* Overload of above described Doxygen dummy. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAI, typename ComparisonFunction> template<typename RAI, typename ComparisonFunction>
void MergeSortAllocate( void MergeSortAllocate(
RAI first, RAI first,
RAI last, RAI last,
ComparisonFunction comparison, ComparisonFunction comparison,
const ExecutionPolicy& policy, const embb::mtapi::ExecutionPolicy& policy
size_t block_size
) { ) {
typedef base::Allocation Alloc; MergeSortAllocate(first, last, comparison, policy, 0);
typename std::iterator_traits<RAI>::difference_type distance = last - first;
typedef typename std::iterator_traits<RAI>::value_type value_type;
value_type* temporary = static_cast<value_type*>(
Alloc::Allocate(distance * sizeof(value_type)));
MergeSort(first, last, temporary, comparison, policy, block_size);
Alloc::Free(temporary);
} }
/** /**
...@@ -209,7 +222,7 @@ void MergeSort( ...@@ -209,7 +222,7 @@ void MergeSort(
) { ) {
MergeSort(first, last, temporary_first, MergeSort(first, last, temporary_first,
std::less<typename std::iterator_traits<RAI>::value_type>(), std::less<typename std::iterator_traits<RAI>::value_type>(),
ExecutionPolicy(), 0); embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -222,7 +235,8 @@ void MergeSort( ...@@ -222,7 +235,8 @@ void MergeSort(
RAITemp temporary_first, RAITemp temporary_first,
ComparisonFunction comparison ComparisonFunction comparison
) { ) {
MergeSort(first, last, temporary_first, comparison, ExecutionPolicy(), 0); MergeSort(first, last, temporary_first, comparison,
embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -234,24 +248,11 @@ void MergeSort( ...@@ -234,24 +248,11 @@ void MergeSort(
RAI last, RAI last,
RAITemp temporary_first, RAITemp temporary_first,
ComparisonFunction comparison, ComparisonFunction comparison,
const ExecutionPolicy& policy const embb::mtapi::ExecutionPolicy& policy
) { ) {
MergeSort(first, last, temporary_first, comparison, policy, 0); MergeSort(first, last, temporary_first, comparison, policy, 0);
} }
/**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename RAITemp, typename ComparisonFunction>
void MergeSort(
const ExecutionPolicy& policy,
RAI first,
RAI last,
RAITemp temporary_first,
ComparisonFunction comparison,
size_t block_size
);
#endif // else DOXYGEN #endif // else DOXYGEN
/** /**
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define EMBB_ALGORITHMS_QUICK_SORT_H_ #define EMBB_ALGORITHMS_QUICK_SORT_H_
#include <functional> #include <functional>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
namespace embb { namespace embb {
namespace algorithms { namespace algorithms {
...@@ -54,7 +54,7 @@ namespace algorithms { ...@@ -54,7 +54,7 @@ namespace algorithms {
* modified by another thread while the algorithm is executed. * modified by another thread while the algorithm is executed.
* \note No guarantee is given on the execution order of the comparison * \note No guarantee is given on the execution order of the comparison
* operations. * operations.
* \see ExecutionPolicy, MergeSort() * \see embb::mtapi::ExecutionPolicy, MergeSort()
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam ComparisonFunction Binary predicate with both arguments of type * \tparam ComparisonFunction Binary predicate with both arguments of type
* <tt>std::iterator_traits<RAI>::value_type</tt>. * <tt>std::iterator_traits<RAI>::value_type</tt>.
...@@ -72,8 +72,8 @@ void QuickSort( ...@@ -72,8 +72,8 @@ void QuickSort(
\c a appears before an element \c b in the sorted range if \c a appears before an element \c b in the sorted range if
<tt>comparison(a, b) == true</tt>. The default value uses the <tt>comparison(a, b) == true</tt>. The default value uses the
less-than relation. */ less-than relation. */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the quick sort algorithm */ /**< [IN] embb::mtapi::ExecutionPolicy for the quick sort algorithm */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are sorted in parallel. Partitioning of a block stops if its size are sorted in parallel. Partitioning of a block stops if its size
...@@ -88,6 +88,18 @@ void QuickSort( ...@@ -88,6 +88,18 @@ void QuickSort(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy.
*/
template <typename RAI, typename ComparisonFunction>
void QuickSort(
RAI first,
RAI last,
ComparisonFunction comparison,
const embb::mtapi::ExecutionPolicy& policy,
size_t block_size
);
/**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
*/ */
template <typename RAI> template <typename RAI>
...@@ -97,7 +109,7 @@ void QuickSort( ...@@ -97,7 +109,7 @@ void QuickSort(
) { ) {
QuickSort(first, last, QuickSort(first, last,
std::less<typename std::iterator_traits<RAI>::value_type>(), std::less<typename std::iterator_traits<RAI>::value_type>(),
ExecutionPolicy(), 0); embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -109,7 +121,7 @@ void QuickSort( ...@@ -109,7 +121,7 @@ void QuickSort(
RAI last, RAI last,
ComparisonFunction comparison ComparisonFunction comparison
) { ) {
QuickSort(first, last, comparison, ExecutionPolicy(), 0); QuickSort(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -120,23 +132,11 @@ void QuickSort( ...@@ -120,23 +132,11 @@ void QuickSort(
RAI first, RAI first,
RAI last, RAI last,
ComparisonFunction comparison, ComparisonFunction comparison,
const ExecutionPolicy& policy const embb::mtapi::ExecutionPolicy& policy
) { ) {
QuickSort(first, last, comparison, policy, 0); QuickSort(first, last, comparison, policy, 0);
} }
/**
* Overload of above described Doxygen dummy.
*/
template <typename RAI, typename ComparisonFunction>
void QuickSort(
RAI first,
RAI last,
ComparisonFunction comparison,
const ExecutionPolicy& policy,
size_t block_size
);
#endif // else DOXYGEN #endif // else DOXYGEN
/** /**
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef EMBB_ALGORITHMS_REDUCE_H_ #ifndef EMBB_ALGORITHMS_REDUCE_H_
#define EMBB_ALGORITHMS_REDUCE_H_ #define EMBB_ALGORITHMS_REDUCE_H_
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <embb/algorithms/identity.h> #include <embb/algorithms/identity.h>
namespace embb { namespace embb {
...@@ -64,14 +64,14 @@ namespace algorithms { ...@@ -64,14 +64,14 @@ namespace algorithms {
* associative, i.e., <tt>reduction(x, reduction(y, z)) == * associative, i.e., <tt>reduction(x, reduction(y, z)) ==
* reduction(reduction(x, y), z))</tt> for all \c x, \c y, \c z of type * reduction(reduction(x, y), z))</tt> for all \c x, \c y, \c z of type
* \c ReturnType. * \c ReturnType.
* \see ExecutionPolicy, ZipIterator, Identity * \see embb::mtapi::ExecutionPolicy, ZipIterator, Identity
* \tparam RAI Random access iterator * \tparam RAI Random access iterator
* \tparam ReturnType Type of result of reduction operation, deduced from * \tparam ReturnType Type of result of reduction operation, deduced from
* \c neutral * \c neutral
* \tparam ReductionFunction Binary reduction function with signature * \tparam ReductionFunction Binary reduction function object with signature
* <tt>ReturnType ReductionFunction(ReturnType, ReturnType)</tt>. * <tt>ReturnType ReductionFunction(ReturnType, ReturnType)</tt>.
* \tparam TransformationFunction Unary transformation function with signature * \tparam TransformationFunction Unary transformation function object with
* <tt>ReturnType TransformationFunction(typename * signature <tt>ReturnType TransformationFunction(typename
* std::iterator_traits<RAI>::value_type)</tt> * std::iterator_traits<RAI>::value_type)</tt>
*/ */
template<typename RAI, typename ReturnType, typename ReductionFunction, template<typename RAI, typename ReturnType, typename ReductionFunction,
...@@ -89,8 +89,8 @@ ReturnType Reduce( ...@@ -89,8 +89,8 @@ ReturnType Reduce(
TransformationFunction transformation = Identity(), TransformationFunction transformation = Identity(),
/**< [IN] Transforms the elements of the range before the reduction operation /**< [IN] Transforms the elements of the range before the reduction operation
is applied */ is applied */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the reduction computation */ /**< [IN] embb::mtapi::ExecutionPolicy for the reduction computation */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are treated in parallel. Partitioning of a block stops if its size are treated in parallel. Partitioning of a block stops if its size
...@@ -103,6 +103,21 @@ ReturnType Reduce( ...@@ -103,6 +103,21 @@ ReturnType Reduce(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename ReturnType, typename ReductionFunction,
typename TransformationFunction>
ReturnType Reduce(
RAI first,
RAI last,
ReturnType neutral,
ReductionFunction reduction,
TransformationFunction transformation,
const embb::mtapi::ExecutionPolicy& policy,
size_t block_size
);
/**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAI, typename ReturnType, typename ReductionFunction> template<typename RAI, typename ReturnType, typename ReductionFunction>
...@@ -112,8 +127,8 @@ ReturnType Reduce( ...@@ -112,8 +127,8 @@ ReturnType Reduce(
ReturnType neutral, ReturnType neutral,
ReductionFunction reduction ReductionFunction reduction
) { ) {
return Reduce(first, last, neutral, reduction, Identity(), ExecutionPolicy(), return Reduce(first, last, neutral, reduction, Identity(),
0); embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -129,7 +144,7 @@ ReturnType Reduce( ...@@ -129,7 +144,7 @@ ReturnType Reduce(
TransformationFunction transformation TransformationFunction transformation
) { ) {
return Reduce(first, last, neutral, reduction, transformation, return Reduce(first, last, neutral, reduction, transformation,
ExecutionPolicy(), 0); embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -143,26 +158,11 @@ ReturnType Reduce( ...@@ -143,26 +158,11 @@ ReturnType Reduce(
ReturnType neutral, ReturnType neutral,
ReductionFunction reduction, ReductionFunction reduction,
TransformationFunction transformation, TransformationFunction transformation,
const ExecutionPolicy& policy const embb::mtapi::ExecutionPolicy& policy
) { ) {
return Reduce(first, last, neutral, reduction, transformation, policy, 0); return Reduce(first, last, neutral, reduction, transformation, policy, 0);
} }
/**
* Overload of above described Doxygen dummy.
*/
template<typename RAI, typename ReturnType, typename ReductionFunction,
typename TransformationFunction>
ReturnType Reduce(
RAI first,
RAI last,
ReturnType neutral,
ReductionFunction reduction,
TransformationFunction transformation,
const ExecutionPolicy& policy,
size_t block_size
);
#endif // else DOXYGEN #endif // else DOXYGEN
/** /**
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef EMBB_ALGORITHMS_SCAN_H_ #ifndef EMBB_ALGORITHMS_SCAN_H_
#define EMBB_ALGORITHMS_SCAN_H_ #define EMBB_ALGORITHMS_SCAN_H_
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <embb/algorithms/identity.h> #include <embb/algorithms/identity.h>
namespace embb { namespace embb {
...@@ -66,15 +66,15 @@ namespace algorithms { ...@@ -66,15 +66,15 @@ namespace algorithms {
* associative, i.e., <tt>reduction(x, reduction(y, z)) == * associative, i.e., <tt>reduction(x, reduction(y, z)) ==
* reduction(reduction(x, y), z))</tt> for all \c x, \c y, \c z of type * reduction(reduction(x, y), z))</tt> for all \c x, \c y, \c z of type
* \c ReturnType. * \c ReturnType.
* \see ExecutionPolicy, Identity, ZipIterator * \see embb::mtapi::ExecutionPolicy, Identity, ZipIterator
* \tparam RAIIn Random access iterator type of input range * \tparam RAIIn Random access iterator type of input range
* \tparam RAIOut Random access iterator type of output range * \tparam RAIOut Random access iterator type of output range
* \tparam ReturnType Type of output elements of scan operation, deduced from * \tparam ReturnType Type of output elements of scan operation, deduced from
* \c neutral * \c neutral
* \tparam ScanFunction Binary scan function with signature * \tparam ScanFunction Binary scan function object with signature
* <tt>ReturnType ScanFunction(ReturnType, ReturnType)</tt> * <tt>ReturnType ScanFunction(ReturnType, ReturnType)</tt>
* \tparam TransformationFunction Unary transformation function with signature * \tparam TransformationFunction Unary transformation function object with
* <tt>ReturnType TransformationFunction(typename * signature <tt>ReturnType TransformationFunction(typename
* std::iterator_traits<RAIIn>::value_type)</tt>. * std::iterator_traits<RAIIn>::value_type)</tt>.
*/ */
template<typename RAIIn, typename RAIOut, typename ReturnType, template<typename RAIIn, typename RAIOut, typename ReturnType,
...@@ -96,8 +96,8 @@ void Scan( ...@@ -96,8 +96,8 @@ void Scan(
TransformationFunction transformation = Identity(), TransformationFunction transformation = Identity(),
/**< [IN] Transforms the elements of the input range before the scan operation /**< [IN] Transforms the elements of the input range before the scan operation
is applied */ is applied */
const ExecutionPolicy& policy = ExecutionPolicy(), const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(),
/**< [IN] ExecutionPolicy for the scan computation */ /**< [IN] embb::mtapi::ExecutionPolicy for the scan computation */
size_t block_size = 0 size_t block_size = 0
/**< [IN] Lower bound for partitioning the range of elements into blocks that /**< [IN] Lower bound for partitioning the range of elements into blocks that
are treated in parallel. Partitioning of a block stops if its size are treated in parallel. Partitioning of a block stops if its size
...@@ -110,36 +110,35 @@ void Scan( ...@@ -110,36 +110,35 @@ void Scan(
#else // DOXYGEN #else // DOXYGEN
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy.
*/ */
template<typename RAIIn, typename RAIOut, typename ReturnType, template<typename RAIIn, typename RAIOut, typename ReturnType,
typename ScanFunction> typename ScanFunction, typename TransformationFunction>
void Scan( void Scan(
RAIIn first, RAIIn first,
RAIIn last, RAIIn last,
RAIOut output_iterator, RAIOut output_iterator,
ReturnType neutral, ReturnType neutral,
ScanFunction scan ScanFunction scan,
) { TransformationFunction transformation,
Scan(first, last, output_iterator, neutral, scan, Identity(), const embb::mtapi::ExecutionPolicy& policy,
ExecutionPolicy(), 0); size_t block_size
} );
/** /**
* Overload of above described Doxygen dummy with less arguments. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAIIn, typename RAIOut, typename ReturnType, template<typename RAIIn, typename RAIOut, typename ReturnType,
typename ScanFunction, typename TransformationFunction> typename ScanFunction>
void Scan( void Scan(
RAIIn first, RAIIn first,
RAIIn last, RAIIn last,
RAIOut output_iterator, RAIOut output_iterator,
ReturnType neutral, ReturnType neutral,
ScanFunction scan, ScanFunction scan
TransformationFunction transformation
) { ) {
Scan(first, last, output_iterator, neutral, scan, transformation, Scan(first, last, output_iterator, neutral, scan, Identity(),
ExecutionPolicy(), 0); embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
...@@ -153,14 +152,14 @@ void Scan( ...@@ -153,14 +152,14 @@ void Scan(
RAIOut output_iterator, RAIOut output_iterator,
ReturnType neutral, ReturnType neutral,
ScanFunction scan, ScanFunction scan,
TransformationFunction transformation, TransformationFunction transformation
const ExecutionPolicy& policy
) { ) {
Scan(first, last, output_iterator, neutral, scan, transformation, policy, 0); Scan(first, last, output_iterator, neutral, scan, transformation,
embb::mtapi::ExecutionPolicy(), 0);
} }
/** /**
* Overload of above described Doxygen dummy. * Overload of above described Doxygen dummy with less arguments.
*/ */
template<typename RAIIn, typename RAIOut, typename ReturnType, template<typename RAIIn, typename RAIOut, typename ReturnType,
typename ScanFunction, typename TransformationFunction> typename ScanFunction, typename TransformationFunction>
...@@ -171,9 +170,10 @@ void Scan( ...@@ -171,9 +170,10 @@ void Scan(
ReturnType neutral, ReturnType neutral,
ScanFunction scan, ScanFunction scan,
TransformationFunction transformation, TransformationFunction transformation,
const ExecutionPolicy& policy, const embb::mtapi::ExecutionPolicy& policy
size_t block_size ) {
); Scan(first, last, output_iterator, neutral, scan, transformation, policy, 0);
}
#endif // else DOXYGEN #endif // else DOXYGEN
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <count_test.h> #include <count_test.h>
#include <embb/algorithms/count.h> #include <embb/algorithms/count.h>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <deque> #include <deque>
#include <vector> #include <vector>
#include <functional> #include <functional>
...@@ -59,8 +59,8 @@ CountTest::CountTest() { ...@@ -59,8 +59,8 @@ CountTest::CountTest() {
void CountTest::TestDataStructures() { void CountTest::TestDataStructures() {
using embb::algorithms::Count; using embb::algorithms::Count;
const int size =10; const int size = 10;
int array[] = {10, 20, 30, 30, 20, 10, 10, 20, 20, 20}; int array[] = { 10, 20, 30, 30, 20, 10, 10, 20, 20, 20 };
std::vector<int> vector(array, array + size); std::vector<int> vector(array, array + size);
std::deque<int> deque(array, array + size); std::deque<int> deque(array, array + size);
const std::vector<int> const_vector(array, array + size); const std::vector<int> const_vector(array, array + size);
...@@ -73,8 +73,8 @@ void CountTest::TestDataStructures() { ...@@ -73,8 +73,8 @@ void CountTest::TestDataStructures() {
void CountTest::TestCountIf() { void CountTest::TestCountIf() {
using embb::algorithms::CountIf; using embb::algorithms::CountIf;
const int size =10; const int size = 10;
int array[] = {10, 21, 30, 31, 20, 11, 10, 21, 20, 20}; int array[] = { 10, 21, 30, 31, 20, 11, 10, 21, 20, 20 };
PT_EXPECT_EQ(CountIf(array, array + size, IsEven()), 6); PT_EXPECT_EQ(CountIf(array, array + size, IsEven()), 6);
PT_EXPECT_EQ(CountIf(array, array + size, &IsEvenFunction), 6); PT_EXPECT_EQ(CountIf(array, array + size, &IsEvenFunction), 6);
} }
...@@ -122,14 +122,12 @@ void CountTest::TestBlockSizes() { ...@@ -122,14 +122,12 @@ void CountTest::TestBlockSizes() {
void CountTest::TestPolicy() { void CountTest::TestPolicy() {
using embb::algorithms::Count; using embb::algorithms::Count;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
int a[] = { 10, 20, 30, 30, 20, 10, 10, 20, 20, 20 }; int a[] = { 10, 20, 30, 30, 20, 10, 10, 20, 20, 20 };
std::vector<int> vector(a, a + (sizeof a / sizeof a[0])); std::vector<int> vector(a, a + (sizeof a / sizeof a[0]));
PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy()), 3); PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy()), 3);
PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy(true)), PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy(true)),
3); 3);
PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy(false)),
3);
PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10,
ExecutionPolicy(true, 1)), 3); ExecutionPolicy(true, 1)), 3);
} }
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <for_each_test.h> #include <for_each_test.h>
#include <embb/algorithms/for_each.h> #include <embb/algorithms/for_each.h>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <sstream> #include <sstream>
...@@ -166,7 +166,7 @@ void ForEachTest::TestRanges() { ...@@ -166,7 +166,7 @@ void ForEachTest::TestRanges() {
void ForEachTest::TestBlockSizes() { void ForEachTest::TestBlockSizes() {
using embb::algorithms::ForEach; using embb::algorithms::ForEach;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
std::vector<int> vector(count); std::vector<int> vector(count);
...@@ -186,7 +186,7 @@ void ForEachTest::TestBlockSizes() { ...@@ -186,7 +186,7 @@ void ForEachTest::TestBlockSizes() {
void ForEachTest::TestPolicy() { void ForEachTest::TestPolicy() {
using embb::algorithms::ForEach; using embb::algorithms::ForEach;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
std::vector<int> vector(count); std::vector<int> vector(count);
...@@ -207,12 +207,6 @@ void ForEachTest::TestPolicy() { ...@@ -207,12 +207,6 @@ void ForEachTest::TestPolicy() {
} }
vector = init; vector = init;
ForEach(vector.begin(), vector.end(), Square(), ExecutionPolicy(false));
for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector[i], init[i]*init[i]);
}
vector = init;
ForEach(vector.begin(), vector.end(), Square(), ExecutionPolicy(true, 1)); ForEach(vector.begin(), vector.end(), Square(), ExecutionPolicy(true, 1));
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector[i], init[i]*init[i]); PT_EXPECT_EQ(vector[i], init[i]*init[i]);
...@@ -221,7 +215,7 @@ void ForEachTest::TestPolicy() { ...@@ -221,7 +215,7 @@ void ForEachTest::TestPolicy() {
void ForEachTest::StressTest() { void ForEachTest::StressTest() {
using embb::algorithms::ForEach; using embb::algorithms::ForEach;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10; size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10;
std::vector<int> large_vector(count); std::vector<int> large_vector(count);
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -67,6 +67,7 @@ int compute1_() { ...@@ -67,6 +67,7 @@ int compute1_() {
PT_MAIN("Algorithms") { PT_MAIN("Algorithms") {
embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID);
PT_RUN(PartitionerTest); PT_RUN(PartitionerTest);
PT_RUN(ForEachTest); PT_RUN(ForEachTest);
PT_RUN(ReduceTest); PT_RUN(ReduceTest);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <merge_sort_test.h> #include <merge_sort_test.h>
#include <embb/algorithms/merge_sort.h> #include <embb/algorithms/merge_sort.h>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <sstream> #include <sstream>
...@@ -50,7 +50,7 @@ MergeSortTest::MergeSortTest() { ...@@ -50,7 +50,7 @@ MergeSortTest::MergeSortTest() {
void MergeSortTest::TestDataStructures() { void MergeSortTest::TestDataStructures() {
using embb::algorithms::MergeSortAllocate; using embb::algorithms::MergeSortAllocate;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
int array[kCountSize]; int array[kCountSize];
std::vector<int> vector(kCountSize); std::vector<int> vector(kCountSize);
std::deque<int> deque(kCountSize); std::deque<int> deque(kCountSize);
...@@ -75,7 +75,7 @@ void MergeSortTest::TestDataStructures() { ...@@ -75,7 +75,7 @@ void MergeSortTest::TestDataStructures() {
void MergeSortTest::TestFunctionPointers() { void MergeSortTest::TestFunctionPointers() {
using embb::algorithms::MergeSortAllocate; using embb::algorithms::MergeSortAllocate;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
std::vector<int> vector(kCountSize); std::vector<int> vector(kCountSize);
for (size_t i = kCountSize - 1; i > 0; i--) { for (size_t i = kCountSize - 1; i > 0; i--) {
...@@ -181,7 +181,7 @@ void MergeSortTest::TestRanges() { ...@@ -181,7 +181,7 @@ void MergeSortTest::TestRanges() {
void MergeSortTest::TestPolicy() { void MergeSortTest::TestPolicy() {
using embb::algorithms::MergeSortAllocate; using embb::algorithms::MergeSortAllocate;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
std::vector<int> vector(count); std::vector<int> vector(count);
...@@ -208,13 +208,6 @@ void MergeSortTest::TestPolicy() { ...@@ -208,13 +208,6 @@ void MergeSortTest::TestPolicy() {
vector = init; vector = init;
MergeSortAllocate(vector.begin(), vector.end(), std::less<int>(), MergeSortAllocate(vector.begin(), vector.end(), std::less<int>(),
ExecutionPolicy(false));
for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector_copy[i], vector[i]);
}
vector = init;
MergeSortAllocate(vector.begin(), vector.end(), std::less<int>(),
ExecutionPolicy(true, 1)); ExecutionPolicy(true, 1));
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector_copy[i], vector[i]); PT_EXPECT_EQ(vector_copy[i], vector[i]);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <quick_sort_test.h> #include <quick_sort_test.h>
#include <embb/algorithms/quick_sort.h> #include <embb/algorithms/quick_sort.h>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <sstream> #include <sstream>
...@@ -54,7 +54,7 @@ QuickSortTest::QuickSortTest() { ...@@ -54,7 +54,7 @@ QuickSortTest::QuickSortTest() {
void QuickSortTest::TestDataStructures() { void QuickSortTest::TestDataStructures() {
using embb::algorithms::QuickSort; using embb::algorithms::QuickSort;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
int array[kCountSize]; int array[kCountSize];
std::vector<int> vector(kCountSize); std::vector<int> vector(kCountSize);
...@@ -163,7 +163,7 @@ void QuickSortTest::TestRanges() { ...@@ -163,7 +163,7 @@ void QuickSortTest::TestRanges() {
void QuickSortTest::TestBlockSizes() { void QuickSortTest::TestBlockSizes() {
using embb::algorithms::QuickSort; using embb::algorithms::QuickSort;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
...@@ -187,7 +187,7 @@ void QuickSortTest::TestBlockSizes() { ...@@ -187,7 +187,7 @@ void QuickSortTest::TestBlockSizes() {
void QuickSortTest::TestPolicy() { void QuickSortTest::TestPolicy() {
using embb::algorithms::QuickSort; using embb::algorithms::QuickSort;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
std::vector<int> vector(count); std::vector<int> vector(count);
...@@ -214,13 +214,6 @@ void QuickSortTest::TestPolicy() { ...@@ -214,13 +214,6 @@ void QuickSortTest::TestPolicy() {
vector = init; vector = init;
QuickSort(vector.begin(), vector.end(), std::greater<int>(), QuickSort(vector.begin(), vector.end(), std::greater<int>(),
ExecutionPolicy(false));
for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector_copy[i], vector[i]);
}
vector = init;
QuickSort(vector.begin(), vector.end(), std::greater<int>(),
ExecutionPolicy(true, 1)); ExecutionPolicy(true, 1));
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
PT_EXPECT_EQ(vector_copy[i], vector[i]); PT_EXPECT_EQ(vector_copy[i], vector[i]);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <reduce_test.h> #include <reduce_test.h>
#include <embb/algorithms/reduce.h> #include <embb/algorithms/reduce.h>
#include <embb/algorithms/execution_policy.h> #include <embb/mtapi/execution_policy.h>
#include <deque> #include <deque>
#include <vector> #include <vector>
#include <functional> #include <functional>
...@@ -163,7 +163,7 @@ void ReduceTest::TestBlockSizes() { ...@@ -163,7 +163,7 @@ void ReduceTest::TestBlockSizes() {
void ReduceTest::TestPolicy() { void ReduceTest::TestPolicy() {
using embb::algorithms::Reduce; using embb::algorithms::Reduce;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
using embb::algorithms::Identity; using embb::algorithms::Identity;
size_t count = 4; size_t count = 4;
int sum = 0; int sum = 0;
...@@ -179,15 +179,13 @@ void ReduceTest::TestPolicy() { ...@@ -179,15 +179,13 @@ void ReduceTest::TestPolicy() {
Identity(), ExecutionPolicy()), sum); Identity(), ExecutionPolicy()), sum);
PT_EXPECT_EQ(Reduce(vector.begin(), vector.end(), 0, std::plus<int>(), PT_EXPECT_EQ(Reduce(vector.begin(), vector.end(), 0, std::plus<int>(),
Identity(), ExecutionPolicy(true)), sum); Identity(), ExecutionPolicy(true)), sum);
PT_EXPECT_EQ(Reduce(vector.begin(), vector.end(), 0,
std::plus<int>(), Identity(), ExecutionPolicy(false)), sum);
PT_EXPECT_EQ(Reduce(vector.begin(), vector.end(), 0, std::plus<int>(), PT_EXPECT_EQ(Reduce(vector.begin(), vector.end(), 0, std::plus<int>(),
Identity(), ExecutionPolicy(true, 1)), sum); Identity(), ExecutionPolicy(true, 1)), sum);
} }
void ReduceTest::StressTest() { void ReduceTest::StressTest() {
using embb::algorithms::Reduce; using embb::algorithms::Reduce;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
using embb::algorithms::Identity; using embb::algorithms::Identity;
size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10; size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10;
std::vector<int> large_vector(count); std::vector<int> large_vector(count);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -228,7 +228,7 @@ void ScanTest::TestRanges() { ...@@ -228,7 +228,7 @@ void ScanTest::TestRanges() {
void ScanTest::TestBlockSizes() { void ScanTest::TestBlockSizes() {
using embb::algorithms::Scan; using embb::algorithms::Scan;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
using embb::algorithms::Identity; using embb::algorithms::Identity;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
...@@ -253,7 +253,7 @@ void ScanTest::TestBlockSizes() { ...@@ -253,7 +253,7 @@ void ScanTest::TestBlockSizes() {
void ScanTest::TestPolicy() { void ScanTest::TestPolicy() {
using embb::algorithms::Scan; using embb::algorithms::Scan;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
using embb::algorithms::Identity; using embb::algorithms::Identity;
size_t count = 4; size_t count = 4;
std::vector<int> init(count); std::vector<int> init(count);
...@@ -284,15 +284,6 @@ void ScanTest::TestPolicy() { ...@@ -284,15 +284,6 @@ void ScanTest::TestPolicy() {
outputVector = init; outputVector = init;
Scan(vector.begin(), vector.end(), outputVector.begin(), 0, std::plus<int>(), Scan(vector.begin(), vector.end(), outputVector.begin(), 0, std::plus<int>(),
Identity(), ExecutionPolicy(false));
expected = 0;
for (size_t i = 0; i < count; i++) {
expected += vector[i];
PT_EXPECT_EQ(expected, outputVector[i]);
}
outputVector = init;
Scan(vector.begin(), vector.end(), outputVector.begin(), 0, std::plus<int>(),
Identity(), ExecutionPolicy(true, 1)); Identity(), ExecutionPolicy(true, 1));
expected = 0; expected = 0;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
...@@ -304,7 +295,7 @@ void ScanTest::TestPolicy() { ...@@ -304,7 +295,7 @@ void ScanTest::TestPolicy() {
void ScanTest::StressTest() { void ScanTest::StressTest() {
using embb::algorithms::Scan; using embb::algorithms::Scan;
using embb::algorithms::Identity; using embb::algorithms::Identity;
using embb::algorithms::ExecutionPolicy; using embb::mtapi::ExecutionPolicy;
size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10; size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10;
std::vector<int> large_vector(count); std::vector<int> large_vector(count);
std::vector<int> large_vector_output(count); std::vector<int> large_vector_output(count);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -136,7 +136,7 @@ void ZipIteratorTest::TestZipScan() { ...@@ -136,7 +136,7 @@ void ZipIteratorTest::TestZipScan() {
Scan(embb::algorithms::Zip(vectorA.begin(), vectorB.begin()), Scan(embb::algorithms::Zip(vectorA.begin(), vectorB.begin()),
embb::algorithms::Zip(vectorA.end(), vectorB.end()), embb::algorithms::Zip(vectorA.end(), vectorB.end()),
vectorOut.begin(), 0, std::plus<int>(), DotProductFunctor(), vectorOut.begin(), 0, std::plus<int>(), DotProductFunctor(),
embb::algorithms::ExecutionPolicy(), 0); embb::mtapi::ExecutionPolicy(), 0);
long sum = 0; long sum = 0;
for (size_t i = 0; i < kCountSize; i++) { for (size_t i = 0; i < kCountSize; i++) {
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
...@@ -77,14 +77,14 @@ endif() ...@@ -77,14 +77,14 @@ endif()
# Check headers and create configure file with preprocessor defines # Check headers and create configure file with preprocessor defines
include(CheckIncludeFiles) # Includes module to perform checks include(CheckIncludeFiles) # Includes module to perform checks
include(CheckSymbolExists) # Includes module to perform symbol checks include(CheckSymbolExists) # Includes module to perform symbol checks
check_include_files("sys/sysinfo.h" EMBB_HAS_HEADER_SYSINFO) check_include_files("sys/sysinfo.h" EMBB_PLATFORM_HAS_HEADER_SYSINFO)
check_include_files("sys/types.h;sys/sysctl.h" EMBB_HAS_HEADER_SYSCTL) check_include_files("sys/types.h;sys/sysctl.h" EMBB_PLATFORM_HAS_HEADER_SYSCTL)
check_include_files("sys/param.h;sys/cpuset.h" EMBB_HAS_HEADER_CPUSET) check_include_files("sys/param.h;sys/cpuset.h" EMBB_PLATFORM_HAS_HEADER_CPUSET)
link_libraries(${link_libraries} ${gnu_libs}) link_libraries(${link_libraries} ${gnu_libs})
set(CMAKE_EXTRA_INCLUDE_FILES sched.h) set(CMAKE_EXTRA_INCLUDE_FILES sched.h)
check_type_size(cpu_set_t EMBB_HAS_GLIB_CPU) check_type_size(cpu_set_t EMBB_PLATFORM_HAS_GLIB_CPU)
set(CMAKE_EXTRA_INCLUDE_FILES) set(CMAKE_EXTRA_INCLUDE_FILES)
if(DEFINED EMBB_HAS_GLIB_CPU) if(DEFINED EMBB_PLATFORM_HAS_GLIB_CPU)
add_definitions(-D_GNU_SOURCE) # Needed to activate CPU_ macros add_definitions(-D_GNU_SOURCE) # Needed to activate CPU_ macros
endif() endif()
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE void embb_atomic_and_assign_TYPE( EMBB_PLATFORM_INLINE void embb_atomic_and_assign_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for /**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for
the "and" operation and is used to store the result. */ the "and" operation and is used to store the result. */
...@@ -120,7 +120,7 @@ EMBB_INLINE void embb_atomic_and_assign_TYPE( ...@@ -120,7 +120,7 @@ EMBB_INLINE void embb_atomic_and_assign_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE int embb_atomic_compare_and_swap_TYPE( EMBB_PLATFORM_INLINE int embb_atomic_compare_and_swap_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable */ /**< [IN,OUT] Pointer to atomic variable */
TYPE* expected, TYPE* expected,
...@@ -140,7 +140,7 @@ EMBB_INLINE int embb_atomic_compare_and_swap_TYPE( ...@@ -140,7 +140,7 @@ EMBB_INLINE int embb_atomic_compare_and_swap_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE TYPE embb_atomic_fetch_and_add_TYPE( EMBB_PLATFORM_INLINE TYPE embb_atomic_fetch_and_add_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable*/ /**< [IN,OUT] Pointer to atomic variable*/
TYPE value TYPE value
...@@ -158,7 +158,7 @@ EMBB_INLINE TYPE embb_atomic_fetch_and_add_TYPE( ...@@ -158,7 +158,7 @@ EMBB_INLINE TYPE embb_atomic_fetch_and_add_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE TYPE embb_atomic_load_TYPE( EMBB_PLATFORM_INLINE TYPE embb_atomic_load_TYPE(
const embb_atomic_TYPE* variable const embb_atomic_TYPE* variable
/**< [IN] Pointer to atomic variable */ /**< [IN] Pointer to atomic variable */
); );
...@@ -169,7 +169,7 @@ EMBB_INLINE TYPE embb_atomic_load_TYPE( ...@@ -169,7 +169,7 @@ EMBB_INLINE TYPE embb_atomic_load_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE void embb_atomic_memory_barrier(); EMBB_PLATFORM_INLINE void embb_atomic_memory_barrier();
/** /**
* Computes the logical "or" of the value stored in \p variable and \c value. * Computes the logical "or" of the value stored in \p variable and \c value.
...@@ -182,7 +182,7 @@ EMBB_INLINE void embb_atomic_memory_barrier(); ...@@ -182,7 +182,7 @@ EMBB_INLINE void embb_atomic_memory_barrier();
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE void embb_atomic_or_assign_TYPE( EMBB_PLATFORM_INLINE void embb_atomic_or_assign_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for /**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for
the "or" operation and is used to store the result. */ the "or" operation and is used to store the result. */
...@@ -199,7 +199,7 @@ EMBB_INLINE void embb_atomic_or_assign_TYPE( ...@@ -199,7 +199,7 @@ EMBB_INLINE void embb_atomic_or_assign_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE void embb_atomic_store_TYPE( EMBB_PLATFORM_INLINE void embb_atomic_store_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable */ /**< [IN,OUT] Pointer to atomic variable */
int value int value
...@@ -217,7 +217,7 @@ EMBB_INLINE void embb_atomic_store_TYPE( ...@@ -217,7 +217,7 @@ EMBB_INLINE void embb_atomic_store_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE TYPE embb_atomic_swap_TYPE( EMBB_PLATFORM_INLINE TYPE embb_atomic_swap_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable whose value is swapped */ /**< [IN,OUT] Pointer to atomic variable whose value is swapped */
TYPE value TYPE value
...@@ -235,7 +235,7 @@ EMBB_INLINE TYPE embb_atomic_swap_TYPE( ...@@ -235,7 +235,7 @@ EMBB_INLINE TYPE embb_atomic_swap_TYPE(
* \ingroup C_BASE_ATOMIC * \ingroup C_BASE_ATOMIC
* \waitfree * \waitfree
*/ */
EMBB_INLINE void embb_atomic_xor_assign_TYPE( EMBB_PLATFORM_INLINE void embb_atomic_xor_assign_TYPE(
embb_atomic_TYPE* variable, embb_atomic_TYPE* variable,
/**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for /**< [IN,OUT] Pointer to atomic variable which serves as left-hand side for
the "xor" operation and is used to store the result. */ the "xor" operation and is used to store the result. */
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -53,21 +53,21 @@ ...@@ -53,21 +53,21 @@
* BYTE_SIZE is the number of bytes passed to the macro. * BYTE_SIZE is the number of bytes passed to the macro.
* *
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern void __fastcall EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ extern void __fastcall EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \
EMBB_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \ EMBB_PLATFORM_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \ EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\ #define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\
EMBB_INLINE void EMBB_CAT2(embb_internal__atomic_and_assign_, \ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_internal__atomic_and_assign_, \
EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
__asm__ __volatile__("lock and" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("lock and" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \ : "+m" (*pointer_to_value), "+q" (value) \
...@@ -89,12 +89,12 @@ EMBB_DEFINE_AND_ASSIGN(4, "l") ...@@ -89,12 +89,12 @@ EMBB_DEFINE_AND_ASSIGN(4, "l")
EMBB_DEFINE_AND_ASSIGN(8, "q") EMBB_DEFINE_AND_ASSIGN(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \ #define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \
EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
void EMBB_CAT2(embb_internal__atomic_and_assign_, \ void EMBB_CAT2(embb_internal__atomic_and_assign_, \
EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -148,7 +148,7 @@ EMBB_DEFINE_AND_ASSIGN(4, "") ...@@ -148,7 +148,7 @@ EMBB_DEFINE_AND_ASSIGN(4, "")
* This generated function is supposed to be called by the user of the lib. * This generated function is supposed to be called by the user of the lib.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_AND_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_AND_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE void EMBB_CAT2(embb_atomic_and_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_and_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -56,7 +56,7 @@ typedef uint64_t EMBB_BASE_BASIC_TYPE_SIZE_8; ...@@ -56,7 +56,7 @@ typedef uint64_t EMBB_BASE_BASIC_TYPE_SIZE_8;
#define EMBB_UINTMAX_T_TYPE_SIZE ${EMBB_UINTMAX_T_TYPE_SIZE} #define EMBB_UINTMAX_T_TYPE_SIZE ${EMBB_UINTMAX_T_TYPE_SIZE}
#ifdef EMBB_ARCH_X86_64 #ifdef EMBB_PLATFORM_ARCH_X86_64
# define EMBB_64_BIT_ATOMIC_AVAILABLE_VAL 1 # define EMBB_64_BIT_ATOMIC_AVAILABLE_VAL 1
# define EMBB_64_BIT_ATOMIC_AVAILABLE # define EMBB_64_BIT_ATOMIC_AVAILABLE
#else #else
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <stddef.h> #include <stddef.h>
#include <embb/base/c/internal/macro_helper.h> #include <embb/base/c/internal/macro_helper.h>
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#include <intrin.h> #include <intrin.h>
#endif #endif
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern int __fastcall EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ extern int __fastcall EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_PARAMETER_SIZE_BYTE)_asm( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired); \
EMBB_INLINE int __fastcall EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_PARAMETER_SIZE_BYTE)( \ EMBB_PLATFORM_INLINE int __fastcall EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_PARAMETER_SIZE_BYTE)( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \
int result; \ int result; \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
return result; \ return result; \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE int EMBB_CAT2(embb_internal__atomic_compare_and_swap_, \ EMBB_PLATFORM_INLINE int EMBB_CAT2(embb_internal__atomic_compare_and_swap_, \
EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, \ EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* expected, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \
char result; \ char result; \
...@@ -82,12 +82,12 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "l") ...@@ -82,12 +82,12 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "l")
EMBB_DEFINE_COMPARE_AND_SWAP(8, "q") EMBB_DEFINE_COMPARE_AND_SWAP(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, \ #define EMBB_DEFINE_COMPARE_AND_SWAP(EMBB_PARAMETER_SIZE_BYTE, \
EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
int EMBB_CAT2(embb_internal__atomic_compare_and_swap_, \ int EMBB_CAT2(embb_internal__atomic_compare_and_swap_, \
EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -134,7 +134,7 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "") ...@@ -134,7 +134,7 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_COMPARE_AND_SWAP_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_COMPARE_AND_SWAP_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE int EMBB_CAT2(embb_atomic_compare_and_swap_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE int EMBB_CAT2(embb_atomic_compare_and_swap_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE* expected, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE desired) {\ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE* expected, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE desired) {\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) desired_pun;\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) desired_pun;\
memcpy(&desired_pun, &desired, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\ memcpy(&desired_pun, &desired, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -38,13 +38,13 @@ ...@@ -38,13 +38,13 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE)_asm( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) (\ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) (\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
return result; \ return result; \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) \
(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) { \ (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) { \
__asm__ __volatile__ ("lock xadd" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__ ("lock xadd" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (new_value) \ : "+m" (*pointer_to_value), "+q" (new_value) \
...@@ -78,12 +78,12 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "l") ...@@ -78,12 +78,12 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "l")
EMBB_DEFINE_FETCH_AND_ADD(8, "q") EMBB_DEFINE_FETCH_AND_ADD(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, \ #define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, \
EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
EMBB_CAT2(embb_internal__atomic_fetch_and_add_, \ EMBB_CAT2(embb_internal__atomic_fetch_and_add_, \
EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PARAMETER_SIZE_BYTE)(\
...@@ -92,17 +92,17 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q") ...@@ -92,17 +92,17 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q")
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
new_value) { \ new_value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
tmp, result; \ tmp1, tmp2, result; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%3]\n\t" \
"add %1, %0, %3\n\t" \ "add %1, %0, %4\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %1, [%2]\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %1, [%3]\n\t" \
"teq %1, #0\n\t" \ "teq %2, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"isb" \ "isb" \
: "=&r" (result), "=&r" (tmp) \ : "=&r" (result), "=&r" (tmp1), "=&r" (tmp2) \
: "r" (pointer_to_value), "r" (new_value) \ : "r" (pointer_to_value), "r" (new_value) \
: "memory", "cc" ); \ : "memory", "cc" ); \
return result; \ return result; \
...@@ -127,7 +127,7 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") ...@@ -127,7 +127,7 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_FETCH_AND_ADD_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_FETCH_AND_ADD_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_fetch_and_add_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_fetch_and_add_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)_asm( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value); \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \
register EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ register EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
...@@ -54,9 +54,9 @@ ...@@ -54,9 +54,9 @@
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
return result; \ return result; \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \ EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \
/* no fence required for loads */ \ /* no fence required for loads */ \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \
...@@ -81,11 +81,11 @@ EMBB_DEFINE_LOAD(4, "l") ...@@ -81,11 +81,11 @@ EMBB_DEFINE_LOAD(4, "l")
EMBB_DEFINE_LOAD(8, "q") EMBB_DEFINE_LOAD(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ #define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -118,7 +118,7 @@ EMBB_DEFINE_LOAD(4, "") ...@@ -118,7 +118,7 @@ EMBB_DEFINE_LOAD(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_LOAD_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_LOAD_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_load_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_load_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
const EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \ const EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
return_val = (EMBB_CAT2(embb_internal__atomic_load_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)(\ return_val = (EMBB_CAT2(embb_internal__atomic_load_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)(\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -31,32 +31,32 @@ ...@@ -31,32 +31,32 @@
#ifndef DOXYGEN #ifndef DOXYGEN
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#include <intrin.h> #include <intrin.h>
#endif #endif
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
extern void __fastcall embb_internal__atomic_memory_barrier_asm(); extern void __fastcall embb_internal__atomic_memory_barrier_asm();
// Read/write barrier // Read/write barrier
EMBB_INLINE void __fastcall embb_atomic_memory_barrier() { EMBB_PLATFORM_INLINE void __fastcall embb_atomic_memory_barrier() {
_ReadWriteBarrier(); _ReadWriteBarrier();
embb_internal__atomic_memory_barrier_asm(); embb_internal__atomic_memory_barrier_asm();
_ReadWriteBarrier(); _ReadWriteBarrier();
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
// Read/write barrier // Read/write barrier
EMBB_INLINE void embb_atomic_memory_barrier() { EMBB_PLATFORM_INLINE void embb_atomic_memory_barrier() {
__asm__ __volatile__ ("mfence" : : : "memory"); __asm__ __volatile__ ("mfence" : : : "memory");
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
EMBB_INLINE void embb_atomic_memory_barrier() { EMBB_PLATFORM_INLINE void embb_atomic_memory_barrier() {
__asm__ __volatile__ ("dmb" : : : "memory"); __asm__ __volatile__ ("dmb" : : : "memory");
} }
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,22 +39,22 @@ ...@@ -39,22 +39,22 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern void __fastcall EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(\ extern void __fastcall EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \
EMBB_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \ EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE void EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
__asm__ __volatile__("lock or" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("lock or" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \ : "+m" (*pointer_to_value), "+q" (value) \
...@@ -77,12 +77,12 @@ EMBB_DEFINE_OR_ASSIGN(4, "l") ...@@ -77,12 +77,12 @@ EMBB_DEFINE_OR_ASSIGN(4, "l")
EMBB_DEFINE_OR_ASSIGN(8, "q") EMBB_DEFINE_OR_ASSIGN(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \ #define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \
EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
void EMBB_CAT2(embb_internal__atomic_or_assign_, \ void EMBB_CAT2(embb_internal__atomic_or_assign_, \
EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -120,7 +120,7 @@ EMBB_DEFINE_OR_ASSIGN(4, "") ...@@ -120,7 +120,7 @@ EMBB_DEFINE_OR_ASSIGN(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_OR_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_OR_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE void EMBB_CAT2(embb_atomic_or_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_or_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\
EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\ EMBB_CAT2(embb_internal__atomic_or_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\ #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\
extern void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ extern void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)_asm( \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \
EMBB_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) \
{ \ { \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, new_value); \ EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, new_value); \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\ #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\
EMBB_INLINE void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\
/*the lock prefix is implicit for xchg*/ \ /*the lock prefix is implicit for xchg*/ \
__asm__ __volatile__("xchg" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("xchg" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
...@@ -78,11 +78,11 @@ EMBB_DEFINE_STORE(4, "l") ...@@ -78,11 +78,11 @@ EMBB_DEFINE_STORE(4, "l")
EMBB_DEFINE_STORE(8, "q") EMBB_DEFINE_STORE(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX)\ #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX)\
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\ void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* \
pointer_to_value, \ pointer_to_value, \
...@@ -115,7 +115,7 @@ EMBB_DEFINE_STORE(4, "") ...@@ -115,7 +115,7 @@ EMBB_DEFINE_STORE(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_STORE_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_STORE_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE void EMBB_CAT2(embb_atomic_store_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_store_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
EMBB_CAT2(embb_internal__atomic_store_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\ EMBB_CAT2(embb_internal__atomic_store_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2 (embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)_asm(\ extern EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2 (embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)_asm(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2 (embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) __fastcall EMBB_CAT2 (embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
return result; \ return result; \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value)\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value)\
{ \ { \
/*the lock prefix is implicit for xchg*/ \ /*the lock prefix is implicit for xchg*/ \
...@@ -80,11 +80,11 @@ EMBB_DEFINE_SWAP(4, "l") ...@@ -80,11 +80,11 @@ EMBB_DEFINE_SWAP(4, "l")
EMBB_DEFINE_SWAP(8, "q") EMBB_DEFINE_SWAP(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ #define EMBB_DEFINE_SWAP(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2 \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2 \
(embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\ (embb_internal__atomic_swap_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -123,7 +123,7 @@ EMBB_DEFINE_SWAP(4, "") ...@@ -123,7 +123,7 @@ EMBB_DEFINE_SWAP(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_SWAP_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_SWAP_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_swap_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE EMBB_ATOMIC_PARAMETER_TYPE_NATIVE EMBB_CAT2(embb_atomic_swap_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun; \
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -39,22 +39,22 @@ ...@@ -39,22 +39,22 @@
* See file and_assign.h for a detailed (and operation independent) description * See file and_assign.h for a detailed (and operation independent) description
* of the following macro. * of the following macro.
*/ */
#ifdef EMBB_ARCH_X86 #ifdef EMBB_PLATFORM_ARCH_X86
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
extern void __fastcall EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(\ extern void __fastcall EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)_asm(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value); \
EMBB_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
EMBB_CAT2(embb_internal__atomic_xor_assign_, \ EMBB_CAT2(embb_internal__atomic_xor_assign_, \
EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \ EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, value); \
_ReadWriteBarrier(); \ _ReadWriteBarrier(); \
} }
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ #define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
EMBB_INLINE void EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \
__asm__ __volatile__("lock xor" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("lock xor" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
...@@ -78,12 +78,12 @@ EMBB_DEFINE_XOR_ASSIGN(4, "l") ...@@ -78,12 +78,12 @@ EMBB_DEFINE_XOR_ASSIGN(4, "l")
EMBB_DEFINE_XOR_ASSIGN(8, "q") EMBB_DEFINE_XOR_ASSIGN(8, "q")
#endif #endif
#elif defined(EMBB_ARCH_ARM) #elif defined(EMBB_PLATFORM_ARCH_ARM)
#if defined(EMBB_COMPILER_GNUC) #if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \ #define EMBB_DEFINE_XOR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, \
EMBB_ATOMIC_ARM_SIZE_SUFFIX) \ EMBB_ATOMIC_ARM_SIZE_SUFFIX) \
EMBB_INLINE \ EMBB_PLATFORM_INLINE \
void EMBB_CAT2(embb_internal__atomic_xor_assign_, \ void EMBB_CAT2(embb_internal__atomic_xor_assign_, \
EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
...@@ -121,7 +121,7 @@ EMBB_DEFINE_XOR_ASSIGN(4, "") ...@@ -121,7 +121,7 @@ EMBB_DEFINE_XOR_ASSIGN(4, "")
* of the following macro. * of the following macro.
*/ */
#define EMBB_ATOMIC_INTERNAL_DEFINE_XOR_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \ #define EMBB_ATOMIC_INTERNAL_DEFINE_XOR_ASSIGN_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_INLINE void EMBB_CAT2(embb_atomic_xor_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\ EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_xor_assign_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable, EMBB_ATOMIC_PARAMETER_TYPE_NATIVE value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) value_pun;\
memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\ memcpy(&value_pun, &value, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE));\
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <embb/base/c/internal/config.h> #include <embb/base/c/internal/config.h>
EMBB_INLINE void embb_bitset_set( EMBB_PLATFORM_INLINE void embb_bitset_set(
uint64_t * that, uint64_t * that,
unsigned int bit unsigned int bit
) { ) {
...@@ -42,7 +42,7 @@ EMBB_INLINE void embb_bitset_set( ...@@ -42,7 +42,7 @@ EMBB_INLINE void embb_bitset_set(
*that |= (1ull << bit); *that |= (1ull << bit);
} }
EMBB_INLINE void embb_bitset_set_n( EMBB_PLATFORM_INLINE void embb_bitset_set_n(
uint64_t * that, uint64_t * that,
unsigned int count) { unsigned int count) {
assert(NULL != that); assert(NULL != that);
...@@ -55,7 +55,7 @@ EMBB_INLINE void embb_bitset_set_n( ...@@ -55,7 +55,7 @@ EMBB_INLINE void embb_bitset_set_n(
} }
} }
EMBB_INLINE void embb_bitset_clear( EMBB_PLATFORM_INLINE void embb_bitset_clear(
uint64_t * that, uint64_t * that,
unsigned int bit unsigned int bit
) { ) {
...@@ -64,21 +64,21 @@ EMBB_INLINE void embb_bitset_clear( ...@@ -64,21 +64,21 @@ EMBB_INLINE void embb_bitset_clear(
*that &= ~(1ull << bit); *that &= ~(1ull << bit);
} }
EMBB_INLINE void embb_bitset_clear_all( EMBB_PLATFORM_INLINE void embb_bitset_clear_all(
uint64_t * that uint64_t * that
) { ) {
assert(NULL != that); assert(NULL != that);
*that = 0ull; *that = 0ull;
} }
EMBB_INLINE unsigned int embb_bitset_is_set( EMBB_PLATFORM_INLINE unsigned int embb_bitset_is_set(
uint64_t const * that, uint64_t const * that,
unsigned int bit unsigned int bit
) { ) {
return (unsigned int)((*that & (1ull << bit)) ? 1 : 0); return (unsigned int)((*that & (1ull << bit)) ? 1 : 0);
} }
EMBB_INLINE void embb_bitset_intersect( EMBB_PLATFORM_INLINE void embb_bitset_intersect(
uint64_t * that, uint64_t * that,
uint64_t mask uint64_t mask
) { ) {
...@@ -86,7 +86,7 @@ EMBB_INLINE void embb_bitset_intersect( ...@@ -86,7 +86,7 @@ EMBB_INLINE void embb_bitset_intersect(
*that &= mask; *that &= mask;
} }
EMBB_INLINE void embb_bitset_union( EMBB_PLATFORM_INLINE void embb_bitset_union(
uint64_t * that, uint64_t * that,
uint64_t mask uint64_t mask
) { ) {
...@@ -94,7 +94,7 @@ EMBB_INLINE void embb_bitset_union( ...@@ -94,7 +94,7 @@ EMBB_INLINE void embb_bitset_union(
*that |= mask; *that |= mask;
} }
EMBB_INLINE unsigned int embb_bitset_count( EMBB_PLATFORM_INLINE unsigned int embb_bitset_count(
uint64_t const * that uint64_t const * that
) { ) {
unsigned int count = 0; unsigned int count = 0;
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -36,21 +36,21 @@ ...@@ -36,21 +36,21 @@
/** /**
* Is used to get the number of cores on certain systems. * Is used to get the number of cores on certain systems.
*/ */
#cmakedefine EMBB_HAS_HEADER_SYSINFO #cmakedefine EMBB_PLATFORM_HAS_HEADER_SYSINFO
/** /**
* Is used to get the number of cores on certain systems. * Is used to get the number of cores on certain systems.
*/ */
#cmakedefine EMBB_HAS_HEADER_SYSCTL #cmakedefine EMBB_PLATFORM_HAS_HEADER_SYSCTL
/** /**
* Is used to set thread affinities on certain systems. * Is used to set thread affinities on certain systems.
*/ */
#cmakedefine EMBB_HAS_HEADER_CPUSET #cmakedefine EMBB_PLATFORM_HAS_HEADER_CPUSET
/** /**
* Is used for Linux thread affinities. * Is used for Linux thread affinities.
*/ */
#cmakedefine EMBB_HAS_GLIB_CPU #cmakedefine EMBB_PLATFORM_HAS_GLIB_CPU
#endif /* EMBB_BASE_INTERNAL_CMAKE_CONFIG_H_ */ #endif /* EMBB_BASE_INTERNAL_CMAKE_CONFIG_H_ */
\ No newline at end of file
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
* which has 128 bytes. * which has 128 bytes.
*/ */
#if defined(_M_IA64) || defined(_IA64) #if defined(_M_IA64) || defined(_IA64)
#define EMBB_CACHE_LINE_SIZE 128 #define EMBB_PLATFORM_CACHE_LINE_SIZE 128
#else #else
#define EMBB_CACHE_LINE_SIZE 64 #define EMBB_PLATFORM_CACHE_LINE_SIZE 64
#endif #endif
/* For MSVC, if _DEBUG is set, set also EMBB_DEBUG. /* For MSVC, if _DEBUG is set, set also EMBB_DEBUG.
...@@ -59,41 +59,41 @@ ...@@ -59,41 +59,41 @@
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
#define EMBB_ALIGN(size) __attribute__ ((aligned(size))) #define EMBB_PLATFORM_ALIGN(size) __attribute__ ((aligned(size)))
#elif defined _MSC_VER || defined __INTEL_COMPILER #elif defined _MSC_VER || defined __INTEL_COMPILER
#define EMBB_ALIGN(size) __declspec(align(size)) #define EMBB_PLATFORM_ALIGN(size) __declspec(align(size))
#else #else
#error "Unsupported compiler" #error "Unsupported compiler"
#endif #endif
#if __GNUC__ #if __GNUC__
#define EMBB_INLINE static inline #define EMBB_PLATFORM_INLINE static inline
#define EMBB_COMPILER_GNUC #define EMBB_PLATFORM_COMPILER_GNUC
#elif _MSC_VER #elif _MSC_VER
#define EMBB_INLINE __inline #define EMBB_PLATFORM_INLINE __inline
#define EMBB_COMPILER_MSVC #define EMBB_PLATFORM_COMPILER_MSVC
#else #else
#define EMBB_INLINE inline #define EMBB_PLATFORM_INLINE inline
#define EMBB_COMPILER_UNKNOWN #define EMBB_PLATFORM_COMPILER_UNKNOWN
#endif #endif
#if defined(__x86_64__) || defined(_M_X64) #if defined(__x86_64__) || defined(_M_X64)
#define EMBB_ARCH_X86_64 #define EMBB_PLATFORM_ARCH_X86_64
#define EMBB_ARCH_X86 #define EMBB_PLATFORM_ARCH_X86
#define EMBB_HAS_CAS_64 #define EMBB_PLATFORM_HAS_CAS_64
#elif defined(__i386) || defined(_M_IX86) #elif defined(__i386) || defined(_M_IX86)
#define EMBB_ARCH_X86_32 #define EMBB_PLATFORM_ARCH_X86_32
#define EMBB_ARCH_X86 #define EMBB_PLATFORM_ARCH_X86
#elif defined(__arm__) #elif defined(__arm__)
#define EMBB_ARCH_ARM #define EMBB_PLATFORM_ARCH_ARM
#else #else
#define EMBB_ARCH_UNKNOWN #define EMBB_PLATFORM_ARCH_UNKNOWN
#endif #endif
#if defined(EMBB_COMPILER_MSVC) #if defined(EMBB_PLATFORM_COMPILER_MSVC)
#define EMBB_THREADING_WINTHREADS #define EMBB_PLATFORM_THREADING_WINTHREADS
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_THREADING_POSIXTHREADS #define EMBB_PLATFORM_THREADING_POSIXTHREADS
#else #else
#error "No thread implementation could be determined" #error "No thread implementation could be determined"
#endif #endif
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -37,9 +37,9 @@ extern "C" { ...@@ -37,9 +37,9 @@ extern "C" {
#define EMBB_TIME_MAX_SECONDS ULLONG_MAX #define EMBB_TIME_MAX_SECONDS ULLONG_MAX
#define EMBB_DURATION_MAX_SECONDS 60 * 60 * 24 * 7 #define EMBB_DURATION_MAX_SECONDS 60 * 60 * 24 * 7
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
// Suppress virtual functions but non-virtual constructor warning // Suppress virtual functions but non-virtual constructor warning
// in windows headers // in windows headers
#pragma warning(push) #pragma warning(push)
...@@ -49,7 +49,7 @@ extern "C" { ...@@ -49,7 +49,7 @@ extern "C" {
#define NOMINMAX #define NOMINMAX
#include <windows.h> #include <windows.h>
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(pop) // Reset warning 4640 #pragma warning(pop) // Reset warning 4640
#endif #endif
...@@ -71,7 +71,7 @@ typedef CONDITION_VARIABLE embb_condition_t; ...@@ -71,7 +71,7 @@ typedef CONDITION_VARIABLE embb_condition_t;
#define EMBB_THREAD_SPECIFIC static __declspec(thread) #define EMBB_THREAD_SPECIFIC static __declspec(thread)
#elif defined EMBB_THREADING_POSIXTHREADS /* EMBB_THREADING_WINTHREADS */ #elif defined EMBB_PLATFORM_THREADING_POSIXTHREADS
#include <pthread.h> #include <pthread.h>
#include <errno.h> #include <errno.h>
...@@ -95,7 +95,7 @@ typedef pthread_cond_t embb_condition_t; ...@@ -95,7 +95,7 @@ typedef pthread_cond_t embb_condition_t;
#define EMBB_THREAD_SPECIFIC __thread #define EMBB_THREAD_SPECIFIC __thread
#else /* EMBB_THREADING_POSIXTHREADS */ #else /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
#error "No threading platform defined!" #error "No threading platform defined!"
...@@ -105,4 +105,4 @@ typedef pthread_cond_t embb_condition_t; ...@@ -105,4 +105,4 @@ typedef pthread_cond_t embb_condition_t;
} /* Close extern "C" { */ } /* Close extern "C" { */
#endif #endif
#endif /* EMBB_BASE_C_INTERNAL_PLATFORM_H_ */ #endif // EMBB_BASE_C_INTERNAL_PLATFORM_H_
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -43,7 +43,7 @@ int embb_condition_wait_for(embb_condition_t* condition_var, ...@@ -43,7 +43,7 @@ int embb_condition_wait_for(embb_condition_t* condition_var,
return embb_condition_wait_until(condition_var, mutex, &time); return embb_condition_wait_until(condition_var, mutex, &time);
} }
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
int embb_condition_init(embb_condition_t* condition_var) { int embb_condition_init(embb_condition_t* condition_var) {
assert(condition_var != NULL); assert(condition_var != NULL);
...@@ -108,9 +108,9 @@ int embb_condition_destroy(embb_condition_t* condition_var) { ...@@ -108,9 +108,9 @@ int embb_condition_destroy(embb_condition_t* condition_var) {
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
#endif /* EMBB_THREADING_WINTHREADS */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
#ifdef EMBB_THREADING_POSIXTHREADS #ifdef EMBB_PLATFORM_THREADING_POSIXTHREADS
int embb_condition_init(embb_condition_t* condition_var) { int embb_condition_init(embb_condition_t* condition_var) {
assert(condition_var != NULL); assert(condition_var != NULL);
...@@ -165,4 +165,4 @@ int embb_condition_destroy(embb_condition_t* condition_var) { ...@@ -165,4 +165,4 @@ int embb_condition_destroy(embb_condition_t* condition_var) {
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
#endif /* EMBB_THREADING_POSIXTHREADS */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <limits.h> #include <limits.h>
#include <assert.h> #include <assert.h>
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
/** /**
* For handling of more than 64 logical processors on Windows. * For handling of more than 64 logical processors on Windows.
...@@ -87,21 +87,21 @@ void embb_core_set_init(embb_core_set_t* core_set, int initializer) { ...@@ -87,21 +87,21 @@ void embb_core_set_init(embb_core_set_t* core_set, int initializer) {
} }
} }
#endif /* EMBB_THREADING_WINTHREADS */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
#ifdef EMBB_THREADING_POSIXTHREADS #ifdef EMBB_PLATFORM_THREADING_POSIXTHREADS
#ifdef EMBB_HAS_HEADER_SYSINFO #ifdef EMBB_PLATFORM_HAS_HEADER_SYSINFO
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#elif defined EMBB_HAS_HEADER_SYSCTL #elif defined EMBB_PLATFORM_HAS_HEADER_SYSCTL
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
unsigned int embb_core_count_available() { unsigned int embb_core_count_available() {
#ifdef EMBB_HAS_HEADER_SYSINFO #ifdef EMBB_PLATFORM_HAS_HEADER_SYSINFO
return get_nprocs(); return get_nprocs();
#elif defined EMBB_HAS_HEADER_SYSCTL #elif defined EMBB_PLATFORM_HAS_HEADER_SYSCTL
const size_t kBufferSize = sizeof(unsigned int); const size_t kBufferSize = sizeof(unsigned int);
char buf[kBufferSize]; char buf[kBufferSize];
size_t len = kBufferSize; size_t len = kBufferSize;
...@@ -123,7 +123,7 @@ void embb_core_set_init(embb_core_set_t* core_set, int initializer) { ...@@ -123,7 +123,7 @@ void embb_core_set_init(embb_core_set_t* core_set, int initializer) {
} }
} }
#endif /* EMBB_THREADING_POSIXTHREADS */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
void embb_core_set_add(embb_core_set_t* core_set, unsigned int core_number) { void embb_core_set_add(embb_core_set_t* core_set, unsigned int core_number) {
assert(core_set != NULL); assert(core_set != NULL);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -91,14 +91,14 @@ static void embb_log_write_internal( ...@@ -91,14 +91,14 @@ static void embb_log_write_internal(
log_level_str = " "; log_level_str = " ";
break; break;
} }
#if defined(EMBB_COMPILER_MSVC) #if defined(EMBB_PLATFORM_COMPILER_MSVC)
char msg_buffer[400]; char msg_buffer[400];
char buffer[500]; char buffer[500];
vsprintf_s(msg_buffer, sizeof(msg_buffer), message, argp); vsprintf_s(msg_buffer, sizeof(msg_buffer), message, argp);
sprintf_s(buffer, sizeof(buffer), "[%s] - [%s] %s", sprintf_s(buffer, sizeof(buffer), "[%s] - [%s] %s",
channel_str, log_level_str, msg_buffer); channel_str, log_level_str, msg_buffer);
embb_log_global_log_function(log_context, buffer); embb_log_global_log_function(log_context, buffer);
#elif defined(EMBB_COMPILER_GNUC) #elif defined(EMBB_PLATFORM_COMPILER_GNUC)
char msg_buffer[400]; char msg_buffer[400];
char buffer[500]; char buffer[500];
vsnprintf(msg_buffer, sizeof(msg_buffer), message, argp); vsnprintf(msg_buffer, sizeof(msg_buffer), message, argp);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -166,7 +166,7 @@ void embb_free(void * ptr) { ...@@ -166,7 +166,7 @@ void embb_free(void * ptr) {
void *embb_alloc_aligned(size_t alignment, size_t size) { void *embb_alloc_aligned(size_t alignment, size_t size) {
void* malloc_addr = NULL; void* malloc_addr = NULL;
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
/* /*
* From the Documentation: * From the Documentation:
* Allocates memory on a specified alignment boundary. * Allocates memory on a specified alignment boundary.
...@@ -176,7 +176,7 @@ void *embb_alloc_aligned(size_t alignment, size_t size) { ...@@ -176,7 +176,7 @@ void *embb_alloc_aligned(size_t alignment, size_t size) {
* failed. The pointer is a multiple of alignment. * failed. The pointer is a multiple of alignment.
*/ */
malloc_addr = _aligned_malloc(size, alignment); malloc_addr = _aligned_malloc(size, alignment);
#elif defined EMBB_COMPILER_GNUC #elif defined EMBB_PLATFORM_COMPILER_GNUC
/* /*
* From the Documentation: * From the Documentation:
* The posix_memalign() function shall allocate size bytes aligned on a * The posix_memalign() function shall allocate size bytes aligned on a
...@@ -193,10 +193,10 @@ void *embb_alloc_aligned(size_t alignment, size_t size) { ...@@ -193,10 +193,10 @@ void *embb_alloc_aligned(size_t alignment, size_t size) {
} }
void embb_free_aligned(void* ptr) { void embb_free_aligned(void* ptr) {
#ifdef EMBB_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
_aligned_free(ptr); _aligned_free(ptr);
#else #else
#ifdef EMBB_COMPILER_GNUC #ifdef EMBB_PLATFORM_COMPILER_GNUC
free(ptr); free(ptr);
#else #else
#error Unsupported compiler #error Unsupported compiler
...@@ -211,5 +211,5 @@ size_t embb_get_bytes_allocated() { ...@@ -211,5 +211,5 @@ size_t embb_get_bytes_allocated() {
#endif #endif
void *embb_alloc_cache_aligned(size_t size) { void *embb_alloc_cache_aligned(size_t size) {
return embb_alloc_aligned(EMBB_CACHE_LINE_SIZE, size); return embb_alloc_aligned(EMBB_PLATFORM_CACHE_LINE_SIZE, size);
} }
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <embb/base/c/internal/unused.h> #include <embb/base/c/internal/unused.h>
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
int embb_mutex_init(embb_mutex_t* mutex, int type) { int embb_mutex_init(embb_mutex_t* mutex, int type) {
/* Critical sections in Windows are always recursive */ /* Critical sections in Windows are always recursive */
...@@ -59,9 +59,9 @@ void embb_mutex_destroy(embb_mutex_t* mutex) { ...@@ -59,9 +59,9 @@ void embb_mutex_destroy(embb_mutex_t* mutex) {
DeleteCriticalSection(mutex); DeleteCriticalSection(mutex);
} }
#endif /* EMBB_THREADING_WINTHREADS */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
#ifdef EMBB_THREADING_POSIXTHREADS #ifdef EMBB_PLATFORM_THREADING_POSIXTHREADS
int embb_mutex_init(embb_mutex_t* mutex, int type) { int embb_mutex_init(embb_mutex_t* mutex, int type) {
if (type == EMBB_MUTEX_PLAIN) { if (type == EMBB_MUTEX_PLAIN) {
...@@ -71,9 +71,13 @@ int embb_mutex_init(embb_mutex_t* mutex, int type) { ...@@ -71,9 +71,13 @@ int embb_mutex_init(embb_mutex_t* mutex, int type) {
pthread_mutexattr_t attributes; pthread_mutexattr_t attributes;
if (pthread_mutexattr_init(&attributes) != 0) return EMBB_ERROR; if (pthread_mutexattr_init(&attributes) != 0) return EMBB_ERROR;
if (pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE) != 0) { if (pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE) != 0) {
pthread_mutexattr_destroy(&attributes);
return EMBB_ERROR;
}
if (pthread_mutex_init(mutex, &attributes) != 0) {
pthread_mutexattr_destroy(&attributes);
return EMBB_ERROR; return EMBB_ERROR;
} }
if (pthread_mutex_init(mutex, &attributes) != 0) return EMBB_ERROR;
if (pthread_mutexattr_destroy(&attributes) != 0) return EMBB_ERROR; if (pthread_mutexattr_destroy(&attributes) != 0) return EMBB_ERROR;
} }
return EMBB_SUCCESS; return EMBB_SUCCESS;
...@@ -110,4 +114,4 @@ void embb_mutex_destroy(embb_mutex_t* mutex) { ...@@ -110,4 +114,4 @@ void embb_mutex_destroy(embb_mutex_t* mutex) {
pthread_mutex_destroy(mutex); pthread_mutex_destroy(mutex);
} }
#endif /* EMBB_THREADING_POSIXTHREADS */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -40,7 +40,7 @@ void embb_thread_set_max_count(unsigned int max) { ...@@ -40,7 +40,7 @@ void embb_thread_set_max_count(unsigned int max) {
embb_internal_thread_index_set_max(max); embb_internal_thread_index_set_max(max);
} }
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
/** /**
* Used to wrap client thread start function and argument when calling internal * Used to wrap client thread start function and argument when calling internal
...@@ -151,21 +151,21 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) { ...@@ -151,21 +151,21 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) {
return 0; return 0;
} }
#endif /* EMBB_THREADING_WINTHREADS */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
#ifdef EMBB_THREADING_POSIXTHREADS #ifdef EMBB_PLATFORM_THREADING_POSIXTHREADS
#ifdef EMBB_HAS_GLIB_CPU #ifdef EMBB_PLATFORM_HAS_GLIB_CPU
#include <sched.h> #include <sched.h>
#elif defined EMBB_HAS_HEADER_CPUSET #elif defined EMBB_PLATFORM_HAS_HEADER_CPUSET
#include <pthread_np.h> #include <pthread_np.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/cpuset.h> #include <sys/cpuset.h>
#endif #endif
#ifdef EMBB_HAS_HEADER_SYSINFO #ifdef EMBB_PLATFORM_HAS_HEADER_SYSINFO
#include <sys/sysinfo.h> /* Used to get number of processors */ #include <sys/sysinfo.h> /* Used to get number of processors */
#endif /* EMBB_HAS_HEADER_SYSINFO */ #endif /* EMBB_PLATFORM_HAS_HEADER_SYSINFO */
/** /**
* Used to wrap client thread start function and argument when calling internal * Used to wrap client thread start function and argument when calling internal
...@@ -207,10 +207,11 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, ...@@ -207,10 +207,11 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set,
int status = pthread_attr_init(&attr); int status = pthread_attr_init(&attr);
if (status != 0) return EMBB_ERROR; if (status != 0) return EMBB_ERROR;
if (core_set != NULL) { if (core_set != NULL) {
#if defined(EMBB_HAS_GLIB_CPU) || defined(EMBB_HAS_HEADER_CPUSET) #if defined(EMBB_PLATFORM_HAS_GLIB_CPU) || \
defined(EMBB_PLATFORM_HAS_HEADER_CPUSET)
assert(embb_core_count_available() < CPU_SETSIZE && assert(embb_core_count_available() < CPU_SETSIZE &&
"Core sets are only supported up to CPU_SETSIZE processors!"); "Core sets are only supported up to CPU_SETSIZE processors!");
#ifdef EMBB_HAS_GLIB_CPU #ifdef EMBB_PLATFORM_HAS_GLIB_CPU
cpu_set_t cpuset; cpu_set_t cpuset;
#else #else
cpuset_t cpuset; cpuset_t cpuset;
...@@ -243,7 +244,7 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, ...@@ -243,7 +244,7 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set,
(void*)(thread->embb_internal_arg)); /* arguments to thread start func. */ (void*)(thread->embb_internal_arg)); /* arguments to thread start func. */
if (status != 0) return EMBB_ERROR; if (status != 0) return EMBB_ERROR;
pthread_attr_destroy(&attr); status = pthread_attr_destroy(&attr);
if (status != 0) return EMBB_ERROR; if (status != 0) return EMBB_ERROR;
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
...@@ -265,4 +266,4 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) { ...@@ -265,4 +266,4 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) {
return pthread_equal(lhs->embb_internal_handle, rhs->embb_internal_handle); return pthread_equal(lhs->embb_internal_handle, rhs->embb_internal_handle);
} }
#endif /* EMBB_THREADING_POSIXTHREADS */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -57,6 +57,7 @@ int embb_tss_set(embb_tss_t* tss, void* value) { ...@@ -57,6 +57,7 @@ int embb_tss_set(embb_tss_t* tss, void* value) {
void* embb_tss_get(const embb_tss_t* tss) { void* embb_tss_get(const embb_tss_t* tss) {
assert(tss != NULL); assert(tss != NULL);
assert(tss->values != NULL);
unsigned int index = 0; unsigned int index = 0;
int status = embb_internal_thread_index(&index); int status = embb_internal_thread_index(&index);
if ((status != EMBB_SUCCESS) || (index >= tss->size)) { if ((status != EMBB_SUCCESS) || (index >= tss->size)) {
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -53,7 +53,7 @@ int embb_time_compare(const embb_time_t* lhs, const embb_time_t* rhs) { ...@@ -53,7 +53,7 @@ int embb_time_compare(const embb_time_t* lhs, const embb_time_t* rhs) {
} }
#ifdef EMBB_THREADING_WINTHREADS #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { int embb_time_in(embb_time_t* time, const embb_duration_t* duration) {
assert(time != NULL); assert(time != NULL);
...@@ -81,10 +81,10 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { ...@@ -81,10 +81,10 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) {
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
#endif /* EMBB_THREADING_WINTHREADS */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
#ifdef EMBB_THREADING_POSIXTHREADS #ifdef EMBB_PLATFORM_THREADING_POSIXTHREADS
int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { int embb_time_in(embb_time_t* time, const embb_duration_t* duration) {
assert(time != NULL); assert(time != NULL);
...@@ -102,5 +102,5 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { ...@@ -102,5 +102,5 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) {
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
#endif /* EMBB_THREADING_POSIXTHREADS */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -174,7 +174,7 @@ void AllocTest::TestMixedAllocs() { ...@@ -174,7 +174,7 @@ void AllocTest::TestMixedAllocs() {
PT_EXPECT_NE(cache_aligned, static_cast<void*>(NULL)); PT_EXPECT_NE(cache_aligned, static_cast<void*>(NULL));
allocated = embb_get_bytes_allocated(); allocated = embb_get_bytes_allocated();
#ifdef EMBB_DEBUG #ifdef EMBB_DEBUG
expected += (1 + 1) * EMBB_CACHE_LINE_SIZE + 3 * sizeof(size_t) - 1; expected += (1 + 1) * EMBB_PLATFORM_CACHE_LINE_SIZE + 3 * sizeof(size_t) - 1;
#endif // else EMBB_DEBUG #endif // else EMBB_DEBUG
PT_EXPECT_EQ(allocated, expected); PT_EXPECT_EQ(allocated, expected);
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -81,4 +81,4 @@ class AllocTest : public partest::TestCase { ...@@ -81,4 +81,4 @@ class AllocTest : public partest::TestCase {
} // namespace base } // namespace base
} // namespace embb } // namespace embb
#endif /* BASE_C_TEST_ALLOC_TEST_H_ */ #endif // BASE_C_TEST_ALLOC_TEST_H_
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -65,4 +65,4 @@ class ConditionVarTest : public partest::TestCase { ...@@ -65,4 +65,4 @@ class ConditionVarTest : public partest::TestCase {
} // namespace base } // namespace base
} // namespace embb } // namespace embb
#endif /* BASE_C_TEST_CONDITION_VAR_TEST_H_ */ #endif // BASE_C_TEST_CONDITION_VAR_TEST_H_
/* /*
* Copyright (c) 2014, Siemens AG. All rights reserved. * Copyright (c) 2014-2015, Siemens AG. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment