Commit 5c3d5fbb by Marcus Winter

added threading analysis mode for linux

parent 9653c63b
......@@ -83,6 +83,7 @@ option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" ON)
option(WARNINGS_ARE_ERRORS "Specify whether warnings should be treated as errors" OFF)
option(USE_AUTOMATIC_INITIALIZATION "Specify whether the MTAPI C++ interface, algorithms and dataflow should automatically intialize the MTAPI node if no explicit initialization is present" ON)
option(BUILD_OPENCL_PLUGIN "Specify whether the MTAPI OpenCL plugin should be built" OFF)
option(THREADING_ANALYSIS_MODE "Replaces lock-free synchronization constructs by mutex-based implementations to support threading analysis tools" OFF)
## LOCAL INSTALLATION OF SUBPROJECT BINARIES
#
......@@ -104,6 +105,14 @@ else()
endif()
message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)")
if (THREADING_ANALYSIS_MODE STREQUAL ON)
set(EMBB_THREADING_ANALYSIS_MODE 1)
message("-- Threading analysis mode enabled")
else()
message("-- Threading analysis mode disabled (default")
endif()
message(" (set with command line option -DTHREADING_ANALYSIS_MODE=ON/OFF)")
include(CMakeCommon/SetCompilerFlags.cmake)
SetGNUCompilerFlags(compiler_libs compiler_flags)
SetVisualStudioCompilerFlags(compiler_libs compiler_flags)
......
......@@ -46,6 +46,8 @@
#include <functional>
#include <embb/base/c/memory_allocation.h>
#include <embb/base/c/atomic.h>
#define THIS_DOMAIN_ID 1
#define THIS_NODE_ID 1
......@@ -66,6 +68,8 @@ int compute1_() {
}
PT_MAIN("Algorithms") {
embb_atomic_initialize();
embb::tasks::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID);
PT_RUN(PartitionerTest);
......@@ -82,6 +86,5 @@ PT_MAIN("Algorithms") {
PT_EXPECT(embb_get_bytes_allocated() == 0);
// std::cout << "please press return to continue..." << std::endl;
// std::cin.get();
embb_atomic_finalize();
}
......@@ -292,11 +292,32 @@ void embb_atomic_xor_assign_TYPE(
extern "C" {
#endif
#include <embb/base/c/internal/cmake_config.h>
#ifdef EMBB_THREADING_ANALYSIS_MODE
#include <embb/base/c/internal/platform.h>
int embb_mutex_lock(
embb_mutex_t* mutex
);
int embb_mutex_unlock(
embb_mutex_t* mutex
);
#define EMBB_ATOMIC_MUTEX_LOCK embb_mutex_lock(&embb_atomic_mutex)
#define EMBB_ATOMIC_MUTEX_UNLOCK embb_mutex_unlock(&embb_atomic_mutex)
#else
#define EMBB_ATOMIC_MUTEX_LOCK
#define EMBB_ATOMIC_MUTEX_UNLOCK
#endif
#include <embb/base/c/internal/platform.h>
#include <embb/base/c/internal/atomic/atomic_sizes.h>
#include <embb/base/c/internal/atomic/atomic_variables.h>
#include <embb/base/c/internal/macro_helper.h>
#include <embb/base/c/internal/atomic/init_destroy.h>
#include <embb/base/c/internal/atomic/load.h>
#include <embb/base/c/internal/atomic/and_assign.h>
#include <embb/base/c/internal/atomic/store.h>
......
......@@ -69,10 +69,12 @@
#define EMBB_DEFINE_AND_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\
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_ATOMIC_MUTEX_LOCK; \
__asm__ __volatile__("lock and" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \
: \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
}
#else
#error "No atomic fetch and store implementation found"
......@@ -133,7 +135,7 @@ EMBB_DEFINE_AND_ASSIGN(4, "")
/*
* Now, using the basic functions above, we generate the respective functions
* for all basic data types, like "unsigned short". For that purpose, the
* following generator macro is used. This macro is called by the macros in the
* following generator macro is used. This macro is calleuild-work-Desktop-Defaultd by the macros in the
* generator header, defining the implementation for the basic data types.
*
* For unsigned short and for and_assign.h, the following method would be
......
......@@ -29,6 +29,7 @@
#include <stddef.h>
#include <embb/base/c/internal/macro_helper.h>
#include <embb/base/c/internal/cmake_config.h>
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#include <intrin.h>
......@@ -57,4 +58,16 @@ EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(size_t, size_t)
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(ptrdiff_t, ptrdiff_t)
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(uintmax_t, uintmax_t)
#ifdef EMBB_THREADING_ANALYSIS_MODE
#include <embb/base/c/mutex.h>
extern embb_mutex_t embb_atomic_mutex;
void embb_atomic_initialize();
void embb_atomic_finalize();
#else
#define embb_atomic_initialize()
#define embb_atomic_finalize()
#endif
#endif //EMBB_BASE_C_INTERNAL_ATOMIC_ATOMIC_VARIABLES_H_
......@@ -58,6 +58,7 @@
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_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \
EMBB_ATOMIC_MUTEX_LOCK; \
char result; \
__asm__ __volatile__ ("lock cmpxchg" EMBB_ATOMIC_X86_SIZE_SUFFIX\
" %3, %0 \n\t" \
......@@ -65,6 +66,7 @@
: "+m" (*pointer_to_value), "+a" (*expected), "=q" (result) \
: "q" (desired) \
: "memory", "cc" ); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return result; \
}
#else
......
......@@ -57,10 +57,12 @@
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
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_ATOMIC_MUTEX_LOCK; \
__asm__ __volatile__ ("lock xadd" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (new_value) \
: \
: "memory", "cc" ); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return new_value; \
}
#else
......
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_
#define EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_
// TODO implementation of embb_atomic_init()
#endif // EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_
......@@ -58,12 +58,14 @@
#define EMBB_DEFINE_LOAD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
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_ATOMIC_MUTEX_LOCK; \
/* no fence required for loads */ \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \
__asm__ __volatile__("mov" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "=q" (result) \
: "m" (*pointer_to_value) \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return result; \
}
#else
......
......@@ -56,10 +56,12 @@
#define EMBB_DEFINE_OR_ASSIGN(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
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_ATOMIC_MUTEX_LOCK; \
__asm__ __volatile__("lock or" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \
: \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
}
#else
......
......@@ -57,11 +57,13 @@
#define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\
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_ATOMIC_MUTEX_LOCK; \
/*the lock prefix is implicit for xchg*/ \
__asm__ __volatile__("xchg" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (new_value) \
: \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
}
#else
#error "No atomic fetch and store implementation found"
......
......@@ -58,11 +58,13 @@
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_ATOMIC_MUTEX_LOCK; \
/*the lock prefix is implicit for xchg*/ \
__asm__ __volatile__("xchg" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (new_value) \
: \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return new_value; \
}
#else
......
......@@ -57,10 +57,12 @@
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) value) { \
EMBB_ATOMIC_MUTEX_LOCK; \
__asm__ __volatile__("lock xor" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \
: \
: "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
}
#else
......
......@@ -53,4 +53,9 @@
*/
#cmakedefine EMBB_PLATFORM_HAS_GLIB_CPU
/**
* Enables mutex-based implementation of all synchronization constructs.
*/
#cmakedefine EMBB_THREADING_ANALYSIS_MODE
#endif /* EMBB_BASE_INTERNAL_CMAKE_CONFIG_H_ */
......@@ -46,3 +46,17 @@ void __embb_atomic_internal_compile_time_checks() {
BUILD_BUG_ON(sizeof(ptrdiff_t) != EMBB_PTRDIFF_T_TYPE_SIZE);
BUILD_BUG_ON(sizeof(uintmax_t) != EMBB_UINTMAX_T_TYPE_SIZE);
}
#ifdef EMBB_THREADING_ANALYSIS_MODE
embb_mutex_t embb_atomic_mutex;
void embb_atomic_initialize() {
embb_mutex_init(&embb_atomic_mutex, EMBB_MUTEX_PLAIN);
}
void embb_atomic_finalize() {
embb_mutex_destroy(&embb_atomic_mutex);
}
#endif
......@@ -39,6 +39,7 @@
#include <embb/base/c/log.h>
#include <iostream>
#include <embb/base/c/atomic.h>
#include <embb/base/c/memory_allocation.h>
using embb::base::test::AllocTest;
......@@ -54,6 +55,8 @@ using embb::base::test::ThreadTest;
using embb::base::test::ThreadSpecificStorageTest;
PT_MAIN("Base C") {
embb_atomic_initialize();
embb_log_set_log_level(EMBB_LOG_LEVEL_WARNING);
unsigned int max_threads =
static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads());
......@@ -71,4 +74,6 @@ PT_MAIN("Base C") {
PT_RUN(ThreadTest);
PT_RUN(ThreadSpecificStorageTest);
PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
}
......@@ -36,6 +36,7 @@
#include <memory_allocation_test.h>
#include <log_test.h>
#include <embb/base/c/atomic.h>
#include <embb/base/c/memory_allocation.h>
using embb::base::test::CoreSetTest;
......@@ -50,6 +51,8 @@ using embb::base::test::ThreadTest;
using embb::base::test::LogTest;
PT_MAIN("Base C++") {
embb_atomic_initialize();
unsigned int max_threads =
static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads());
embb_thread_set_max_count(max_threads);
......@@ -66,4 +69,6 @@ PT_MAIN("Base C++") {
PT_RUN(LogTest);
PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
}
......@@ -31,6 +31,7 @@
#include <embb/containers/lock_free_stack.h>
#include <embb/containers/lock_free_mpmc_queue.h>
#include <embb/base/c/memory_allocation.h>
#include <embb/base/c/atomic.h>
#include <partest/partest.h>
#include <embb/base/thread.h>
......@@ -58,6 +59,8 @@ using embb::containers::test::ObjectPoolTest;
using embb::containers::test::HazardPointerTest2;
PT_MAIN("Data Structures C++") {
embb_atomic_initialize();
unsigned int max_threads = static_cast<unsigned int>(
2 * partest::TestSuite::GetDefaultNumThreads());
embb_thread_set_max_count(max_threads);
......@@ -74,4 +77,6 @@ PT_MAIN("Data Structures C++") {
PT_RUN(ObjectPoolTest< WaitFreeArrayValuePool<bool COMMA false> >);
PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
}
......@@ -31,7 +31,13 @@
#include <dataflow_cpp_test_simple.h>
#include <dataflow_cpp_test_tuple.h>
#include <embb/base/c/atomic.h>
PT_MAIN("Dataflow C++") {
embb_atomic_initialize();
PT_RUN(SimpleTest);
PT_RUN(TupleTest);
embb_atomic_finalize();
}
......@@ -40,8 +40,11 @@
#include <embb_mtapi_test_id_pool.h>
#include <embb/base/c/memory_allocation.h>
#include <embb/base/c/atomic.h>
PT_MAIN("MTAPI C") {
embb_atomic_initialize();
embb_log_set_log_level(EMBB_LOG_LEVEL_NONE);
embb_thread_set_max_count(1024);
......@@ -54,4 +57,6 @@ PT_MAIN("MTAPI C") {
PT_RUN(IdPoolTest);
PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
}
......@@ -27,6 +27,7 @@
#include <partest/partest.h>
#include <embb/base/c/thread.h>
#include <embb/base/c/atomic.h>
#include <mtapi_cpp_test_task.h>
#include <mtapi_cpp_test_group.h>
......@@ -34,9 +35,13 @@
PT_MAIN("MTAPI C++") {
embb_atomic_initialize();
embb_thread_set_max_count(1024);
PT_RUN(TaskTest);
PT_RUN(GroupTest);
PT_RUN(QueueTest);
embb_atomic_finalize();
}
......@@ -30,8 +30,14 @@
#include <embb_mtapi_network_test_socket.h>
#include <embb_mtapi_network_test_task.h>
#include <embb/base/c/atomic.h>
PT_MAIN("MTAPI NETWORK") {
embb_atomic_initialize();
PT_RUN(NetworkBufferTest);
PT_RUN(NetworkSocketTest);
PT_RUN(NetworkTaskTest);
embb_atomic_finalize();
}
......@@ -29,8 +29,13 @@
#include <embb_mtapi_opencl_test_linker.h>
#include <embb_mtapi_opencl_test_task.h>
#include <embb/base/c/atomic.h>
PT_MAIN("MTAPI OPENCL") {
embb_atomic_initialize();
PT_RUN(LinkerTest);
PT_RUN(TaskTest);
embb_atomic_finalize();
}
......@@ -32,9 +32,15 @@
#include <tasks_cpp_test_group.h>
#include <tasks_cpp_test_queue.h>
#include <embb/base/c/atomic.h>
PT_MAIN("TASKS") {
embb_atomic_initialize();
PT_RUN(TaskTest);
PT_RUN(GroupTest);
PT_RUN(QueueTest);
embb_atomic_finalize();
}
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