Commit 3926d7a1 by Marcus Winter

full implementation of threading analysis mode

parent 8aa76fe9
...@@ -68,8 +68,6 @@ int compute1_() { ...@@ -68,8 +68,6 @@ int compute1_() {
} }
PT_MAIN("Algorithms") { PT_MAIN("Algorithms") {
embb_atomic_initialize();
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);
...@@ -85,6 +83,4 @@ PT_MAIN("Algorithms") { ...@@ -85,6 +83,4 @@ PT_MAIN("Algorithms") {
embb::mtapi::Node::Finalize(); embb::mtapi::Node::Finalize();
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
} }
...@@ -295,6 +295,12 @@ extern "C" { ...@@ -295,6 +295,12 @@ extern "C" {
#include <embb/base/c/internal/cmake_config.h> #include <embb/base/c/internal/cmake_config.h>
#ifdef EMBB_THREADING_ANALYSIS_MODE #ifdef EMBB_THREADING_ANALYSIS_MODE
#include <embb/base/c/internal/platform.h> #include <embb/base/c/internal/platform.h>
#include <assert.h>
int embb_mutex_init(
embb_mutex_t* mutex,
int type
);
int embb_mutex_lock( int embb_mutex_lock(
embb_mutex_t* mutex embb_mutex_t* mutex
...@@ -304,13 +310,20 @@ int embb_mutex_unlock( ...@@ -304,13 +310,20 @@ int embb_mutex_unlock(
embb_mutex_t* mutex embb_mutex_t* mutex
); );
#define EMBB_ATOMIC_MUTEX_LOCK embb_mutex_lock(&embb_atomic_mutex) void embb_mutex_destroy(
#define EMBB_ATOMIC_MUTEX_UNLOCK embb_mutex_unlock(&embb_atomic_mutex) embb_mutex_t* mutex
);
#define EMBB_ATOMIC_MUTEX_INIT(mutex) embb_mutex_init(&(mutex), 0)
#define EMBB_ATOMIC_MUTEX_LOCK(mutex) embb_mutex_lock(&(mutex))
#define EMBB_ATOMIC_MUTEX_UNLOCK(mutex) embb_mutex_unlock(&(mutex))
#define EMBB_ATOMIC_MUTEX_DESTROY(mutex) embb_mutex_destroy(&(mutex))
#define EMBB_ATOMIC_INIT_CHECK(variable) assert(variable->marker == 0x12345678)
#else #else
#define EMBB_ATOMIC_MUTEX_LOCK #define EMBB_ATOMIC_MUTEX_LOCK(mutex)
#define EMBB_ATOMIC_MUTEX_UNLOCK #define EMBB_ATOMIC_MUTEX_UNLOCK(mutex)
#endif #endif
...@@ -318,6 +331,8 @@ int embb_mutex_unlock( ...@@ -318,6 +331,8 @@ int embb_mutex_unlock(
#include <embb/base/c/internal/atomic/atomic_sizes.h> #include <embb/base/c/internal/atomic/atomic_sizes.h>
#include <embb/base/c/internal/atomic/atomic_variables.h> #include <embb/base/c/internal/atomic/atomic_variables.h>
#include <embb/base/c/internal/macro_helper.h> #include <embb/base/c/internal/macro_helper.h>
#include <embb/base/c/internal/atomic/init.h>
#include <embb/base/c/internal/atomic/destroy.h>
#include <embb/base/c/internal/atomic/load.h> #include <embb/base/c/internal/atomic/load.h>
#include <embb/base/c/internal/atomic/and_assign.h> #include <embb/base/c/internal/atomic/and_assign.h>
#include <embb/base/c/internal/atomic/store.h> #include <embb/base/c/internal/atomic/store.h>
......
...@@ -69,12 +69,10 @@ ...@@ -69,12 +69,10 @@
#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_PLATFORM_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
__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) \
: \ : \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
...@@ -154,8 +152,11 @@ EMBB_DEFINE_AND_ASSIGN(4, "") ...@@ -154,8 +152,11 @@ EMBB_DEFINE_AND_ASSIGN(4, "")
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));\
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) \ EMBB_CAT2(embb_internal__atomic_and_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) \
(&(variable->internal_variable)), value_pun); \ (&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
} }
#undef EMBB_ATOMIC_METHOD_TO_GENERATE #undef EMBB_ATOMIC_METHOD_TO_GENERATE
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
typedef struct \ typedef struct \
{ \ { \
volatile EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ volatile EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \
embb_mutex_t internal_mutex; \
uint32_t marker; \
} EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX); } EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX);
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char) EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char)
...@@ -58,16 +60,4 @@ EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(size_t, size_t) ...@@ -58,16 +60,4 @@ EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(size_t, size_t)
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(ptrdiff_t, ptrdiff_t) EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(ptrdiff_t, ptrdiff_t)
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(uintmax_t, uintmax_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_ #endif //EMBB_BASE_C_INTERNAL_ATOMIC_ATOMIC_VARIABLES_H_
...@@ -58,7 +58,6 @@ ...@@ -58,7 +58,6 @@
EMBB_PLATFORM_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
char result; \ char result; \
__asm__ __volatile__ ("lock cmpxchg" EMBB_ATOMIC_X86_SIZE_SUFFIX\ __asm__ __volatile__ ("lock cmpxchg" EMBB_ATOMIC_X86_SIZE_SUFFIX\
" %3, %0 \n\t" \ " %3, %0 \n\t" \
...@@ -66,7 +65,6 @@ ...@@ -66,7 +65,6 @@
: "+m" (*pointer_to_value), "+a" (*expected), "=q" (result) \ : "+m" (*pointer_to_value), "+a" (*expected), "=q" (result) \
: "q" (desired) \ : "q" (desired) \
: "memory", "cc" ); \ : "memory", "cc" ); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return result; \ return result; \
} }
#else #else
...@@ -140,8 +138,12 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "") ...@@ -140,8 +138,12 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "")
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));\
return EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) \ EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
int result = EMBB_CAT2(embb_internal__atomic_compare_and_swap_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) \
(&(variable->internal_variable)), (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) expected, desired_pun); \ (&(variable->internal_variable)), (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *) expected, desired_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
return result;\
} }
#undef EMBB_ATOMIC_METHOD_TO_GENERATE #undef EMBB_ATOMIC_METHOD_TO_GENERATE
......
/*
* Copyright (c) 2014-2016, Siemens AG. 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_DESTROY_H_
#define EMBB_BASE_C_INTERNAL_ATOMIC_DESTROY_H_
#ifndef DOXYGEN
#include <embb/base/c/internal/config.h>
#include <embb/base/c/internal/atomic/atomic_sizes.h>
#include <embb/base/c/internal/macro_helper.h>
#include <embb/base/c/internal/atomic/atomic_variables.h>
#include <string.h>
/*
* See file and_assign.h for a detailed (and operation independent) description
* of the following macro.
*/
#define EMBB_ATOMIC_INTERNAL_DEFINE_DESTROY_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_destroy_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_DESTROY(variable->internal_mutex); \
}
#undef EMBB_ATOMIC_METHOD_TO_GENERATE
#define EMBB_ATOMIC_METHOD_TO_GENERATE DESTROY_METHOD
#include <embb/base/c/internal/atomic/generate_atomic_implementation_template.h>
#undef EMBB_ATOMIC_METHOD_TO_GENERATE
#endif //DOXYGEN
#endif //EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_
...@@ -57,12 +57,10 @@ ...@@ -57,12 +57,10 @@
#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_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_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
__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) \
: \ : \
: "memory", "cc" ); \ : "memory", "cc" ); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return new_value; \ return new_value; \
} }
#else #else
...@@ -109,9 +107,6 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q") ...@@ -109,9 +107,6 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q")
: "memory", "cc" ); \ : "memory", "cc" ); \
return result; \ return result; \
} }
/* return __sync_fetch_and_add( \
pointer_to_value, new_value); \
}*/
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
#endif #endif
...@@ -133,9 +128,12 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") ...@@ -133,9 +128,12 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "")
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)); \
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) return_val = EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)(\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) return_val = EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)(\
(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\ (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\
(&(variable->internal_variable)), value_pun); \ (&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \ EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \
memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
return return_val_pun; \ return return_val_pun; \
......
/*
* Copyright (c) 2014-2016, Siemens AG. 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_
#ifndef DOXYGEN
#include <embb/base/c/internal/config.h>
#include <embb/base/c/internal/atomic/atomic_sizes.h>
#include <embb/base/c/internal/macro_helper.h>
#include <embb/base/c/internal/atomic/atomic_variables.h>
#include <string.h>
/*
* See file and_assign.h for a detailed (and operation independent) description
* of the following macro.
*/
#define EMBB_ATOMIC_INTERNAL_DEFINE_INIT_METHOD(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) \
EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_atomic_init_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)(\
EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \
EMBB_ATOMIC_MUTEX_INIT(variable->internal_mutex); \
variable->marker = 0x12345678; \
}
#undef EMBB_ATOMIC_METHOD_TO_GENERATE
#define EMBB_ATOMIC_METHOD_TO_GENERATE INIT_METHOD
#include <embb/base/c/internal/atomic/generate_atomic_implementation_template.h>
#undef EMBB_ATOMIC_METHOD_TO_GENERATE
#endif //DOXYGEN
#endif //EMBB_BASE_C_INTERNAL_ATOMIC_INIT_H_
...@@ -58,14 +58,12 @@ ...@@ -58,14 +58,12 @@
#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_PLATFORM_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
/* 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; \
__asm__ __volatile__("mov" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("mov" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "=q" (result) \ : "=q" (result) \
: "m" (*pointer_to_value) \ : "m" (*pointer_to_value) \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return result; \ return result; \
} }
#else #else
...@@ -121,10 +119,13 @@ EMBB_DEFINE_LOAD(4, "") ...@@ -121,10 +119,13 @@ EMBB_DEFINE_LOAD(4, "")
*/ */
#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_PLATFORM_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) { \ EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX)* variable) { \
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
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)(\
(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)(&(variable->internal_variable)))); \ (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)(&(variable->internal_variable)))); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \ EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \
memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
return return_val_pun; \ return return_val_pun; \
......
...@@ -56,12 +56,10 @@ ...@@ -56,12 +56,10 @@
#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_PLATFORM_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
__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) \
: \ : \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
} }
#else #else
...@@ -125,8 +123,11 @@ EMBB_DEFINE_OR_ASSIGN(4, "") ...@@ -125,8 +123,11 @@ EMBB_DEFINE_OR_ASSIGN(4, "")
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_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_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
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 *)\
(&(variable->internal_variable)), value_pun); \ (&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
} }
#undef EMBB_ATOMIC_METHOD_TO_GENERATE #undef EMBB_ATOMIC_METHOD_TO_GENERATE
......
...@@ -57,13 +57,11 @@ ...@@ -57,13 +57,11 @@
#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_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_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) {\
EMBB_ATOMIC_MUTEX_LOCK; \
/*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" \
: "+m" (*pointer_to_value), "+q" (new_value) \ : "+m" (*pointer_to_value), "+q" (new_value) \
: \ : \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
...@@ -120,8 +118,11 @@ EMBB_DEFINE_STORE(4, "") ...@@ -120,8 +118,11 @@ EMBB_DEFINE_STORE(4, "")
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_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_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
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 *)\
(&(variable->internal_variable)), value_pun); \ (&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
} }
#undef EMBB_ATOMIC_METHOD_TO_GENERATE #undef EMBB_ATOMIC_METHOD_TO_GENERATE
......
...@@ -58,13 +58,11 @@ ...@@ -58,13 +58,11 @@
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_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)\
{ \ { \
EMBB_ATOMIC_MUTEX_LOCK; \
/*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" \
: "+m" (*pointer_to_value), "+q" (new_value) \ : "+m" (*pointer_to_value), "+q" (new_value) \
: \ : \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
return new_value; \ return new_value; \
} }
#else #else
...@@ -129,8 +127,11 @@ EMBB_DEFINE_SWAP(4, "") ...@@ -129,8 +127,11 @@ EMBB_DEFINE_SWAP(4, "")
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)); \
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
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_swap_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)(&(variable->internal_variable)), value_pun); \ return_val = EMBB_CAT2(embb_internal__atomic_swap_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)(&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \ EMBB_ATOMIC_PARAMETER_TYPE_NATIVE return_val_pun; \
memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \ memcpy(&return_val_pun, &return_val, sizeof(EMBB_ATOMIC_PARAMETER_TYPE_NATIVE)); \
return return_val_pun; \ return return_val_pun; \
......
...@@ -57,12 +57,10 @@ ...@@ -57,12 +57,10 @@
EMBB_PLATFORM_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) { \
EMBB_ATOMIC_MUTEX_LOCK; \
__asm__ __volatile__("lock xor" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ __asm__ __volatile__("lock xor" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \
: "+m" (*pointer_to_value), "+q" (value) \ : "+m" (*pointer_to_value), "+q" (value) \
: \ : \
: "memory"); \ : "memory"); \
EMBB_ATOMIC_MUTEX_UNLOCK; \
} }
#else #else
...@@ -127,8 +125,11 @@ EMBB_DEFINE_XOR_ASSIGN(4, "") ...@@ -127,8 +125,11 @@ EMBB_DEFINE_XOR_ASSIGN(4, "")
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));\
EMBB_ATOMIC_INIT_CHECK(variable); \
EMBB_ATOMIC_MUTEX_LOCK(variable->internal_mutex); \
EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\ EMBB_CAT2(embb_internal__atomic_xor_assign_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE)((EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_ATOMIC_PARAMETER_TYPE_SIZE) volatile *)\
(&(variable->internal_variable)), value_pun); \ (&(variable->internal_variable)), value_pun); \
EMBB_ATOMIC_MUTEX_UNLOCK(variable->internal_mutex); \
} }
#undef EMBB_ATOMIC_METHOD_TO_GENERATE #undef EMBB_ATOMIC_METHOD_TO_GENERATE
......
...@@ -46,17 +46,3 @@ void __embb_atomic_internal_compile_time_checks() { ...@@ -46,17 +46,3 @@ void __embb_atomic_internal_compile_time_checks() {
BUILD_BUG_ON(sizeof(ptrdiff_t) != EMBB_PTRDIFF_T_TYPE_SIZE); BUILD_BUG_ON(sizeof(ptrdiff_t) != EMBB_PTRDIFF_T_TYPE_SIZE);
BUILD_BUG_ON(sizeof(uintmax_t) != EMBB_UINTMAX_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
...@@ -33,6 +33,7 @@ int embb_counter_init(embb_counter_t* counter) { ...@@ -33,6 +33,7 @@ int embb_counter_init(embb_counter_t* counter) {
if (counter == NULL) { if (counter == NULL) {
return EMBB_ERROR; return EMBB_ERROR;
} }
embb_atomic_init_unsigned_int(&(counter->value));
embb_atomic_store_unsigned_int(&(counter->value), 0); embb_atomic_store_unsigned_int(&(counter->value), 0);
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
...@@ -55,7 +56,7 @@ unsigned int embb_counter_decrement(embb_counter_t* counter) { ...@@ -55,7 +56,7 @@ unsigned int embb_counter_decrement(embb_counter_t* counter) {
void embb_counter_destroy(embb_counter_t* counter) { void embb_counter_destroy(embb_counter_t* counter) {
assert(counter != NULL); assert(counter != NULL);
EMBB_UNUSED_IN_RELEASE(counter); embb_atomic_destroy_unsigned_int(&(counter->value));
} }
...@@ -40,18 +40,18 @@ ...@@ -40,18 +40,18 @@
* This function has local scope. * This function has local scope.
*/ */
static int embb_max_number_thread_indices_max = 0; static int embb_max_number_thread_indices_max = 0;
static embb_atomic_int embb_max_number_thread_indices_flag = { 0 }; static EMBB_BASE_BASIC_TYPE_SIZE_4 embb_max_number_thread_indices_flag = 0;
unsigned int* embb_max_number_thread_indices() { unsigned int* embb_max_number_thread_indices() {
int compare_to = 0; EMBB_BASE_BASIC_TYPE_SIZE_4 compare_to = 0;
if (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) { if (embb_internal__atomic_load_4(&embb_max_number_thread_indices_flag) != 2) {
if (embb_atomic_compare_and_swap_int( if (embb_internal__atomic_compare_and_swap_4(
&embb_max_number_thread_indices_flag, &compare_to, 1)) { &embb_max_number_thread_indices_flag, &compare_to, 1)) {
embb_max_number_thread_indices_max = embb_max_number_thread_indices_max =
(int)(embb_core_count_available() * 2); (int)(embb_core_count_available() * 2);
embb_atomic_store_int(&embb_max_number_thread_indices_flag, 2); embb_internal__atomic_store_4(&embb_max_number_thread_indices_flag, 2);
} }
while (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) {} while (embb_internal__atomic_load_4(&embb_max_number_thread_indices_flag) != 2) {}
} }
return (unsigned int*) &embb_max_number_thread_indices_max; return (unsigned int*) &embb_max_number_thread_indices_max;
} }
...@@ -61,17 +61,17 @@ unsigned int* embb_max_number_thread_indices() { ...@@ -61,17 +61,17 @@ unsigned int* embb_max_number_thread_indices() {
* *
* This function has local scope. * This function has local scope.
*/ */
static embb_atomic_int embb_thread_index_counter_flag = { 0 }; static EMBB_BASE_BASIC_TYPE_SIZE_4 embb_thread_index_counter_flag = 0;
static embb_counter_t embb_thread_index_counter_index; static embb_counter_t embb_thread_index_counter_index;
embb_counter_t* embb_thread_index_counter() { embb_counter_t* embb_thread_index_counter() {
int compare_to = 0; EMBB_BASE_BASIC_TYPE_SIZE_4 compare_to = 0;
if (embb_atomic_load_int(&embb_thread_index_counter_flag) != 2) { if (embb_internal__atomic_load_4(&embb_thread_index_counter_flag) != 2) {
if (embb_atomic_compare_and_swap_int( if (embb_internal__atomic_compare_and_swap_4(
&embb_thread_index_counter_flag, &compare_to, 1)) { &embb_thread_index_counter_flag, &compare_to, 1)) {
embb_counter_init(&embb_thread_index_counter_index); embb_counter_init(&embb_thread_index_counter_index);
embb_atomic_store_int(&embb_thread_index_counter_flag, 2); embb_internal__atomic_store_4(&embb_thread_index_counter_flag, 2);
} }
while (embb_atomic_load_int(&embb_thread_index_counter_flag) != 2) {} while (embb_internal__atomic_load_4(&embb_thread_index_counter_flag) != 2) {}
} }
return &embb_thread_index_counter_index; return &embb_thread_index_counter_index;
} }
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#ifdef EMBB_DEBUG #ifdef EMBB_DEBUG
static embb_atomic_long embb_bytes_allocated = { 0 }; static EMBB_BASE_BASIC_TYPE_SIZE_4 embb_bytes_allocated = 0;
enum { enum {
// Make the marking unlikely to be something else // Make the marking unlikely to be something else
...@@ -49,7 +49,7 @@ void* embb_alloc(size_t bytes) { ...@@ -49,7 +49,7 @@ void* embb_alloc(size_t bytes) {
if (allocated == NULL) if (allocated == NULL)
return NULL; return NULL;
embb_atomic_fetch_and_add_long( embb_internal__atomic_fetch_and_add_4(
&embb_bytes_allocated, (long)bytes_to_allocate); &embb_bytes_allocated, (long)bytes_to_allocate);
size_t* x_as_size_type = (size_t*)allocated; size_t* x_as_size_type = (size_t*)allocated;
...@@ -72,7 +72,7 @@ void embb_free(void * ptr) { ...@@ -72,7 +72,7 @@ void embb_free(void * ptr) {
(*alloc_type) = (size_t)INVALID_ALLOCATION; (*alloc_type) = (size_t)INVALID_ALLOCATION;
embb_atomic_fetch_and_add_long( embb_internal__atomic_fetch_and_add_4(
&embb_bytes_allocated, (long)(0 - (size_t)(*bytes_allocated))); &embb_bytes_allocated, (long)(0 - (size_t)(*bytes_allocated)));
free((size_t*)ptr - 2); free((size_t*)ptr - 2);
...@@ -127,7 +127,7 @@ void* embb_alloc_aligned(size_t alignment, size_t size) { ...@@ -127,7 +127,7 @@ void* embb_alloc_aligned(size_t alignment, size_t size) {
x_as_size_type[-2] = (size_t)allocated; x_as_size_type[-2] = (size_t)allocated;
x_as_size_type[-3] = bytes_to_allocate; x_as_size_type[-3] = bytes_to_allocate;
embb_atomic_fetch_and_add_long( embb_internal__atomic_fetch_and_add_4(
&embb_bytes_allocated, (long)bytes_to_allocate); &embb_bytes_allocated, (long)bytes_to_allocate);
return x; return x;
...@@ -144,14 +144,14 @@ void embb_free_aligned(void* ptr) { ...@@ -144,14 +144,14 @@ void embb_free_aligned(void* ptr) {
ptr_conv[-1] = (size_t)INVALID_ALLOCATION; ptr_conv[-1] = (size_t)INVALID_ALLOCATION;
embb_atomic_fetch_and_add_long( embb_internal__atomic_fetch_and_add_4(
&embb_bytes_allocated, (long)((long)0 - ptr_conv[-3])); &embb_bytes_allocated, (long)((long)0 - ptr_conv[-3]));
free((void*)ptr_conv[-2]); free((void*)ptr_conv[-2]);
} }
size_t embb_get_bytes_allocated() { size_t embb_get_bytes_allocated() {
return (size_t)(embb_atomic_load_long(&embb_bytes_allocated)); return (size_t)(embb_internal__atomic_load_4(&embb_bytes_allocated));
} }
#else // EMBB_DEBUG #else // EMBB_DEBUG
......
...@@ -149,6 +149,7 @@ int embb_spin_init(embb_spinlock_t* spinlock) { ...@@ -149,6 +149,7 @@ int embb_spin_init(embb_spinlock_t* spinlock) {
} }
// For now, store the initial value. In the future will use atomic init // For now, store the initial value. In the future will use atomic init
// function (as soon as available). // function (as soon as available).
embb_atomic_init_int(&spinlock->atomic_spin_variable_);
embb_atomic_store_int(&spinlock->atomic_spin_variable_, 0); embb_atomic_store_int(&spinlock->atomic_spin_variable_, 0);
return EMBB_SUCCESS; return EMBB_SUCCESS;
} }
...@@ -207,7 +208,5 @@ int embb_spin_unlock(embb_spinlock_t* spinlock) { ...@@ -207,7 +208,5 @@ int embb_spin_unlock(embb_spinlock_t* spinlock) {
void embb_spin_destroy(embb_spinlock_t* spinlock) { void embb_spin_destroy(embb_spinlock_t* spinlock) {
assert(NULL != spinlock); assert(NULL != spinlock);
// for now, doing nothing here... in future, will call the respective embb_atomic_destroy_int(&spinlock->atomic_spin_variable_);
// destroy function for atomics...
EMBB_UNUSED(spinlock);
} }
...@@ -55,8 +55,6 @@ using embb::base::test::ThreadTest; ...@@ -55,8 +55,6 @@ using embb::base::test::ThreadTest;
using embb::base::test::ThreadSpecificStorageTest; using embb::base::test::ThreadSpecificStorageTest;
PT_MAIN("Base C") { PT_MAIN("Base C") {
embb_atomic_initialize();
embb_log_set_log_level(EMBB_LOG_LEVEL_WARNING); embb_log_set_log_level(EMBB_LOG_LEVEL_WARNING);
unsigned int max_threads = unsigned int max_threads =
static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads()); static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads());
...@@ -74,6 +72,4 @@ PT_MAIN("Base C") { ...@@ -74,6 +72,4 @@ PT_MAIN("Base C") {
PT_RUN(ThreadTest); PT_RUN(ThreadTest);
PT_RUN(ThreadSpecificStorageTest); PT_RUN(ThreadSpecificStorageTest);
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
} }
...@@ -36,13 +36,22 @@ namespace embb { ...@@ -36,13 +36,22 @@ namespace embb {
namespace base { namespace base {
namespace test { namespace test {
embb_atomic_int flag;
ThreadIndexTest::ThreadIndexTest() ThreadIndexTest::ThreadIndexTest()
: number_threads_(partest::TestSuite::GetDefaultNumThreads()) { : number_threads_(partest::TestSuite::GetDefaultNumThreads()) {
embb_atomic_init_int(&flag);
embb_atomic_store_int(&flag, 1);
CreateUnit("Test 0 indices").Add(&ThreadIndexTest::Test0, this); CreateUnit("Test 0 indices").Add(&ThreadIndexTest::Test0, this);
CreateUnit("Test 1 index").Add(&ThreadIndexTest::Test1, this); CreateUnit("Test 1 index").Add(&ThreadIndexTest::Test1, this);
CreateUnit("Test N indices").Add(&ThreadIndexTest::TestN, this, 1); CreateUnit("Test N indices").Add(&ThreadIndexTest::TestN, this, 1);
} }
ThreadIndexTest::~ThreadIndexTest() {
embb_atomic_destroy_int(&flag);
}
void ThreadIndexTest::Test0() { void ThreadIndexTest::Test0() {
embb_internal_thread_index_reset(); embb_internal_thread_index_reset();
unsigned int old_max = embb_thread_get_max_count(); unsigned int old_max = embb_thread_get_max_count();
...@@ -78,8 +87,6 @@ void ThreadIndexTest::Test1() { ...@@ -78,8 +87,6 @@ void ThreadIndexTest::Test1() {
embb_internal_thread_index_set_max(old_max); embb_internal_thread_index_set_max(old_max);
} }
embb_atomic_int flag = { 1 };
void ThreadIndexTest::TestN() { void ThreadIndexTest::TestN() {
embb_internal_thread_index_reset(); embb_internal_thread_index_reset();
unsigned int old_max = embb_thread_get_max_count(); unsigned int old_max = embb_thread_get_max_count();
...@@ -106,6 +113,8 @@ void ThreadIndexTest::TestN() { ...@@ -106,6 +113,8 @@ void ThreadIndexTest::TestN() {
embb_thread_join(&thread, NULL); embb_thread_join(&thread, NULL);
delete[] threads; delete[] threads;
embb_internal_thread_index_set_max(old_max); embb_internal_thread_index_set_max(old_max);
embb_atomic_destroy_int(&flag);
} }
int ThreadStart(void* arg) { int ThreadStart(void* arg) {
......
...@@ -36,10 +36,15 @@ namespace test { ...@@ -36,10 +36,15 @@ namespace test {
class ThreadIndexTest : public partest::TestCase { class ThreadIndexTest : public partest::TestCase {
public: public:
/** /**
* Adds test methods. * Adds test methods and allocates temporary data.
*/ */
ThreadIndexTest(); ThreadIndexTest();
/**
* Destroys temporary data.
*/
~ThreadIndexTest();
private: private:
/** /**
* Tests 0 available indices. * Tests 0 available indices.
......
...@@ -117,8 +117,10 @@ FetchAndAdd(DifferenceType val) { ...@@ -117,8 +117,10 @@ FetchAndAdd(DifferenceType val) {
NativeType native_desired; NativeType native_desired;
memcpy(&native_desired, &desired, sizeof(desired)); memcpy(&native_desired, &desired, sizeof(desired));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
NativeType storage_value = fetch_and_add_implementation<NativeType>:: NativeType storage_value = fetch_and_add_implementation<NativeType>::
fetch_and_add(&this->AtomicValue, native_desired); fetch_and_add(&this->AtomicValue, native_desired);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
memcpy(&return_value, &storage_value, sizeof(return_value)); memcpy(&return_value, &storage_value, sizeof(return_value));
return return_value; return return_value;
......
...@@ -58,6 +58,10 @@ class AtomicBase { ...@@ -58,6 +58,10 @@ class AtomicBase {
mutable NativeType AtomicValue; mutable NativeType AtomicValue;
#ifdef EMBB_THREADING_ANALYSIS_MODE
embb_mutex_t internal_mutex;
#endif
public: public:
/** /**
* Default constructor. * Default constructor.
...@@ -73,36 +77,48 @@ class AtomicBase { ...@@ -73,36 +77,48 @@ class AtomicBase {
*/ */
explicit AtomicBase(BaseType val); explicit AtomicBase(BaseType val);
/**
* Destructor.
*/
~AtomicBase();
// The members below are documented in atomic.h // The members below are documented in atomic.h
BaseType operator=(BaseType val); BaseType operator=(BaseType val);
operator BaseType() const; operator BaseType();
bool IsLockFree() const; bool IsLockFree() const;
bool IsArithmetic() const; bool IsArithmetic() const;
bool IsInteger() const; bool IsInteger() const;
bool IsPointer() const; bool IsPointer() const;
void Store(BaseType val); void Store(BaseType val);
BaseType Load() const; BaseType Load();
BaseType Swap(BaseType val); BaseType Swap(BaseType val);
bool CompareAndSwap(BaseType& expected, BaseType desired); bool CompareAndSwap(BaseType& expected, BaseType desired);
}; };
template<typename BaseType> template<typename BaseType>
inline AtomicBase<BaseType>::AtomicBase() : AtomicValue(0) { inline AtomicBase<BaseType>::AtomicBase() : AtomicValue(0) {
EMBB_ATOMIC_MUTEX_INIT(internal_mutex);
} }
template<typename BaseType> template<typename BaseType>
inline AtomicBase<BaseType>::AtomicBase(BaseType val) /*: AtomicValue(val)*/ { inline AtomicBase<BaseType>::AtomicBase(BaseType val) /*: AtomicValue(val)*/ {
EMBB_ATOMIC_MUTEX_INIT(internal_mutex);
memcpy(&AtomicValue, &val, sizeof(AtomicValue)); memcpy(&AtomicValue, &val, sizeof(AtomicValue));
} }
template<typename BaseType> template<typename BaseType>
inline AtomicBase<BaseType>::~AtomicBase() {
EMBB_ATOMIC_MUTEX_DESTROY(internal_mutex);
}
template<typename BaseType>
inline BaseType AtomicBase<BaseType>::operator=(BaseType val) { inline BaseType AtomicBase<BaseType>::operator=(BaseType val) {
Store(val); Store(val);
return val; return val;
} }
template<typename BaseType> template<typename BaseType>
inline AtomicBase<BaseType>::operator BaseType() const { inline AtomicBase<BaseType>::operator BaseType() {
return Load(); return Load();
} }
...@@ -132,16 +148,20 @@ inline void AtomicBase<BaseType>::Store(BaseType val) { ...@@ -132,16 +148,20 @@ inline void AtomicBase<BaseType>::Store(BaseType val) {
// anyway... // anyway...
memcpy(&storage_value, &val, sizeof(storage_value)); memcpy(&storage_value, &val, sizeof(storage_value));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
store_implementation< NativeType > store_implementation< NativeType >
::Store(&AtomicValue, storage_value); ::Store(&AtomicValue, storage_value);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
} }
template<typename BaseType> template<typename BaseType>
inline BaseType AtomicBase<BaseType>::Load() const { inline BaseType AtomicBase<BaseType>::Load() {
BaseType return_value; BaseType return_value;
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
NativeType storage_value = NativeType storage_value =
load_implementation< NativeType >::Load(&AtomicValue); load_implementation< NativeType >::Load(&AtomicValue);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
memcpy(&return_value, &storage_value, sizeof(return_value)); memcpy(&return_value, &storage_value, sizeof(return_value));
...@@ -155,8 +175,10 @@ inline BaseType AtomicBase<BaseType>::Swap(BaseType val) { ...@@ -155,8 +175,10 @@ inline BaseType AtomicBase<BaseType>::Swap(BaseType val) {
memcpy(&storage_value, &val, sizeof(storage_value)); memcpy(&storage_value, &val, sizeof(storage_value));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
NativeType storage_value2 = swap_implementation< NativeType > NativeType storage_value2 = swap_implementation< NativeType >
::Swap(&AtomicValue, storage_value); ::Swap(&AtomicValue, storage_value);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
memcpy(&return_value, &storage_value2, sizeof(return_value)); memcpy(&return_value, &storage_value2, sizeof(return_value));
...@@ -172,10 +194,12 @@ CompareAndSwap(BaseType& expected, BaseType desired) { ...@@ -172,10 +194,12 @@ CompareAndSwap(BaseType& expected, BaseType desired) {
memcpy(&native_expected, &expected, sizeof(expected)); memcpy(&native_expected, &expected, sizeof(expected));
memcpy(&native_desired, &desired, sizeof(desired)); memcpy(&native_desired, &desired, sizeof(desired));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
bool return_val = bool return_val =
(compare_and_swap_implementation<NativeType>:: (compare_and_swap_implementation<NativeType>::
compare_and_swap(&AtomicValue, &native_expected, native_desired)) !=0 compare_and_swap(&AtomicValue, &native_expected, native_desired)) !=0
? true : false; ? true : false;
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
memcpy(&expected, &native_expected, sizeof(expected)); memcpy(&expected, &native_expected, sizeof(expected));
......
...@@ -93,8 +93,10 @@ inline void AtomicInteger<BaseType>::operator&=(BaseType val) { ...@@ -93,8 +93,10 @@ inline void AtomicInteger<BaseType>::operator&=(BaseType val) {
NativeType native_operand; NativeType native_operand;
memcpy(&native_operand, &val, sizeof(val)); memcpy(&native_operand, &val, sizeof(val));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
and_assign_implementation<NativeType>:: and_assign_implementation<NativeType>::
and_assign(&this->AtomicValue, native_operand); and_assign(&this->AtomicValue, native_operand);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
} }
template<typename BaseType> template<typename BaseType>
...@@ -102,8 +104,10 @@ inline void AtomicInteger<BaseType>::operator|=(BaseType val) { ...@@ -102,8 +104,10 @@ inline void AtomicInteger<BaseType>::operator|=(BaseType val) {
NativeType native_operand; NativeType native_operand;
memcpy(&native_operand, &val, sizeof(val)); memcpy(&native_operand, &val, sizeof(val));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
or_assign_implementation<NativeType>:: or_assign_implementation<NativeType>::
or_assign(&this->AtomicValue, native_operand); or_assign(&this->AtomicValue, native_operand);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
} }
template<typename BaseType> template<typename BaseType>
...@@ -111,8 +115,10 @@ inline void AtomicInteger<BaseType>::operator^=(BaseType val) { ...@@ -111,8 +115,10 @@ inline void AtomicInteger<BaseType>::operator^=(BaseType val) {
NativeType native_operand; NativeType native_operand;
memcpy(&native_operand, &val, sizeof(val)); memcpy(&native_operand, &val, sizeof(val));
EMBB_ATOMIC_MUTEX_LOCK(internal_mutex);
xor_assign_implementation<NativeType>:: xor_assign_implementation<NativeType>::
xor_assign(&this->AtomicValue, native_operand); xor_assign(&this->AtomicValue, native_operand);
EMBB_ATOMIC_MUTEX_UNLOCK(internal_mutex);
} }
} // namespace atomic } // namespace atomic
......
...@@ -65,8 +65,8 @@ class AtomicPointer : public AtomicArithmetic<BaseType*, DifferenceType, S> { ...@@ -65,8 +65,8 @@ class AtomicPointer : public AtomicArithmetic<BaseType*, DifferenceType, S> {
bool IsPointer() const; bool IsPointer() const;
// The methods below are documented in atomic.h // The methods below are documented in atomic.h
BaseType* operator->() const; BaseType* operator->();
BaseType& operator*() const; BaseType& operator*();
}; };
template<typename BaseType, typename DifferenceType, size_t S> template<typename BaseType, typename DifferenceType, size_t S>
...@@ -93,13 +93,13 @@ inline bool AtomicPointer<BaseType, DifferenceType, S>:: ...@@ -93,13 +93,13 @@ inline bool AtomicPointer<BaseType, DifferenceType, S>::
template<typename BaseType, typename DifferenceType, size_t S> template<typename BaseType, typename DifferenceType, size_t S>
inline BaseType* AtomicPointer<BaseType, DifferenceType, S>:: inline BaseType* AtomicPointer<BaseType, DifferenceType, S>::
operator->() const { operator->() {
return this->Load(); return this->Load();
} }
template<typename BaseType, typename DifferenceType, size_t S> template<typename BaseType, typename DifferenceType, size_t S>
inline BaseType& AtomicPointer<BaseType, DifferenceType, S>:: inline BaseType& AtomicPointer<BaseType, DifferenceType, S>::
operator*() const { operator*() {
return *(this->Load()); return *(this->Load());
} }
......
...@@ -51,8 +51,6 @@ using embb::base::test::ThreadTest; ...@@ -51,8 +51,6 @@ using embb::base::test::ThreadTest;
using embb::base::test::LogTest; using embb::base::test::LogTest;
PT_MAIN("Base C++") { PT_MAIN("Base C++") {
embb_atomic_initialize();
unsigned int max_threads = unsigned int max_threads =
static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads()); static_cast<unsigned int>(2 * partest::TestSuite::GetDefaultNumThreads());
embb_thread_set_max_count(max_threads); embb_thread_set_max_count(max_threads);
...@@ -69,6 +67,4 @@ PT_MAIN("Base C++") { ...@@ -69,6 +67,4 @@ PT_MAIN("Base C++") {
PT_RUN(LogTest); PT_RUN(LogTest);
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
} }
...@@ -72,8 +72,6 @@ using embb::containers::test::ObjectPoolTest; ...@@ -72,8 +72,6 @@ using embb::containers::test::ObjectPoolTest;
using embb::containers::test::HazardPointerTest2; using embb::containers::test::HazardPointerTest2;
PT_MAIN("Data Structures C++") { PT_MAIN("Data Structures C++") {
embb_atomic_initialize();
unsigned int max_threads = static_cast<unsigned int>( unsigned int max_threads = static_cast<unsigned int>(
2 * partest::TestSuite::GetDefaultNumThreads()); 2 * partest::TestSuite::GetDefaultNumThreads());
embb_thread_set_max_count(max_threads); embb_thread_set_max_count(max_threads);
...@@ -90,6 +88,4 @@ PT_MAIN("Data Structures C++") { ...@@ -90,6 +88,4 @@ PT_MAIN("Data Structures C++") {
PT_RUN(ObjectPoolTest< WaitFreeArrayValuePool<bool COMMA false> >); PT_RUN(ObjectPoolTest< WaitFreeArrayValuePool<bool COMMA false> >);
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
} }
...@@ -84,13 +84,16 @@ class Inputs<T1, embb::base::internal::Nil, embb::base::internal::Nil, ...@@ -84,13 +84,16 @@ class Inputs<T1, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 1; new(count_+ii) embb::base::Atomic<int>(1);
} }
} }
this->template Get<0>().SetSlices(slices_); this->template Get<0>().SetSlices(slices_);
} }
~Inputs() { ~Inputs() {
if (NULL != count_) { if (NULL != count_) {
for (int ii = 0; ii < slices_; ii++) {
count_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(count_); embb::base::Allocation::Free(count_);
} }
} }
...@@ -150,7 +153,7 @@ class Inputs<T1, T2, embb::base::internal::Nil, ...@@ -150,7 +153,7 @@ class Inputs<T1, T2, embb::base::internal::Nil,
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 2; new(count_ + ii) embb::base::Atomic<int>(2);
} }
} }
this->template Get<0>().SetSlices(slices_); this->template Get<0>().SetSlices(slices_);
...@@ -158,6 +161,9 @@ class Inputs<T1, T2, embb::base::internal::Nil, ...@@ -158,6 +161,9 @@ class Inputs<T1, T2, embb::base::internal::Nil,
} }
~Inputs() { ~Inputs() {
if (NULL != count_) { if (NULL != count_) {
for (int ii = 0; ii < slices_; ii++) {
count_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(count_); embb::base::Allocation::Free(count_);
} }
} }
...@@ -222,7 +228,7 @@ class Inputs<T1, T2, T3, embb::base::internal::Nil, ...@@ -222,7 +228,7 @@ class Inputs<T1, T2, T3, embb::base::internal::Nil,
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 3; new(count_ + ii) embb::base::Atomic<int>(3);
} }
} }
this->template Get<0>().SetSlices(slices_); this->template Get<0>().SetSlices(slices_);
...@@ -231,6 +237,9 @@ class Inputs<T1, T2, T3, embb::base::internal::Nil, ...@@ -231,6 +237,9 @@ class Inputs<T1, T2, T3, embb::base::internal::Nil,
} }
~Inputs() { ~Inputs() {
if (NULL != count_) { if (NULL != count_) {
for (int ii = 0; ii < slices_; ii++) {
count_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(count_); embb::base::Allocation::Free(count_);
} }
} }
...@@ -299,7 +308,7 @@ class Inputs<T1, T2, T3, T4, embb::base::internal::Nil> ...@@ -299,7 +308,7 @@ class Inputs<T1, T2, T3, T4, embb::base::internal::Nil>
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 4; new(count_ + ii) embb::base::Atomic<int>(4);
} }
} }
this->template Get<0>().SetSlices(slices_); this->template Get<0>().SetSlices(slices_);
...@@ -309,6 +318,9 @@ class Inputs<T1, T2, T3, T4, embb::base::internal::Nil> ...@@ -309,6 +318,9 @@ class Inputs<T1, T2, T3, T4, embb::base::internal::Nil>
} }
~Inputs() { ~Inputs() {
if (NULL != count_) { if (NULL != count_) {
for (int ii = 0; ii < slices_; ii++) {
count_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(count_); embb::base::Allocation::Free(count_);
} }
} }
...@@ -383,7 +395,7 @@ class Inputs ...@@ -383,7 +395,7 @@ class Inputs
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 5; new(count_ + ii) embb::base::Atomic<int>(5);
} }
} }
this->template Get<0>().SetSlices(slices_); this->template Get<0>().SetSlices(slices_);
...@@ -394,6 +406,9 @@ class Inputs ...@@ -394,6 +406,9 @@ class Inputs
} }
~Inputs() { ~Inputs() {
if (NULL != count_) { if (NULL != count_) {
for (int ii = 0; ii < slices_; ii++) {
count_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(count_); embb::base::Allocation::Free(count_);
} }
} }
......
...@@ -802,6 +802,9 @@ class Network : public internal::ClockListener { ...@@ -802,6 +802,9 @@ class Network : public internal::ClockListener {
sched_ = NULL; sched_ = NULL;
} }
if (NULL != sink_counter_) { if (NULL != sink_counter_) {
for (int ii = 0; ii < slices_; ii++) {
sink_counter_[ii].~Atomic<int>();
}
embb::base::Allocation::Free(sink_counter_); embb::base::Allocation::Free(sink_counter_);
sink_counter_ = NULL; sink_counter_ = NULL;
} }
...@@ -1111,7 +1114,7 @@ class Network : public internal::ClockListener { ...@@ -1111,7 +1114,7 @@ class Network : public internal::ClockListener {
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_)); sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) { for (int ii = 0; ii < slices_; ii++) {
sink_counter_[ii] = 0; new(sink_counter_+ii) embb::base::Atomic<int>(0);
} }
} }
}; };
......
...@@ -34,10 +34,6 @@ ...@@ -34,10 +34,6 @@
#include <embb/base/c/atomic.h> #include <embb/base/c/atomic.h>
PT_MAIN("Dataflow C++") { PT_MAIN("Dataflow C++") {
embb_atomic_initialize();
PT_RUN(SimpleTest); PT_RUN(SimpleTest);
PT_RUN(TupleTest); PT_RUN(TupleTest);
embb_atomic_finalize();
} }
...@@ -62,6 +62,7 @@ mtapi_action_hndl_t mtapi_ext_plugin_action_create( ...@@ -62,6 +62,7 @@ mtapi_action_hndl_t mtapi_ext_plugin_action_create(
new_action->node_local_data_size = node_local_data_size; new_action->node_local_data_size = node_local_data_size;
new_action->enabled = MTAPI_TRUE; new_action->enabled = MTAPI_TRUE;
new_action->is_plugin_action = MTAPI_TRUE; new_action->is_plugin_action = MTAPI_TRUE;
embb_atomic_init_int(&new_action->num_tasks);
embb_atomic_store_int(&new_action->num_tasks, 0); embb_atomic_store_int(&new_action->num_tasks, 0);
new_action->plugin_task_start_function = task_start_function; new_action->plugin_task_start_function = task_start_function;
...@@ -87,6 +88,7 @@ mtapi_action_hndl_t mtapi_ext_plugin_action_create( ...@@ -87,6 +88,7 @@ mtapi_action_hndl_t mtapi_ext_plugin_action_create(
action_handle = new_action->handle; action_handle = new_action->handle;
embb_mtapi_job_add_action(job, new_action); embb_mtapi_job_add_action(job, new_action);
} else { } else {
embb_mtapi_action_finalize(new_action);
embb_mtapi_action_pool_deallocate(node->action_pool, new_action); embb_mtapi_action_pool_deallocate(node->action_pool, new_action);
} }
} else { } else {
......
...@@ -49,6 +49,8 @@ embb_mtapi_pool_implementation(action) ...@@ -49,6 +49,8 @@ embb_mtapi_pool_implementation(action)
/* ---- CLASS MEMBERS ------------------------------------------------------ */ /* ---- CLASS MEMBERS ------------------------------------------------------ */
void embb_mtapi_action_initialize(embb_mtapi_action_t* that) { void embb_mtapi_action_initialize(embb_mtapi_action_t* that) {
assert(MTAPI_NULL != that);
that->action_function = NULL; that->action_function = NULL;
that->job_id = MTAPI_JOB_ID_INVALID; that->job_id = MTAPI_JOB_ID_INVALID;
that->domain_id = MTAPI_DOMAIN_ID_INVALID; that->domain_id = MTAPI_DOMAIN_ID_INVALID;
...@@ -57,15 +59,26 @@ void embb_mtapi_action_initialize(embb_mtapi_action_t* that) { ...@@ -57,15 +59,26 @@ void embb_mtapi_action_initialize(embb_mtapi_action_t* that) {
that->node_local_data = NULL; that->node_local_data = NULL;
that->node_local_data_size = 0; that->node_local_data_size = 0;
that->plugin_data = MTAPI_NULL; that->plugin_data = MTAPI_NULL;
embb_atomic_init_int(&that->num_tasks);
embb_atomic_store_int(&that->num_tasks, 0); embb_atomic_store_int(&that->num_tasks, 0);
} }
void embb_mtapi_action_finalize(embb_mtapi_action_t* that) { void embb_mtapi_action_finalize(embb_mtapi_action_t* that) {
assert(MTAPI_NULL != that);
if (that->is_plugin_action) { if (that->is_plugin_action) {
// TODO(mw): check status // TODO(mw): check status
that->plugin_action_finalize_function(that->handle, NULL); that->plugin_action_finalize_function(that->handle, NULL);
} }
embb_mtapi_action_initialize(that); that->action_function = NULL;
that->job_id = MTAPI_JOB_ID_INVALID;
that->domain_id = MTAPI_DOMAIN_ID_INVALID;
that->node_id = MTAPI_NODE_ID_INVALID;
that->enabled = MTAPI_FALSE;
that->node_local_data = NULL;
that->node_local_data_size = 0;
that->plugin_data = MTAPI_NULL;
embb_atomic_destroy_int(&that->num_tasks);
} }
static mtapi_boolean_t embb_mtapi_action_delete_visitor( static mtapi_boolean_t embb_mtapi_action_delete_visitor(
...@@ -140,6 +153,7 @@ mtapi_action_hndl_t mtapi_action_create( ...@@ -140,6 +153,7 @@ mtapi_action_hndl_t mtapi_action_create(
new_action->node_local_data_size = node_local_data_size; new_action->node_local_data_size = node_local_data_size;
new_action->enabled = MTAPI_TRUE; new_action->enabled = MTAPI_TRUE;
new_action->is_plugin_action = MTAPI_FALSE; new_action->is_plugin_action = MTAPI_FALSE;
embb_atomic_init_int(&new_action->num_tasks);
embb_atomic_store_int(&new_action->num_tasks, 0); embb_atomic_store_int(&new_action->num_tasks, 0);
new_action->action_function = action_function; new_action->action_function = action_function;
...@@ -162,6 +176,7 @@ mtapi_action_hndl_t mtapi_action_create( ...@@ -162,6 +176,7 @@ mtapi_action_hndl_t mtapi_action_create(
action_handle = new_action->handle; action_handle = new_action->handle;
embb_mtapi_job_add_action(job, new_action); embb_mtapi_job_add_action(job, new_action);
} else { } else {
embb_mtapi_action_finalize(new_action);
embb_mtapi_action_pool_deallocate(node->action_pool, new_action); embb_mtapi_action_pool_deallocate(node->action_pool, new_action);
} }
} else { } else {
...@@ -337,8 +352,7 @@ void mtapi_action_delete( ...@@ -337,8 +352,7 @@ void mtapi_action_delete(
node, local_action->job_id); node, local_action->job_id);
embb_mtapi_job_remove_action(local_job, local_action); embb_mtapi_job_remove_action(local_job, local_action);
} }
/* this is done by pool deallocate: embb_mtapi_action_finalize(local_action);
embb_mtapi_action_finalize(local_action); */
embb_mtapi_action_pool_deallocate(node->action_pool, local_action); embb_mtapi_action_pool_deallocate(node->action_pool, local_action);
} else { } else {
local_status = MTAPI_ERR_ACTION_INVALID; local_status = MTAPI_ERR_ACTION_INVALID;
......
...@@ -30,12 +30,12 @@ ...@@ -30,12 +30,12 @@
#include <embb_mtapi_alloc.h> #include <embb_mtapi_alloc.h>
static embb_atomic_unsigned_int embb_mtapi_alloc_bytes_allocated = { 0 }; static EMBB_BASE_BASIC_TYPE_SIZE_4 embb_mtapi_alloc_bytes_allocated = 0;
void * embb_mtapi_alloc_allocate(unsigned int bytes) { void * embb_mtapi_alloc_allocate(unsigned int bytes) {
void * ptr = embb_alloc(bytes); void * ptr = embb_alloc(bytes);
if (ptr != NULL) { if (ptr != NULL) {
embb_atomic_fetch_and_add_unsigned_int( embb_internal__atomic_fetch_and_add_4(
&embb_mtapi_alloc_bytes_allocated, sizeof(unsigned int)+bytes); &embb_mtapi_alloc_bytes_allocated, sizeof(unsigned int)+bytes);
} }
return ptr; return ptr;
...@@ -48,9 +48,9 @@ void embb_mtapi_alloc_deallocate(void * ptr) { ...@@ -48,9 +48,9 @@ void embb_mtapi_alloc_deallocate(void * ptr) {
} }
void embb_mtapi_alloc_reset_bytes_allocated() { void embb_mtapi_alloc_reset_bytes_allocated() {
embb_atomic_store_unsigned_int(&embb_mtapi_alloc_bytes_allocated, 0); embb_internal__atomic_store_4(&embb_mtapi_alloc_bytes_allocated, 0);
} }
unsigned int embb_mtapi_alloc_get_bytes_allocated() { unsigned int embb_mtapi_alloc_get_bytes_allocated() {
return embb_atomic_load_unsigned_int(&embb_mtapi_alloc_bytes_allocated); return embb_internal__atomic_load_4(&embb_mtapi_alloc_bytes_allocated);
} }
...@@ -55,8 +55,10 @@ void embb_mtapi_group_initialize(embb_mtapi_group_t * that) { ...@@ -55,8 +55,10 @@ void embb_mtapi_group_initialize(embb_mtapi_group_t * that) {
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
that->group_id = MTAPI_GROUP_ID_NONE; that->group_id = MTAPI_GROUP_ID_NONE;
embb_atomic_init_int(&that->deleted);
embb_atomic_store_int(&that->deleted, MTAPI_FALSE); embb_atomic_store_int(&that->deleted, MTAPI_FALSE);
that->num_tasks.internal_variable = 0; embb_atomic_init_int(&that->num_tasks);
embb_atomic_store_int(&that->num_tasks, 0);
embb_mtapi_task_queue_initialize(&that->queue); embb_mtapi_task_queue_initialize(&that->queue);
} }
...@@ -67,8 +69,10 @@ void embb_mtapi_group_initialize_with_node( ...@@ -67,8 +69,10 @@ void embb_mtapi_group_initialize_with_node(
assert(MTAPI_NULL != node); assert(MTAPI_NULL != node);
that->group_id = MTAPI_GROUP_ID_NONE; that->group_id = MTAPI_GROUP_ID_NONE;
embb_atomic_init_int(&that->deleted);
embb_atomic_store_int(&that->deleted, MTAPI_FALSE); embb_atomic_store_int(&that->deleted, MTAPI_FALSE);
that->num_tasks.internal_variable = 0; embb_atomic_init_int(&that->num_tasks);
embb_atomic_store_int(&that->num_tasks, 0);
embb_mtapi_task_queue_initialize_with_capacity( embb_mtapi_task_queue_initialize_with_capacity(
&that->queue, node->attributes.queue_limit); &that->queue, node->attributes.queue_limit);
} }
...@@ -77,7 +81,9 @@ void embb_mtapi_group_finalize(embb_mtapi_group_t * that) { ...@@ -77,7 +81,9 @@ void embb_mtapi_group_finalize(embb_mtapi_group_t * that) {
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
embb_atomic_store_int(&that->deleted, MTAPI_TRUE); embb_atomic_store_int(&that->deleted, MTAPI_TRUE);
that->num_tasks.internal_variable = 0; embb_atomic_destroy_int(&that->deleted);
embb_atomic_store_int(&that->num_tasks, 0);
embb_atomic_destroy_int(&that->num_tasks);
embb_mtapi_task_queue_finalize(&that->queue); embb_mtapi_task_queue_finalize(&that->queue);
} }
......
...@@ -105,6 +105,7 @@ void mtapi_initialize( ...@@ -105,6 +105,7 @@ void mtapi_initialize(
} }
if (MTAPI_SUCCESS == local_status) { if (MTAPI_SUCCESS == local_status) {
embb_atomic_init_int(&node->is_scheduler_running);
embb_atomic_store_int(&node->is_scheduler_running, MTAPI_FALSE); embb_atomic_store_int(&node->is_scheduler_running, MTAPI_FALSE);
/* initialize storage */ /* initialize storage */
...@@ -199,6 +200,8 @@ void mtapi_finalize(MTAPI_OUT mtapi_status_t* status) { ...@@ -199,6 +200,8 @@ void mtapi_finalize(MTAPI_OUT mtapi_status_t* status) {
embb_mtapi_job_finalize_list(node); embb_mtapi_job_finalize_list(node);
} }
embb_atomic_destroy_int(&node->is_scheduler_running);
/* free system instance */ /* free system instance */
embb_mtapi_alloc_deallocate(node); embb_mtapi_alloc_deallocate(node);
embb_mtapi_node_instance = MTAPI_NULL; embb_mtapi_node_instance = MTAPI_NULL;
......
...@@ -66,8 +66,6 @@ mtapi_boolean_t embb_mtapi_##TYPE##_pool_initialize( \ ...@@ -66,8 +66,6 @@ mtapi_boolean_t embb_mtapi_##TYPE##_pool_initialize( \
that->storage[ii].handle.id = EMBB_MTAPI_IDPOOL_INVALID_ID; \ that->storage[ii].handle.id = EMBB_MTAPI_IDPOOL_INVALID_ID; \
that->storage[ii].handle.tag = 0; \ that->storage[ii].handle.tag = 0; \
} \ } \
/* use entry 0 as invalid */ \
embb_mtapi_##TYPE##_initialize(that->storage); \
return MTAPI_TRUE; \ return MTAPI_TRUE; \
} else { \ } else { \
that->id_pool.ids_available = 0; \ that->id_pool.ids_available = 0; \
...@@ -96,7 +94,6 @@ void embb_mtapi_##TYPE##_pool_deallocate( \ ...@@ -96,7 +94,6 @@ void embb_mtapi_##TYPE##_pool_deallocate( \
embb_mtapi_##TYPE##_pool_t * that, \ embb_mtapi_##TYPE##_pool_t * that, \
embb_mtapi_##TYPE##_t * object) { \ embb_mtapi_##TYPE##_t * object) { \
mtapi_uint_t pool_id = object->handle.id; \ mtapi_uint_t pool_id = object->handle.id; \
embb_mtapi_##TYPE##_finalize(object); \
object->handle.id = EMBB_MTAPI_IDPOOL_INVALID_ID; \ object->handle.id = EMBB_MTAPI_IDPOOL_INVALID_ID; \
object->handle.tag++; \ object->handle.tag++; \
embb_mtapi_id_pool_deallocate(&that->id_pool, pool_id); \ embb_mtapi_id_pool_deallocate(&that->id_pool, pool_id); \
......
...@@ -56,7 +56,9 @@ void embb_mtapi_queue_initialize(embb_mtapi_queue_t* that) { ...@@ -56,7 +56,9 @@ void embb_mtapi_queue_initialize(embb_mtapi_queue_t* that) {
mtapi_queueattr_init(&that->attributes, MTAPI_NULL); mtapi_queueattr_init(&that->attributes, MTAPI_NULL);
that->queue_id = MTAPI_QUEUE_ID_NONE; that->queue_id = MTAPI_QUEUE_ID_NONE;
embb_atomic_init_char(&that->enabled);
embb_atomic_store_char(&that->enabled, MTAPI_FALSE); embb_atomic_store_char(&that->enabled, MTAPI_FALSE);
embb_atomic_init_int(&that->num_tasks);
embb_atomic_store_int(&that->num_tasks, 0); embb_atomic_store_int(&that->num_tasks, 0);
that->job_handle.id = 0; that->job_handle.id = 0;
that->job_handle.tag = 0; that->job_handle.tag = 0;
...@@ -71,7 +73,9 @@ void embb_mtapi_queue_initialize_with_attributes_and_job( ...@@ -71,7 +73,9 @@ void embb_mtapi_queue_initialize_with_attributes_and_job(
that->attributes = *attributes; that->attributes = *attributes;
that->queue_id = MTAPI_QUEUE_ID_NONE; that->queue_id = MTAPI_QUEUE_ID_NONE;
embb_atomic_init_char(&that->enabled);
embb_atomic_store_char(&that->enabled, MTAPI_TRUE); embb_atomic_store_char(&that->enabled, MTAPI_TRUE);
embb_atomic_init_int(&that->num_tasks);
embb_atomic_store_int(&that->num_tasks, 0); embb_atomic_store_int(&that->num_tasks, 0);
that->job_handle = job; that->job_handle = job;
} }
...@@ -81,6 +85,8 @@ void embb_mtapi_queue_finalize(embb_mtapi_queue_t* that) { ...@@ -81,6 +85,8 @@ void embb_mtapi_queue_finalize(embb_mtapi_queue_t* that) {
that->job_handle.id = 0; that->job_handle.id = 0;
that->job_handle.tag = 0; that->job_handle.tag = 0;
embb_atomic_destroy_int(&that->num_tasks);
embb_atomic_destroy_char(&that->enabled);
embb_mtapi_queue_initialize(that); embb_mtapi_queue_initialize(that);
} }
......
...@@ -473,6 +473,7 @@ mtapi_boolean_t embb_mtapi_scheduler_initialize_with_mode( ...@@ -473,6 +473,7 @@ mtapi_boolean_t embb_mtapi_scheduler_initialize_with_mode(
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
assert(MTAPI_NULL != node); assert(MTAPI_NULL != node);
embb_atomic_init_int(&that->affine_task_counter);
embb_atomic_store_int(&that->affine_task_counter, 0); embb_atomic_store_int(&that->affine_task_counter, 0);
/* Paranoia sanitizing of scheduler mode */ /* Paranoia sanitizing of scheduler mode */
...@@ -555,6 +556,8 @@ void embb_mtapi_scheduler_finalize(embb_mtapi_scheduler_t * that) { ...@@ -555,6 +556,8 @@ void embb_mtapi_scheduler_finalize(embb_mtapi_scheduler_t * that) {
embb_mtapi_alloc_deallocate(that->worker_contexts); embb_mtapi_alloc_deallocate(that->worker_contexts);
that->worker_contexts = MTAPI_NULL; that->worker_contexts = MTAPI_NULL;
} }
embb_atomic_destroy_int(&that->affine_task_counter);
} }
embb_mtapi_scheduler_t * embb_mtapi_scheduler_new() { embb_mtapi_scheduler_t * embb_mtapi_scheduler_new() {
......
...@@ -79,20 +79,31 @@ void embb_mtapi_task_initialize(embb_mtapi_task_t* that) { ...@@ -79,20 +79,31 @@ void embb_mtapi_task_initialize(embb_mtapi_task_t* that) {
that->action.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->action.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->job.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->job.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
embb_atomic_init_int(&that->state);
embb_atomic_store_int(&that->state, MTAPI_TASK_ERROR); embb_atomic_store_int(&that->state, MTAPI_TASK_ERROR);
that->task_id = MTAPI_TASK_ID_NONE; that->task_id = MTAPI_TASK_ID_NONE;
that->group.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->group.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->queue.id = EMBB_MTAPI_IDPOOL_INVALID_ID; that->queue.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->error_code = MTAPI_SUCCESS; that->error_code = MTAPI_SUCCESS;
embb_atomic_init_unsigned_int(&that->current_instance);
embb_atomic_store_unsigned_int(&that->current_instance, 0); embb_atomic_store_unsigned_int(&that->current_instance, 0);
embb_spin_init(&that->state_lock); embb_spin_init(&that->state_lock);
embb_atomic_init_unsigned_int(&that->instances_todo);
} }
void embb_mtapi_task_finalize(embb_mtapi_task_t* that) { void embb_mtapi_task_finalize(embb_mtapi_task_t* that) {
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
embb_mtapi_task_initialize(that); that->action.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->job.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
embb_atomic_destroy_int(&that->state);
that->task_id = MTAPI_TASK_ID_NONE;
that->group.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->queue.id = EMBB_MTAPI_IDPOOL_INVALID_ID;
that->error_code = MTAPI_SUCCESS;
embb_atomic_destroy_unsigned_int(&that->current_instance);
embb_spin_destroy(&that->state_lock); embb_spin_destroy(&that->state_lock);
embb_atomic_destroy_unsigned_int(&that->instances_todo);
} }
mtapi_boolean_t embb_mtapi_task_execute( mtapi_boolean_t embb_mtapi_task_execute(
......
...@@ -58,7 +58,12 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize( ...@@ -58,7 +58,12 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize(
that->thread_priority = priority; that->thread_priority = priority;
that->is_main_thread = (worker_index == 0) ? that->is_main_thread = (worker_index == 0) ?
node->attributes.reuse_main_thread : MTAPI_FALSE; node->attributes.reuse_main_thread : MTAPI_FALSE;
embb_atomic_init_int(&that->run);
embb_atomic_init_int(&that->is_sleeping);
embb_atomic_store_int(&that->run, 0); embb_atomic_store_int(&that->run, 0);
embb_atomic_store_int(&that->is_sleeping, 0);
that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate( that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate(
sizeof(embb_mtapi_task_queue_t)*that->priorities); sizeof(embb_mtapi_task_queue_t)*that->priorities);
...@@ -101,7 +106,6 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize( ...@@ -101,7 +106,6 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize(
embb_mutex_init(&that->work_available_mutex, EMBB_MUTEX_PLAIN); embb_mutex_init(&that->work_available_mutex, EMBB_MUTEX_PLAIN);
embb_condition_init(&that->work_available); embb_condition_init(&that->work_available);
embb_atomic_store_int(&that->is_sleeping, 0);
that->is_initialized = MTAPI_TRUE; that->is_initialized = MTAPI_TRUE;
...@@ -208,6 +212,9 @@ void embb_mtapi_thread_context_finalize(embb_mtapi_thread_context_t* that) { ...@@ -208,6 +212,9 @@ void embb_mtapi_thread_context_finalize(embb_mtapi_thread_context_t* that) {
that->private_queue = MTAPI_NULL; that->private_queue = MTAPI_NULL;
} }
embb_atomic_destroy_int(&that->is_sleeping);
embb_atomic_destroy_int(&that->run);
that->priorities = 0; that->priorities = 0;
that->is_initialized = MTAPI_FALSE; that->is_initialized = MTAPI_FALSE;
......
...@@ -733,8 +733,12 @@ void TestContext() { ...@@ -733,8 +733,12 @@ void TestContext() {
} }
void ErrorTest::TestBasic() { void ErrorTest::TestBasic() {
embb_atomic_init_int(&wait);
TestNodeNotInit(); TestNodeNotInit();
TestParameter(); TestParameter();
TestLimits(); TestLimits();
TestContext(); TestContext();
embb_atomic_destroy_int(&wait);
} }
...@@ -84,7 +84,9 @@ void plugin_initialize( ...@@ -84,7 +84,9 @@ void plugin_initialize(
plugin_task.id = 0; plugin_task.id = 0;
plugin_task.tag = 0; plugin_task.tag = 0;
embb_atomic_init_int(&plugin_running);
embb_atomic_store_int(&plugin_running, 1); embb_atomic_store_int(&plugin_running, 1);
embb_atomic_init_int(&plugin_task_available);
embb_atomic_store_int(&plugin_task_available, 0); embb_atomic_store_int(&plugin_task_available, 0);
err = embb_thread_create(&plugin_thread, NULL, plugin_thread_function, NULL); err = embb_thread_create(&plugin_thread, NULL, plugin_thread_function, NULL);
...@@ -108,6 +110,9 @@ void plugin_finalize( ...@@ -108,6 +110,9 @@ void plugin_finalize(
local_status = MTAPI_SUCCESS; local_status = MTAPI_SUCCESS;
} }
embb_atomic_destroy_int(&plugin_task_available);
embb_atomic_destroy_int(&plugin_running);
mtapi_status_set(status, local_status); mtapi_status_set(status, local_status);
} }
......
...@@ -43,8 +43,6 @@ ...@@ -43,8 +43,6 @@
#include <embb/base/c/atomic.h> #include <embb/base/c/atomic.h>
PT_MAIN("MTAPI C") { PT_MAIN("MTAPI C") {
embb_atomic_initialize();
embb_log_set_log_level(EMBB_LOG_LEVEL_NONE); embb_log_set_log_level(EMBB_LOG_LEVEL_NONE);
embb_thread_set_max_count(1024); embb_thread_set_max_count(1024);
...@@ -57,6 +55,4 @@ PT_MAIN("MTAPI C") { ...@@ -57,6 +55,4 @@ PT_MAIN("MTAPI C") {
PT_RUN(IdPoolTest); PT_RUN(IdPoolTest);
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
embb_atomic_finalize();
} }
...@@ -35,13 +35,9 @@ ...@@ -35,13 +35,9 @@
PT_MAIN("MTAPI C++") { PT_MAIN("MTAPI C++") {
embb_atomic_initialize();
embb_thread_set_max_count(1024); embb_thread_set_max_count(1024);
PT_RUN(TaskTest); PT_RUN(TaskTest);
PT_RUN(GroupTest); PT_RUN(GroupTest);
PT_RUN(QueueTest); PT_RUN(QueueTest);
embb_atomic_finalize();
} }
...@@ -654,14 +654,17 @@ void mtapi_network_plugin_initialize( ...@@ -654,14 +654,17 @@ void mtapi_network_plugin_initialize(
plugin->socket_count = 0; plugin->socket_count = 0;
plugin->buffer_size = 0; plugin->buffer_size = 0;
plugin->sockets = NULL; plugin->sockets = NULL;
embb_atomic_store_int(&plugin->run, 0);
err = embb_mtapi_network_initialize(); err = embb_mtapi_network_initialize();
if (0 == err) return; if (0 == err) return;
embb_atomic_init_int(&plugin->run);
embb_atomic_store_int(&plugin->run, 0);
err = embb_mtapi_network_buffer_initialize( err = embb_mtapi_network_buffer_initialize(
&plugin->recv_buffer, (int)buffer_size); &plugin->recv_buffer, (int)buffer_size);
if (0 == err) { if (0 == err) {
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -670,6 +673,7 @@ void mtapi_network_plugin_initialize( ...@@ -670,6 +673,7 @@ void mtapi_network_plugin_initialize(
&plugin->send_buffer, (int)buffer_size); &plugin->send_buffer, (int)buffer_size);
if (0 == err) { if (0 == err) {
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -684,6 +688,7 @@ void mtapi_network_plugin_initialize( ...@@ -684,6 +688,7 @@ void mtapi_network_plugin_initialize(
embb_mtapi_network_buffer_finalize(&plugin->send_buffer); embb_mtapi_network_buffer_finalize(&plugin->send_buffer);
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
plugin->buffer_size = 0; plugin->buffer_size = 0;
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -695,6 +700,7 @@ void mtapi_network_plugin_initialize( ...@@ -695,6 +700,7 @@ void mtapi_network_plugin_initialize(
embb_mtapi_network_buffer_finalize(&plugin->send_buffer); embb_mtapi_network_buffer_finalize(&plugin->send_buffer);
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
plugin->buffer_size = 0; plugin->buffer_size = 0;
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -707,6 +713,7 @@ void mtapi_network_plugin_initialize( ...@@ -707,6 +713,7 @@ void mtapi_network_plugin_initialize(
embb_mtapi_network_buffer_finalize(&plugin->send_buffer); embb_mtapi_network_buffer_finalize(&plugin->send_buffer);
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
plugin->buffer_size = 0; plugin->buffer_size = 0;
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -723,6 +730,7 @@ void mtapi_network_plugin_initialize( ...@@ -723,6 +730,7 @@ void mtapi_network_plugin_initialize(
embb_mtapi_network_buffer_finalize(&plugin->send_buffer); embb_mtapi_network_buffer_finalize(&plugin->send_buffer);
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
plugin->buffer_size = 0; plugin->buffer_size = 0;
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -741,6 +749,7 @@ void mtapi_network_plugin_initialize( ...@@ -741,6 +749,7 @@ void mtapi_network_plugin_initialize(
embb_mtapi_network_buffer_finalize(&plugin->send_buffer); embb_mtapi_network_buffer_finalize(&plugin->send_buffer);
embb_mtapi_network_buffer_finalize(&plugin->recv_buffer); embb_mtapi_network_buffer_finalize(&plugin->recv_buffer);
plugin->buffer_size = 0; plugin->buffer_size = 0;
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
return; return;
} }
...@@ -764,6 +773,9 @@ void mtapi_network_plugin_finalize( ...@@ -764,6 +773,9 @@ void mtapi_network_plugin_finalize(
embb_mtapi_network_socket_finalize(&plugin->sockets[0]); embb_mtapi_network_socket_finalize(&plugin->sockets[0]);
embb_free(plugin->sockets); embb_free(plugin->sockets);
embb_atomic_destroy_int(&plugin->run);
embb_mtapi_network_finalize(); embb_mtapi_network_finalize();
mtapi_status_set(status, local_status); mtapi_status_set(status, local_status);
......
...@@ -33,11 +33,7 @@ ...@@ -33,11 +33,7 @@
#include <embb/base/c/atomic.h> #include <embb/base/c/atomic.h>
PT_MAIN("MTAPI NETWORK") { PT_MAIN("MTAPI NETWORK") {
embb_atomic_initialize();
PT_RUN(NetworkBufferTest); PT_RUN(NetworkBufferTest);
PT_RUN(NetworkSocketTest); PT_RUN(NetworkSocketTest);
PT_RUN(NetworkTaskTest); PT_RUN(NetworkTaskTest);
embb_atomic_finalize();
} }
...@@ -32,10 +32,6 @@ ...@@ -32,10 +32,6 @@
#include <embb/base/c/atomic.h> #include <embb/base/c/atomic.h>
PT_MAIN("MTAPI OPENCL") { PT_MAIN("MTAPI OPENCL") {
embb_atomic_initialize();
PT_RUN(LinkerTest); PT_RUN(LinkerTest);
PT_RUN(TaskTest); PT_RUN(TaskTest);
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