Commit 9018e0ad by Tobias Schuele

Merge branch 'development' of https://github.com/siemens/embb into development

parents 3866f358 36e27d5f
...@@ -90,10 +90,19 @@ function(SetVisualStudioCompilerFlags) ...@@ -90,10 +90,19 @@ function(SetVisualStudioCompilerFlags)
# Locally suppressed warnings (should not be globally suppressed): # Locally suppressed warnings (should not be globally suppressed):
# 4640 -> Information that local static variable initialization is not # 4640 -> Information that local static variable initialization is not
# thread-safe. # thread-safe.
#
# VS 2015 specific warnings:
# 5026 -> Move constructor was implicitly defined as deleted
# 5027 -> Move assignment operator was implicitly defined as deleted
#
set(warning_flags "/Wall /wd4820 /wd4514 /wd4668 /wd4710 /wd4350 /wd4571 /wd4625 /wd4626 /wd4711 /wd4255") set(warning_flags "/Wall /wd4820 /wd4514 /wd4668 /wd4710 /wd4350 /wd4571 /wd4625 /wd4626 /wd4711 /wd4255")
if (WARNINGS_ARE_ERRORS STREQUAL ON) if (WARNINGS_ARE_ERRORS STREQUAL ON)
set(warning_flags "${warning_flags} /WX") set(warning_flags "${warning_flags} /WX")
endif() endif()
string(FIND "${CMAKE_GENERATOR}" "Visual Studio 14 2015" vs2015_state)
if (vs2015_state EQUAL 0)
set(warning_flags "${warning_flags} /wd5026 /wd5027")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warning_flags}" PARENT_SCOPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warning_flags}" PARENT_SCOPE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${warning_flags}" PARENT_SCOPE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${warning_flags}" PARENT_SCOPE)
endif() endif()
......
...@@ -53,12 +53,6 @@ if(POLICY CMP0053) ...@@ -53,12 +53,6 @@ if(POLICY CMP0053)
cmake_policy(SET CMP0053 OLD) cmake_policy(SET CMP0053 OLD)
endif(POLICY CMP0053) endif(POLICY CMP0053)
include(CMakeCommon/FindOpenCL.cmake)
IF(NOT OpenCL_FOUND)
MESSAGE( STATUS "OpenCL is not there, will build without MTAPI OpenCL Plugin." )
ENDIF()
# give the user the possibility, to append compiler flags # give the user the possibility, to append compiler flags
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CMAKE_CXX_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CMAKE_CXX_FLAGS}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CMAKE_C_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CMAKE_C_FLAGS}")
...@@ -88,6 +82,7 @@ option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON ...@@ -88,6 +82,7 @@ option(USE_EXCEPTIONS "Specify whether exceptions should be activated in C++" ON
option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" ON) option(INSTALL_DOCS "Specify whether Doxygen docs should be installed" ON)
option(WARNINGS_ARE_ERRORS "Specify whether warnings should be treated as errors" OFF) option(WARNINGS_ARE_ERRORS "Specify whether warnings should be treated as errors" OFF)
option(USE_AUTOMATIC_INITIALIZATION "Specify whether the MTAPI C++ interface, algorithms and dataflow should automatically intialize the MTAPI node if no explicit initialization is present" ON) option(USE_AUTOMATIC_INITIALIZATION "Specify whether the MTAPI C++ interface, algorithms and dataflow should automatically intialize the MTAPI node if no explicit initialization is present" ON)
option(BUILD_OPENCL_PLUGIN "Specify whether the MTAPI OpenCL plugin should be built" OFF)
## LOCAL INSTALLATION OF SUBPROJECT BINARIES ## LOCAL INSTALLATION OF SUBPROJECT BINARIES
# #
...@@ -146,7 +141,7 @@ set(EXPECTED_EMBB_TEST_EXECUTABLES "embb_algorithms_cpp_test" ...@@ -146,7 +141,7 @@ set(EXPECTED_EMBB_TEST_EXECUTABLES "embb_algorithms_cpp_test"
) )
# if opencl is there, we also expect the mtapi opencl test to be generated # if opencl is there, we also expect the mtapi opencl test to be generated
if(OpenCL_FOUND) if(BUILD_OPENCL_PLUGIN STREQUAL ON)
list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test") list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test")
endif() endif()
...@@ -181,9 +176,9 @@ CheckPartestInstall(${BUILD_TESTS} partest_includepath partest_libpath) ...@@ -181,9 +176,9 @@ CheckPartestInstall(${BUILD_TESTS} partest_includepath partest_libpath)
add_subdirectory(base_c) add_subdirectory(base_c)
add_subdirectory(base_cpp) add_subdirectory(base_cpp)
add_subdirectory(mtapi_c) add_subdirectory(mtapi_c)
add_subdirectory(mtapi_network_c) add_subdirectory(mtapi_plugins_c/mtapi_network_c)
if(OpenCL_FOUND) if(BUILD_OPENCL_PLUGIN STREQUAL ON)
add_subdirectory(mtapi_opencl_c) add_subdirectory(mtapi_plugins_c/mtapi_opencl_c)
endif() endif()
add_subdirectory(tasks_cpp) add_subdirectory(tasks_cpp)
add_subdirectory(mtapi_cpp) add_subdirectory(mtapi_cpp)
......
...@@ -98,7 +98,8 @@ postfixed with either "_cpp" or "_c" for the C++ and C versions, respectively. ...@@ -98,7 +98,8 @@ postfixed with either "_cpp" or "_c" for the C++ and C versions, respectively.
Currently, EMB² contains the following components: Currently, EMB² contains the following components:
- base: base_c, base_cpp - base: base_c, base_cpp
- mtapi: mtapi_c, mtapi_network_c, mtapi_opencl_c, mtapi_cpp - mtapi: mtapi_c, mtapi_cpp and
mtapi_plugins_c (mtapi_network_c and mtapi_opencl_c)
- tasks: tasks_cpp - tasks: tasks_cpp
- algorithms: algorithms_cpp - algorithms: algorithms_cpp
- dataflow: dataflow_cpp - dataflow: dataflow_cpp
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) \ EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX) \
typedef struct \ typedef struct \
{ \ { \
EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \ volatile EMBB_ATOMIC_PARAMETER_TYPE_NATIVE internal_variable; \
} EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX); } EMBB_CAT2(embb_atomic_, EMBB_ATOMIC_PARAMETER_ATOMIC_TYPE_SUFFIX);
EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char) EMBB_ATOMIC_INTERNAL_DEFINE_VARIABLE(char, char)
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define EMBB_BASE_C_LOG_H_ #define EMBB_BASE_C_LOG_H_
#include <embb/base/c/internal/config.h> #include <embb/base/c/internal/config.h>
#include <stdarg.h>
/** /**
* \defgroup C_LOG Logging * \defgroup C_LOG Logging
...@@ -197,6 +198,13 @@ void embb_log_error( ...@@ -197,6 +198,13 @@ void embb_log_error(
\c message */ \c message */
); );
/* function for internal use only */
void embb_log_write_internal(
char const * channel,
embb_log_level_t log_level,
char const * message,
va_list argp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -179,6 +179,9 @@ int embb_spin_init( ...@@ -179,6 +179,9 @@ int embb_spin_init(
/** /**
* Spins until the spinlock can be locked and locks it. * Spins until the spinlock can be locked and locks it.
* *
* \note This method yields the current thread in regular,
* implementation-defined intervals.
*
* \pre \c spinlock is initialized \n * \pre \c spinlock is initialized \n
* \post If successful, \c spinlock is locked. * \post If successful, \c spinlock is locked.
* \return EMBB_SUCCESS if spinlock could be locked. \n * \return EMBB_SUCCESS if spinlock could be locked. \n
......
...@@ -144,4 +144,4 @@ void embb_internal_thread_index_reset() { ...@@ -144,4 +144,4 @@ void embb_internal_thread_index_reset() {
embb_internal_thread_index_var = UINT_MAX; embb_internal_thread_index_var = UINT_MAX;
embb_counter_init(embb_thread_index_counter()); embb_counter_init(embb_thread_index_counter());
} }
\ No newline at end of file
...@@ -59,7 +59,7 @@ void embb_log_set_log_function( ...@@ -59,7 +59,7 @@ void embb_log_set_log_function(
embb_log_global_log_function = func; embb_log_global_log_function = func;
} }
static void embb_log_write_internal( void embb_log_write_internal(
char const * channel, char const * channel,
embb_log_level_t log_level, embb_log_level_t log_level,
char const * message, char const * message,
...@@ -75,18 +75,20 @@ static void embb_log_write_internal( ...@@ -75,18 +75,20 @@ static void embb_log_write_internal(
log_context = (void*)stdout; log_context = (void*)stdout;
} }
switch (log_level) { switch (log_level) {
case EMBB_LOG_LEVEL_INFO:
log_level_str = "INFO ";
break;
case EMBB_LOG_LEVEL_ERROR: case EMBB_LOG_LEVEL_ERROR:
log_level_str = "ERROR"; log_level_str = "ERROR";
break; break;
case EMBB_LOG_LEVEL_WARNING:
log_level_str = "WARN ";
break;
case EMBB_LOG_LEVEL_INFO:
log_level_str = "INFO ";
break;
case EMBB_LOG_LEVEL_TRACE: case EMBB_LOG_LEVEL_TRACE:
log_level_str = "TRACE"; log_level_str = "TRACE";
break; break;
case EMBB_LOG_LEVEL_NONE: case EMBB_LOG_LEVEL_NONE:
case EMBB_LOG_LEVEL_WARNING:
default: default:
log_level_str = " "; log_level_str = " ";
break; break;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
*/ */
#include <embb/base/c/mutex.h> #include <embb/base/c/mutex.h>
#include <embb/base/c/thread.h>
#include <assert.h> #include <assert.h>
#include <embb/base/c/internal/unused.h> #include <embb/base/c/internal/unused.h>
...@@ -125,10 +126,15 @@ int embb_spin_init(embb_spinlock_t* spinlock) { ...@@ -125,10 +126,15 @@ int embb_spin_init(embb_spinlock_t* spinlock) {
int embb_spin_lock(embb_spinlock_t* spinlock) { int embb_spin_lock(embb_spinlock_t* spinlock) {
int expected = 0; int expected = 0;
int spins = 1;
// try to swap the // try to swap the
while (0 == embb_atomic_compare_and_swap_int( while (0 == embb_atomic_compare_and_swap_int(
&spinlock->atomic_spin_variable_, &expected, 1)) { &spinlock->atomic_spin_variable_, &expected, 1)) {
if (0 == (spins & 1023)) {
embb_thread_yield();
}
spins++;
// reset expected, as CAS might change it... // reset expected, as CAS might change it...
expected = 0; expected = 0;
} }
......
...@@ -62,7 +62,7 @@ class Atomic { ...@@ -62,7 +62,7 @@ class Atomic {
/** /**
* Default constructor. * Default constructor.
* *
* Constructs an atomic variable holding an uninitialized value. * Constructs an atomic variable holding zero.
* *
* \waitfree * \waitfree
* *
......
/*
* 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_LOG_H_
#define EMBB_BASE_LOG_H_
#include <embb/base/c/log.h>
/**
* \defgroup CPP_LOG Logging
* \ingroup CPP_BASE
* Simple logging facilities.
*/
namespace embb {
namespace base {
/**
* Simple logging facilities.
*
* \ingroup CPP_LOG
*/
class Log {
private:
// do not allow construction
Log();
public:
/**
* Sets the global log level.
* This determines what messages will be shown, messages with a more detailed
* log level will be filtered out. The default log level is EMBB_LOG_LEVEL_NONE.
* \notthreadsafe
*/
static void SetLogLevel(
embb_log_level_t log_level /**< [in] Log level to use for
filtering */
);
/**
* Sets the global logging function.
* The logging function implements the mechanism for transferring log messages
* to their destination. \c context is a pointer to data the user needs in the
* function to determine where the messages should go (may be NULL if no
* additional data is needed). The default logging function is
* embb_log_write_file() with context set to \c stdout.
* \see embb_log_function_t
* \notthreadsafe
*/
static void SetLogFunction(
void * context, /**< [in] User context to supply as the
first parameter of the logging
function*/
embb_log_function_t func /**< [in] The logging function */
);
/**
* Logs a message to the given channel with the specified log level.
* If the log level is greater than the configured log level for the channel,
* the message will be ignored.
* \see embb::base::Log::SetLogLevel, embb::base::Log::SetLogFunction
* \threadsafe
*/
static void Write(
char const * channel, /**< [in] User specified channel id
for filtering the log later on.
Might be NULL, channel identifier
will be "global" in that case */
embb_log_level_t log_level, /**< [in] Log level to use */
char const * message, /**< [in] Message to convey, may use
\c printf style formatting */
... /**< Additional parameters determined
by the format specifiers in
\c message */
);
/**
* Logs a message to the given channel with EMBB_LOG_LEVEL_TRACE.
* In non-debug builds, this function does nothing.
* \see embb::base::Log::Write
* \threadsafe
*/
static void Trace(
char const * channel, /**< [in] User specified channel id */
char const * message, /**< [in] Message to convey, may use
\c printf style formatting */
... /**< Additional parameters determined
by the format specifiers in
\c message */
);
/**
* Logs a message to the given channel with EMBB_LOG_LEVEL_INFO.
* In non-debug builds, this function does nothing.
* \see embb::base::Log::Write
* \threadsafe
*/
static void Info(
char const * channel, /**< [in] User specified channel id */
char const * message, /**< [in] Message to convey, may use
\c printf style formatting */
... /**< Additional parameters determined
by the format specifiers in
\c message */
);
/**
* Logs a message to the given channel with EMBB_LOG_LEVEL_WARNING.
* \see embb::base::Log::Write
* \threadsafe
*/
static void Warning(
char const * channel, /**< [in] User specified channel id */
char const * message, /**< [in] Message to convey, may use
\c printf style formatting */
... /**< Additional parameters determined
by the format specifiers in
\c message */
);
/**
* Logs a message to the given channel with EMBB_LOG_LEVEL_ERROR.
* \see embb::base::Log::Write
* \threadsafe
*/
static void Error(
char const * channel, /**< [in] User specified channel id */
char const * message, /**< [in] Message to convey, may use
\c printf style formatting */
... /**< Additional parameters determined
by the format specifiers in
\c message */
);
};
} // namespace base
} // namespace embb
#endif // EMBB_BASE_LOG_H_
...@@ -191,6 +191,9 @@ class Spinlock { ...@@ -191,6 +191,9 @@ class Spinlock {
/** /**
* Waits until the spinlock can be locked and locks it. * Waits until the spinlock can be locked and locks it.
* *
* \note This method yields the current thread in regular,
* implementation-defined intervals.
*
* \pre The spinlock is not locked by the current thread. * \pre The spinlock is not locked by the current thread.
* \post The spinlock is locked. * \post The spinlock is locked.
* \threadsafe * \threadsafe
......
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <embb/base/log.h>
#include <embb/base/c/internal/unused.h>
namespace embb {
namespace base {
Log::Log() {
// empty
}
void Log::SetLogLevel(
embb_log_level_t log_level) {
embb_log_set_log_level(log_level);
}
void Log::SetLogFunction(
void * context,
embb_log_function_t func) {
embb_log_set_log_function(context, func);
}
void Log::Write(
char const * channel,
embb_log_level_t log_level,
char const * message,
...) {
va_list argp;
va_start(argp, message);
embb_log_write_internal(channel, log_level, message, argp);
va_end(argp);
}
void Log::Trace(
char const * channel,
char const * message,
...) {
#if defined(EMBB_DEBUG)
va_list argp;
va_start(argp, message);
embb_log_write_internal(channel, EMBB_LOG_LEVEL_TRACE, message, argp);
va_end(argp);
#else
EMBB_UNUSED(channel);
EMBB_UNUSED(message);
#endif
}
void Log::Info(
char const * channel,
char const * message,
...) {
#if defined(EMBB_DEBUG)
va_list argp;
va_start(argp, message);
embb_log_write_internal(channel, EMBB_LOG_LEVEL_INFO, message, argp);
va_end(argp);
#else
EMBB_UNUSED(channel);
EMBB_UNUSED(message);
#endif
}
void Log::Warning(
char const * channel,
char const * message,
...) {
va_list argp;
va_start(argp, message);
embb_log_write_internal(channel, EMBB_LOG_LEVEL_WARNING, message, argp);
va_end(argp);
}
void Log::Error(
char const * channel,
char const * message,
...) {
va_list argp;
va_start(argp, message);
embb_log_write_internal(channel, EMBB_LOG_LEVEL_ERROR, message, argp);
va_end(argp);
}
} // namespace base
} // namespace embb
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <log_test.h>
#include <embb/base/c/internal/unused.h>
#include <embb/base/log.h>
#include <cstring>
namespace embb {
namespace base {
namespace test {
LogTest::LogTest() {
CreateUnit("Test all").Add(&LogTest::Test, this);
}
static char const * logged_message;
static void test_log_function(void * context, char const * msg) {
EMBB_UNUSED(context);
logged_message = msg;
}
void LogTest::Test() {
using embb::base::Log;
char const * test_msg = "hello";
char const * null = 0;
Log::SetLogFunction(0, test_log_function);
Log::SetLogLevel(EMBB_LOG_LEVEL_TRACE);
logged_message = null;
Log::Trace("chn", test_msg);
#ifdef EMBB_DEBUG
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [TRACE] hello"));
#else
PT_EXPECT_EQ(null, logged_message);
#endif
logged_message = null;
Log::Info("chn", test_msg);
#ifdef EMBB_DEBUG
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [INFO ] hello"));
#else
PT_EXPECT_EQ(null, logged_message);
#endif
logged_message = null;
Log::Warning("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello"));
logged_message = null;
Log::Error("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello"));
Log::SetLogLevel(EMBB_LOG_LEVEL_INFO);
logged_message = null;
Log::Trace("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Info("chn", test_msg);
#ifdef EMBB_DEBUG
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [INFO ] hello"));
#else
PT_EXPECT_EQ(null, logged_message);
#endif
logged_message = null;
Log::Warning("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello"));
logged_message = null;
Log::Error("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello"));
Log::SetLogLevel(EMBB_LOG_LEVEL_WARNING);
logged_message = null;
Log::Trace("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Info("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Warning("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [WARN ] hello"));
logged_message = null;
Log::Error("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello"));
Log::SetLogLevel(EMBB_LOG_LEVEL_ERROR);
logged_message = null;
Log::Trace("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Info("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Warning("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Error("chn", test_msg);
PT_EXPECT(0 == strcmp(logged_message, "[chn] - [ERROR] hello"));
Log::SetLogLevel(EMBB_LOG_LEVEL_NONE);
logged_message = null;
Log::Trace("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Info("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Warning("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
logged_message = null;
Log::Error("chn", test_msg);
PT_EXPECT_EQ(null, logged_message);
}
} // namespace test
} // namespace base
} // namespace embb
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASE_CPP_TEST_LOG_TEST_H_
#define BASE_CPP_TEST_LOG_TEST_H_
#include <partest/partest.h>
namespace embb {
namespace base {
namespace test {
/**
* Provides tests for Log.
*/
class LogTest : public partest::TestCase {
public:
/**
* Adds test methods.
*/
LogTest();
private:
/**
* Tests all functionalities.
*/
void Test();
};
} // namespace test
} // namespace base
} // namespace embb
#endif // BASE_CPP_TEST_LOG_TEST_H_
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <thread_specific_storage_test.h> #include <thread_specific_storage_test.h>
#include <atomic_test.h> #include <atomic_test.h>
#include <memory_allocation_test.h> #include <memory_allocation_test.h>
#include <log_test.h>
#include <embb/base/c/memory_allocation.h> #include <embb/base/c/memory_allocation.h>
...@@ -46,6 +47,7 @@ using embb::base::test::ThreadSpecificStorageTest; ...@@ -46,6 +47,7 @@ using embb::base::test::ThreadSpecificStorageTest;
using embb::base::test::AtomicTest; using embb::base::test::AtomicTest;
using embb::base::test::MemoryAllocationTest; using embb::base::test::MemoryAllocationTest;
using embb::base::test::ThreadTest; using embb::base::test::ThreadTest;
using embb::base::test::LogTest;
PT_MAIN("Base C++") { PT_MAIN("Base C++") {
unsigned int max_threads = unsigned int max_threads =
...@@ -61,6 +63,7 @@ PT_MAIN("Base C++") { ...@@ -61,6 +63,7 @@ PT_MAIN("Base C++") {
PT_RUN(AtomicTest); PT_RUN(AtomicTest);
PT_RUN(MemoryAllocationTest); PT_RUN(MemoryAllocationTest);
PT_RUN(ThreadTest); PT_RUN(ThreadTest);
PT_RUN(LogTest);
PT_EXPECT(embb_get_bytes_allocated() == 0); PT_EXPECT(embb_get_bytes_allocated() == 0);
} }
...@@ -46,8 +46,8 @@ namespace internal { ...@@ -46,8 +46,8 @@ namespace internal {
} }
template< typename T > template< typename T >
void LockFreeStackNode< T >::SetNext(LockFreeStackNode< T >* next) { void LockFreeStackNode< T >::SetNext(LockFreeStackNode< T >* next_to_set) {
this->next = next; this->next = next_to_set;
} }
template< typename T > template< typename T >
......
...@@ -169,7 +169,7 @@ void HazardPointerTest::HazardPointerTest1ThreadMethod() { ...@@ -169,7 +169,7 @@ void HazardPointerTest::HazardPointerTest1ThreadMethod() {
same = true; same = true;
break; break;
} }
bool success = stack_->TryPush(allocated_object_from_different_thread); success = stack_->TryPush(allocated_object_from_different_thread);
PT_ASSERT(success == true); PT_ASSERT(success == true);
} }
PT_ASSERT(success_pop == true); PT_ASSERT(success_pop == true);
......
...@@ -165,7 +165,6 @@ void PoolTest<ValuePool_t>::PoolTestStatic() { ...@@ -165,7 +165,6 @@ void PoolTest<ValuePool_t>::PoolTestStatic() {
//if we allocate again, we should get those elements //if we allocate again, we should get those elements
for (int i = 0; i != static_cast<int>(indexes_to_free.size()); i++) { for (int i = 0; i != static_cast<int>(indexes_to_free.size()); i++) {
int element, index;
index = ap.Allocate(element); index = ap.Allocate(element);
PT_EXPECT((index != -1)); PT_EXPECT((index != -1));
......
...@@ -39,29 +39,22 @@ namespace internal { ...@@ -39,29 +39,22 @@ namespace internal {
class Action { class Action {
public: public:
Action() : node_(NULL), clock_(0), pending_(0) {} Action() : node_(NULL), clock_(0) {}
Action(Node * node, int clock) : node_(node), clock_(clock), pending_(2) {} Action(Node * node, int clock) : node_(node), clock_(clock) {}
void RunSequential() { void RunSequential() {
pending_ = 1;
node_->Run(clock_); node_->Run(clock_);
pending_ = 0;
} }
void RunMTAPI(embb::tasks::TaskContext & /*context*/) { void RunMTAPI(embb::tasks::TaskContext & /*context*/) {
pending_ = 1;
node_->Run(clock_); node_->Run(clock_);
pending_ = 0;
} }
bool IsPending() const { return pending_ > 0; }
int GetClock() const { return clock_; } int GetClock() const { return clock_; }
private: private:
Node * node_; Node * node_;
int clock_; int clock_;
volatile int pending_;
}; };
} // namespace internal } // namespace internal
......
...@@ -102,8 +102,9 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -102,8 +102,9 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
} }
template <typename T> template <typename T>
void operator >> (T & target) { T & operator >> (T & target) {
GetOutput<0>() >> target.template GetInput<0>(); GetOutput<0>() >> target.template GetInput<0>();
return target;
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <embb/tasks/node.h> #include <embb/tasks/node.h>
#include <embb/base/function.h> #include <embb/base/function.h>
#include <algorithm>
namespace embb { namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
...@@ -46,7 +48,9 @@ class SchedulerMTAPI : public Scheduler { ...@@ -46,7 +48,9 @@ class SchedulerMTAPI : public Scheduler {
group_[ii] = &group; group_[ii] = &group;
} }
queue_count_ = static_cast<int>(node.GetWorkerThreadCount()); queue_count_ = std::min(
static_cast<int>(node.GetQueueCount()),
static_cast<int>(node.GetWorkerThreadCount()) );
queue_ = reinterpret_cast<embb::tasks::Queue**>( queue_ = reinterpret_cast<embb::tasks::Queue**>(
embb::base::Allocation::Allocate( embb::base::Allocation::Allocate(
sizeof(embb::tasks::Queue*)*queue_count_)); sizeof(embb::tasks::Queue*)*queue_count_));
......
...@@ -105,8 +105,9 @@ class Select ...@@ -105,8 +105,9 @@ class Select
} }
template <typename T> template <typename T>
void operator >> (T & target) { T & operator >> (T & target) {
GetOutput<0>() >> target.template GetInput<0>(); GetOutput<0>() >> target.template GetInput<0>();
return target;
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#ifndef EMBB_DATAFLOW_INTERNAL_SOURCE_H_ #ifndef EMBB_DATAFLOW_INTERNAL_SOURCE_H_
#define EMBB_DATAFLOW_INTERNAL_SOURCE_H_ #define EMBB_DATAFLOW_INTERNAL_SOURCE_H_
#include <embb/base/atomic.h>
#include <embb/dataflow/internal/node.h> #include <embb/dataflow/internal/node.h>
#include <embb/dataflow/internal/outputs.h> #include <embb/dataflow/internal/outputs.h>
#include <embb/dataflow/internal/source_executor.h> #include <embb/dataflow/internal/source_executor.h>
...@@ -81,14 +83,15 @@ class Source< Slices, Outputs<Slices, O1, O2, O3, O4, O5> > ...@@ -81,14 +83,15 @@ class Source< Slices, Outputs<Slices, O1, O2, O3, O4, O5> >
} }
template <typename T> template <typename T>
void operator >> (T & target) { T & operator >> (T & target) {
GetOutput<0>() >> target.template GetInput<0>(); GetOutput<0>() >> target.template GetInput<0>();
return target;
} }
private: private:
OutputsType outputs_; OutputsType outputs_;
ExecutorType executor_; ExecutorType executor_;
volatile bool not_done_; embb::base::Atomic<bool> not_done_;
}; };
} // namespace internal } // namespace internal
......
...@@ -53,7 +53,9 @@ class SourceExecutor< Outputs<Slices, O1> > { ...@@ -53,7 +53,9 @@ class SourceExecutor< Outputs<Slices, O1> > {
Outputs<Slices, O1> & outputs) { Outputs<Slices, O1> & outputs) {
O1 o1; O1 o1;
bool result = function_(o1); bool result = function_(o1);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); if (result) {
outputs.template Get<0>().Send(Signal<O1>(clock, o1));
}
return result; return result;
} }
...@@ -78,8 +80,10 @@ class SourceExecutor< Outputs<Slices, O1, O2> > { ...@@ -78,8 +80,10 @@ class SourceExecutor< Outputs<Slices, O1, O2> > {
O1 o1; O1 o1;
O2 o2; O2 o2;
bool result = function_(o1, o2); bool result = function_(o1, o2);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); if (result) {
outputs.template Get<1>().Send(Signal<O2>(clock, o2)); outputs.template Get<0>().Send(Signal<O1>(clock, o1));
outputs.template Get<1>().Send(Signal<O2>(clock, o2));
}
return result; return result;
} }
...@@ -106,9 +110,11 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > { ...@@ -106,9 +110,11 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > {
O2 o2; O2 o2;
O3 o3; O3 o3;
bool result = function_(o1, o2, o3); bool result = function_(o1, o2, o3);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); if (result) {
outputs.template Get<1>().Send(Signal<O2>(clock, o2)); outputs.template Get<0>().Send(Signal<O1>(clock, o1));
outputs.template Get<2>().Send(Signal<O3>(clock, o3)); outputs.template Get<1>().Send(Signal<O2>(clock, o2));
outputs.template Get<2>().Send(Signal<O3>(clock, o3));
}
return result; return result;
} }
...@@ -137,10 +143,12 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > { ...@@ -137,10 +143,12 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > {
O3 o3; O3 o3;
O4 o4; O4 o4;
bool result = function_(o1, o2, o3, o4); bool result = function_(o1, o2, o3, o4);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); if (result) {
outputs.template Get<1>().Send(Signal<O2>(clock, o2)); outputs.template Get<0>().Send(Signal<O1>(clock, o1));
outputs.template Get<2>().Send(Signal<O3>(clock, o3)); outputs.template Get<1>().Send(Signal<O2>(clock, o2));
outputs.template Get<3>().Send(Signal<O4>(clock, o4)); outputs.template Get<2>().Send(Signal<O3>(clock, o3));
outputs.template Get<3>().Send(Signal<O4>(clock, o4));
}
return result; return result;
} }
...@@ -172,11 +180,13 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > { ...@@ -172,11 +180,13 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > {
O4 o4; O4 o4;
O5 o5; O5 o5;
bool result = function_(o1, o2, o3, o4, o5); bool result = function_(o1, o2, o3, o4, o5);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); if (result) {
outputs.template Get<1>().Send(Signal<O2>(clock, o2)); outputs.template Get<0>().Send(Signal<O1>(clock, o1));
outputs.template Get<2>().Send(Signal<O3>(clock, o3)); outputs.template Get<1>().Send(Signal<O2>(clock, o2));
outputs.template Get<3>().Send(Signal<O4>(clock, o4)); outputs.template Get<2>().Send(Signal<O3>(clock, o3));
outputs.template Get<4>().Send(Signal<O5>(clock, o5)); outputs.template Get<3>().Send(Signal<O4>(clock, o4));
outputs.template Get<4>().Send(Signal<O5>(clock, o5));
}
return result; return result;
} }
......
...@@ -103,8 +103,9 @@ class Switch ...@@ -103,8 +103,9 @@ class Switch
} }
template <typename T> template <typename T>
void operator >> (T & target) { T & operator >> (T & target) {
GetOutput<0>() >> target.template GetInput<0>(); GetOutput<0>() >> target.template GetInput<0>();
return target;
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
......
...@@ -56,12 +56,16 @@ embb::base::Atomic<int> source_counter; ...@@ -56,12 +56,16 @@ embb::base::Atomic<int> source_counter;
int source_array[TEST_COUNT]; int source_array[TEST_COUNT];
bool sourceFunc(int & out) { bool sourceFunc(int & out) {
out = source_counter; if (source_counter < TEST_COUNT) {
out = source_counter;
source_array[source_counter] = out; source_array[source_counter] = out;
source_counter++; source_counter++;
return source_counter < TEST_COUNT; return true;
} else {
return false;
}
} }
embb::base::Atomic<int> pred_counter; embb::base::Atomic<int> pred_counter;
...@@ -149,14 +153,13 @@ SimpleTest::SimpleTest() { ...@@ -149,14 +153,13 @@ SimpleTest::SimpleTest() {
void SimpleTest::TestBasic() { void SimpleTest::TestBasic() {
// All available cores // All available cores
embb::base::CoreSet core_set(true); embb::base::CoreSet core_set(true);
unsigned int num_cores = core_set.Count();
embb::tasks::Node::Initialize( embb::tasks::Node::Initialize(
MTAPI_DOMAIN_ID, MTAPI_DOMAIN_ID,
MTAPI_NODE_ID, MTAPI_NODE_ID,
core_set, core_set,
1024, // max tasks (default: 1024) 1024, // max tasks (default: 1024)
128, // max groups (default: 128) 128, // max groups (default: 128)
num_cores, // max queues (default: 16) 2, // max queues (default: 16)
1024, // queue capacity (default: 1024) 1024, // queue capacity (default: 1024)
4); // num priorities (default: 4) 4); // num priorities (default: 4)
...@@ -189,11 +192,14 @@ void SimpleTest::TestBasic() { ...@@ -189,11 +192,14 @@ void SimpleTest::TestBasic() {
source.GetOutput<0>() >> sw.GetInput<1>(); source.GetOutput<0>() >> sw.GetInput<1>();
source.GetOutput<0>() >> pred.GetInput<0>(); // connection chain representing the commented single connections below
pred.GetOutput<0>() >> sw.GetInput<0>(); source >> pred >> sw >> filter;
//source.GetOutput<0>() >> pred.GetInput<0>();
//pred.GetOutput<0>() >> sw.GetInput<0>();
pred.GetOutput<0>() >> sel.GetInput<0>(); pred.GetOutput<0>() >> sel.GetInput<0>();
sw.GetOutput<0>() >> filter.GetInput<0>(); //sw.GetOutput<0>() >> filter.GetInput<0>();
filter.GetOutput<0>() >> sel.GetInput<1>(); filter.GetOutput<0>() >> sel.GetInput<1>();
constant.GetOutput<0>() >> mult.GetInput<0>(); constant.GetOutput<0>() >> mult.GetInput<0>();
......
...@@ -12,7 +12,7 @@ include_directories( ...@@ -12,7 +12,7 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}/../../base_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../../base_cpp/include
${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src
${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_network_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_plugins_c/mtapi_network_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_cpp/include
${CMAKE_CURRENT_SOURCE_DIR}/../../tasks_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../tasks_cpp/include
${CMAKE_CURRENT_BINARY_DIR}/../../tasks_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../../tasks_cpp/include
...@@ -21,12 +21,12 @@ include_directories( ...@@ -21,12 +21,12 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../dataflow_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../dataflow_cpp/include
) )
if(OpenCL_FOUND) if(BUILD_OPENCL_PLUGIN STREQUAL ON)
# used in source code, to include opencl code # used in source code, to include opencl code
add_definitions(-DEMBB_WITH_OPENCL) add_definitions(-DEMBB_WITH_OPENCL)
# add opencl includes # add opencl includes
include_directories( include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_opencl_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_plugins_c/mtapi_opencl_c/include
) )
# later used, to link opencl to target... # later used, to link opencl to target...
set (EMBB_MTAPI_OPENCL_C_CONDITIONAL "embb_mtapi_opencl_c") set (EMBB_MTAPI_OPENCL_C_CONDITIONAL "embb_mtapi_opencl_c")
......
...@@ -4,12 +4,12 @@ int i, j; ...@@ -4,12 +4,12 @@ int i, j;
bool result = queue.TryDequeue(i); //@\label{lst:queue_lst1:fail_pop}@ bool result = queue.TryDequeue(i); //@\label{lst:queue_lst1:fail_pop}@
assert(result == false); assert(result == false);
for (int i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop1}@ for (i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop1}@
result = queue.TryEnqueue(i); //@\label{lst:queue_lst1:push}@ result = queue.TryEnqueue(i); //@\label{lst:queue_lst1:push}@
assert(result == true); assert(result == true);
} }
for (int i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop2}@ for (i = 0; i <= 4; ++i) { //@\label{lst:queue_lst1:loop2}@
result = queue.TryDequeue(j); //@\label{lst:queue_lst1:pop}@ result = queue.TryDequeue(j); //@\label{lst:queue_lst1:pop}@
assert(result == true && i == j); //@\label{lst:queue_lst1:assert}@ assert(result == true && i == j); //@\label{lst:queue_lst1:assert}@
} }
\ No newline at end of file
...@@ -4,12 +4,12 @@ int i, j; ...@@ -4,12 +4,12 @@ int i, j;
bool result = stack.TryPop(i); //@\label{lst:stack_lst1:fail_pop}@ bool result = stack.TryPop(i); //@\label{lst:stack_lst1:fail_pop}@
assert(result == false); assert(result == false);
for (int i = 0; i <= 4; ++i) {//@\label{lst:stack_lst1:loop1}@ for (i = 0; i <= 4; ++i) {//@\label{lst:stack_lst1:loop1}@
result = stack.TryPush(i); //@\label{lst:stack_lst1:push}@ result = stack.TryPush(i); //@\label{lst:stack_lst1:push}@
assert(result == true); assert(result == true);
} }
for (int i = 4; i >= 0; --i) { //@\label{lst:stack_lst1:loop2}@ for (i = 4; i >= 0; --i) { //@\label{lst:stack_lst1:loop2}@
result = stack.TryPop(j); //@\label{lst:stack_lst1:pop}@ result = stack.TryPop(j); //@\label{lst:stack_lst1:pop}@
assert(result == true && i == j); //@\label{lst:stack_lst1:assert}@ assert(result == true && i == j); //@\label{lst:stack_lst1:assert}@
} }
\ No newline at end of file
read >> replace; read >> replace >> write;
replace >> write;
...@@ -3,10 +3,14 @@ class Producer { ...@@ -3,10 +3,14 @@ class Producer {
public: public:
explicit Producer(int seed) : seed_(seed), count_(4) {} explicit Producer(int seed) : seed_(seed), count_(4) {}
bool Run(T& x) { bool Run(T& x) {
// produce a new value x if (count_ >= 0) {
x = SimpleRand(seed_); // produce a new value x
count_--; x = SimpleRand(seed_);
return count_ >= 0; count_--;
return true;
} else {
return false;
}
} }
private: private:
......
bool SourceFunction(std::string & str) { bool SourceFunction(std::string & str) {
std::getline(file, str); if (!file.eof()) {
return !file.eof(); std::getline(file, str);
return true;
} else {
return false;
}
} }
...@@ -153,8 +153,8 @@ INPUT = "@CMAKE_SOURCE_DIR@/doc/reference/embb.dox" \ ...@@ -153,8 +153,8 @@ INPUT = "@CMAKE_SOURCE_DIR@/doc/reference/embb.dox" \
"@CMAKE_SOURCE_DIR@/base_cpp/include" \ "@CMAKE_SOURCE_DIR@/base_cpp/include" \
"@CMAKE_SOURCE_DIR@/mtapi_c/include" \ "@CMAKE_SOURCE_DIR@/mtapi_c/include" \
"@CMAKE_SOURCE_DIR@/base_c/include" \ "@CMAKE_SOURCE_DIR@/base_c/include" \
"@CMAKE_SOURCE_DIR@/mtapi_opencl_c/include" \ "@CMAKE_SOURCE_DIR@/mtapi_plugins_c/mtapi_opencl_c/include" \
"@CMAKE_SOURCE_DIR@/mtapi_network_c/include" "@CMAKE_SOURCE_DIR@/mtapi_plugins_c/mtapi_network_c/include"
INPUT_ENCODING = UTF-8 INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \ FILE_PATTERNS = *.h \
......
...@@ -55,7 +55,7 @@ void embb_mtapi_group_initialize(embb_mtapi_group_t * that) { ...@@ -55,7 +55,7 @@ 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;
that->deleted = MTAPI_FALSE; embb_atomic_store_int(&that->deleted, MTAPI_FALSE);
that->num_tasks.internal_variable = 0; that->num_tasks.internal_variable = 0;
embb_mtapi_task_queue_initialize(&that->queue); embb_mtapi_task_queue_initialize(&that->queue);
} }
...@@ -67,7 +67,7 @@ void embb_mtapi_group_initialize_with_node( ...@@ -67,7 +67,7 @@ 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;
that->deleted = MTAPI_FALSE; embb_atomic_store_int(&that->deleted, MTAPI_FALSE);
that->num_tasks.internal_variable = 0; that->num_tasks.internal_variable = 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);
...@@ -76,7 +76,7 @@ void embb_mtapi_group_initialize_with_node( ...@@ -76,7 +76,7 @@ void embb_mtapi_group_initialize_with_node(
void embb_mtapi_group_finalize(embb_mtapi_group_t * that) { void embb_mtapi_group_finalize(embb_mtapi_group_t * that) {
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
that->deleted = MTAPI_TRUE; embb_atomic_store_int(&that->deleted, MTAPI_TRUE);
that->num_tasks.internal_variable = 0; that->num_tasks.internal_variable = 0;
embb_mtapi_task_queue_finalize(&that->queue); embb_mtapi_task_queue_finalize(&that->queue);
} }
...@@ -372,7 +372,7 @@ void mtapi_group_delete( ...@@ -372,7 +372,7 @@ void mtapi_group_delete(
embb_mtapi_group_pool_get_storage_for_handle( embb_mtapi_group_pool_get_storage_for_handle(
node->group_pool, group); node->group_pool, group);
if (local_group->deleted) { if (embb_atomic_load_int(&local_group->deleted)) {
local_status = MTAPI_ERR_GROUP_INVALID; local_status = MTAPI_ERR_GROUP_INVALID;
} else { } else {
embb_mtapi_group_finalize(local_group); embb_mtapi_group_finalize(local_group);
......
...@@ -55,7 +55,7 @@ struct embb_mtapi_group_struct { ...@@ -55,7 +55,7 @@ struct embb_mtapi_group_struct {
mtapi_group_hndl_t handle; mtapi_group_hndl_t handle;
mtapi_group_id_t group_id; mtapi_group_id_t group_id;
volatile mtapi_boolean_t deleted; embb_atomic_int deleted;
embb_atomic_int num_tasks; embb_atomic_int num_tasks;
mtapi_group_attributes_t attributes; mtapi_group_attributes_t attributes;
embb_mtapi_task_queue_t queue; embb_mtapi_task_queue_t queue;
......
...@@ -302,7 +302,7 @@ int embb_mtapi_scheduler_worker(void * arg) { ...@@ -302,7 +302,7 @@ int embb_mtapi_scheduler_worker(void * arg) {
node->queue_pool, task->queue); node->queue_pool, task->queue);
} }
switch (task->state) { switch (embb_atomic_load_int(&task->state)) {
case MTAPI_TASK_SCHEDULED: case MTAPI_TASK_SCHEDULED:
/* multi-instance task, another instance might be running */ /* multi-instance task, another instance might be running */
case MTAPI_TASK_RUNNING: case MTAPI_TASK_RUNNING:
...@@ -398,10 +398,12 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( ...@@ -398,10 +398,12 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task(
node->scheduler); node->scheduler);
/* now wait and schedule new tasks if we are on a worker */ /* now wait and schedule new tasks if we are on a worker */
mtapi_task_state_t task_state =
(mtapi_task_state_t)embb_atomic_load_int(&task->state);
while ( while (
(MTAPI_TASK_SCHEDULED == task->state) || (MTAPI_TASK_SCHEDULED == task_state) ||
(MTAPI_TASK_RUNNING == task->state) || (MTAPI_TASK_RUNNING == task_state) ||
(MTAPI_TASK_RETAINED == task->state) ) { (MTAPI_TASK_RETAINED == task_state) ) {
if (MTAPI_INFINITE < timeout) { if (MTAPI_INFINITE < timeout) {
embb_time_t current_time; embb_time_t current_time;
embb_time_now(&current_time); embb_time_now(&current_time);
...@@ -416,6 +418,8 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( ...@@ -416,6 +418,8 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task(
node->scheduler, node->scheduler,
node, node,
context); context);
task_state = (mtapi_task_state_t)embb_atomic_load_int(&task->state);
} }
return MTAPI_TRUE; return MTAPI_TRUE;
......
...@@ -187,7 +187,8 @@ mtapi_task_state_t mtapi_context_taskstate_get( ...@@ -187,7 +187,8 @@ mtapi_task_state_t mtapi_context_taskstate_get(
&(task_context->thread_context->tss_id)); &(task_context->thread_context->tss_id));
if (local_context == task_context->thread_context) { if (local_context == task_context->thread_context) {
task_state = task_context->task->state; task_state = (mtapi_task_state_t)embb_atomic_load_int(
&task_context->task->state);
local_status = MTAPI_SUCCESS; local_status = MTAPI_SUCCESS;
} else { } else {
local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT; local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
......
...@@ -79,7 +79,7 @@ void embb_mtapi_task_initialize(embb_mtapi_task_t* that) { ...@@ -79,7 +79,7 @@ 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;
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;
...@@ -159,7 +159,7 @@ void embb_mtapi_task_set_state( ...@@ -159,7 +159,7 @@ void embb_mtapi_task_set_state(
assert(MTAPI_NULL != that); assert(MTAPI_NULL != that);
embb_spin_lock(&that->state_lock); embb_spin_lock(&that->state_lock);
that->state = state; embb_atomic_store_int(&that->state, state);
embb_atomic_memory_barrier(); embb_atomic_memory_barrier();
embb_spin_unlock(&that->state_lock); embb_spin_unlock(&that->state_lock);
} }
......
...@@ -66,7 +66,7 @@ struct embb_mtapi_task_struct { ...@@ -66,7 +66,7 @@ struct embb_mtapi_task_struct {
mtapi_action_hndl_t action; mtapi_action_hndl_t action;
embb_spinlock_t state_lock; embb_spinlock_t state_lock;
volatile mtapi_task_state_t state; embb_atomic_int state;
embb_atomic_unsigned_int current_instance; embb_atomic_unsigned_int current_instance;
embb_atomic_unsigned_int instances_todo; embb_atomic_unsigned_int instances_todo;
......
...@@ -107,7 +107,7 @@ void TaskTest::TestBasic() { ...@@ -107,7 +107,7 @@ void TaskTest::TestBasic() {
mtapi_action_hndl_t action; mtapi_action_hndl_t action;
mtapi_job_hndl_t job; mtapi_job_hndl_t job;
mtapi_task_hndl_t task[100]; mtapi_task_hndl_t task[100];
int ii; mtapi_uint_t ii;
embb_mtapi_log_info("running testTask...\n"); embb_mtapi_log_info("running testTask...\n");
...@@ -169,9 +169,9 @@ void TaskTest::TestBasic() { ...@@ -169,9 +169,9 @@ void TaskTest::TestBasic() {
job = mtapi_job_get(JOB_TEST_TASK, THIS_DOMAIN_ID, &status); job = mtapi_job_get(JOB_TEST_TASK, THIS_DOMAIN_ID, &status);
MTAPI_CHECK_STATUS(status); MTAPI_CHECK_STATUS(status);
for (ii = 0; ii < 100; ii++) { for (ii = 0; ii < 100u; ii++) {
status = MTAPI_ERR_UNKNOWN; status = MTAPI_ERR_UNKNOWN;
int arg = ii; mtapi_uint_t arg = ii;
task[ii] = mtapi_task_start( task[ii] = mtapi_task_start(
TASK_TEST_ID, TASK_TEST_ID,
job, job,
...@@ -187,7 +187,7 @@ void TaskTest::TestBasic() { ...@@ -187,7 +187,7 @@ void TaskTest::TestBasic() {
testDoSomethingElse(); testDoSomethingElse();
for (ii = 0; ii < 100; ii++) { for (ii = 0; ii < 100u; ii++) {
status = MTAPI_ERR_UNKNOWN; status = MTAPI_ERR_UNKNOWN;
mtapi_task_wait(task[ii], 100000, &status); mtapi_task_wait(task[ii], 100000, &status);
MTAPI_CHECK_STATUS(status); MTAPI_CHECK_STATUS(status);
...@@ -227,7 +227,7 @@ void TaskTest::TestBasic() { ...@@ -227,7 +227,7 @@ void TaskTest::TestBasic() {
MTAPI_CHECK_STATUS(status); MTAPI_CHECK_STATUS(status);
mtapi_uint_t result[kTaskInstances]; mtapi_uint_t result[kTaskInstances];
for (mtapi_uint_t ii = 0; ii < kTaskInstances; ii++) { for (ii = 0; ii < kTaskInstances; ii++) {
result[ii] = kTaskInstances + 1; result[ii] = kTaskInstances + 1;
} }
...@@ -245,7 +245,7 @@ void TaskTest::TestBasic() { ...@@ -245,7 +245,7 @@ void TaskTest::TestBasic() {
mtapi_task_wait(multiinstance_task, MTAPI_INFINITE, &status); mtapi_task_wait(multiinstance_task, MTAPI_INFINITE, &status);
MTAPI_CHECK_STATUS(status); MTAPI_CHECK_STATUS(status);
for (mtapi_uint_t ii = 0; ii < kTaskInstances; ii++) { for (ii = 0; ii < kTaskInstances; ii++) {
PT_EXPECT_EQ(result[ii], ii); PT_EXPECT_EQ(result[ii], ii);
} }
......
...@@ -26,17 +26,17 @@ GroupSourcesMSVC(test) ...@@ -26,17 +26,17 @@ GroupSourcesMSVC(test)
set (EMBB_MTAPI_NETWORK_INCLUDE_DIRS "include" "src" "test") set (EMBB_MTAPI_NETWORK_INCLUDE_DIRS "include" "src" "test")
include_directories(${EMBB_MTAPI_NETWORK_INCLUDE_DIRS} include_directories(${EMBB_MTAPI_NETWORK_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../base_c/include
${CMAKE_CURRENT_BINARY_DIR}/../base_c/include ${CMAKE_CURRENT_BINARY_DIR}/../../base_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/src ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src
) )
add_library(embb_mtapi_network_c ${EMBB_MTAPI_NETWORK_C_SOURCES} ${EMBB_MTAPI_NETWORK_C_HEADERS}) add_library(embb_mtapi_network_c ${EMBB_MTAPI_NETWORK_C_SOURCES} ${EMBB_MTAPI_NETWORK_C_HEADERS})
target_link_libraries(embb_mtapi_network_c embb_mtapi_c embb_base_c) target_link_libraries(embb_mtapi_network_c embb_mtapi_c embb_base_c)
if (BUILD_TESTS STREQUAL ON) if (BUILD_TESTS STREQUAL ON)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../partest/include)
add_executable (embb_mtapi_network_c_test ${EMBB_MTAPI_NETWORK_TEST_SOURCES}) add_executable (embb_mtapi_network_c_test ${EMBB_MTAPI_NETWORK_TEST_SOURCES})
target_link_libraries(embb_mtapi_network_c_test embb_mtapi_network_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_NETWORK_C_LIBS}) target_link_libraries(embb_mtapi_network_c_test embb_mtapi_network_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_NETWORK_C_LIBS})
CopyBin(BIN embb_mtapi_network_c_test DEST ${local_install_dir}) CopyBin(BIN embb_mtapi_network_c_test DEST ${local_install_dir})
......
...@@ -162,7 +162,8 @@ static void embb_mtapi_network_task_complete( ...@@ -162,7 +162,8 @@ static void embb_mtapi_network_task_complete(
send_buf, (int32_t)local_task->result_size); send_buf, (int32_t)local_task->result_size);
assert(err == 4); assert(err == 4);
err = embb_mtapi_network_buffer_push_back_rawdata( err = embb_mtapi_network_buffer_push_back_rawdata(
send_buf, (int32_t)local_task->result_size, local_task->result_buffer); send_buf, (int32_t)local_task->result_size,
local_task->result_buffer);
assert(err == (int)local_task->result_size); assert(err == (int)local_task->result_size);
err = embb_mtapi_network_socket_sendbuffer( err = embb_mtapi_network_socket_sendbuffer(
...@@ -303,7 +304,8 @@ static int embb_mtapi_network_thread(void * args) { ...@@ -303,7 +304,8 @@ static int embb_mtapi_network_thread(void * args) {
mtapi_taskattr_set(&task_attr, MTAPI_TASK_COMPLETE_FUNCTION, mtapi_taskattr_set(&task_attr, MTAPI_TASK_COMPLETE_FUNCTION,
func_void, 0, &local_status); func_void, 0, &local_status);
assert(local_status == MTAPI_SUCCESS); assert(local_status == MTAPI_SUCCESS);
job_hndl = mtapi_job_get((mtapi_job_id_t)job_id, (mtapi_domain_t)domain_id, &local_status); job_hndl = mtapi_job_get((mtapi_job_id_t)job_id,
(mtapi_domain_t)domain_id, &local_status);
assert(local_status == MTAPI_SUCCESS); assert(local_status == MTAPI_SUCCESS);
mtapi_task_start( mtapi_task_start(
MTAPI_TASK_ID_NONE, job_hndl, MTAPI_TASK_ID_NONE, job_hndl,
...@@ -377,7 +379,7 @@ static int embb_mtapi_network_thread(void * args) { ...@@ -377,7 +379,7 @@ static int embb_mtapi_network_thread(void * args) {
assert(err == results_size); assert(err == results_size);
local_task->error_code = (mtapi_status_t)task_status; local_task->error_code = (mtapi_status_t)task_status;
local_task->state = MTAPI_TASK_COMPLETED; embb_atomic_store_int(&local_task->state, MTAPI_TASK_COMPLETED);
embb_atomic_fetch_and_add_int(&local_action->num_tasks, -1); embb_atomic_fetch_and_add_int(&local_action->num_tasks, -1);
/* is task associated with a group? */ /* is task associated with a group? */
...@@ -530,7 +532,7 @@ static void network_task_start( ...@@ -530,7 +532,7 @@ static void network_task_start(
assert(err == send_buf->size); assert(err == send_buf->size);
embb_atomic_fetch_and_add_int(&local_action->num_tasks, 1); embb_atomic_fetch_and_add_int(&local_action->num_tasks, 1);
local_task->state = MTAPI_TASK_RUNNING; embb_atomic_store_int(&local_task->state, MTAPI_TASK_RUNNING);
embb_mtapi_network_buffer_clear(send_buf); embb_mtapi_network_buffer_clear(send_buf);
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_
#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_
#include <stdint.h> #include <stdint.h>
...@@ -43,4 +43,4 @@ void embb_mtapi_network_finalize(); ...@@ -43,4 +43,4 @@ void embb_mtapi_network_finalize();
} }
#endif #endif
#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_H_
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_
#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_
#include <stdint.h> #include <stdint.h>
...@@ -103,4 +103,4 @@ int embb_mtapi_network_buffer_pop_front_rawdata( ...@@ -103,4 +103,4 @@ int embb_mtapi_network_buffer_pop_front_rawdata(
} }
#endif #endif
#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_BUFFER_H_
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_
#define MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_
#include <stdint.h> #include <stdint.h>
#include <embb_mtapi_network_buffer.h> #include <embb_mtapi_network_buffer.h>
...@@ -101,4 +101,4 @@ int embb_mtapi_network_socket_recvbuffer_sized( ...@@ -101,4 +101,4 @@ int embb_mtapi_network_socket_recvbuffer_sized(
} }
#endif #endif
#endif // MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_SRC_EMBB_MTAPI_NETWORK_SOCKET_H_
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_
#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_
#include <partest/partest.h> #include <partest/partest.h>
...@@ -37,4 +37,4 @@ class NetworkBufferTest : public partest::TestCase { ...@@ -37,4 +37,4 @@ class NetworkBufferTest : public partest::TestCase {
void TestBasic(); void TestBasic();
}; };
#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_BUFFER_H_
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_
#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_
#include <partest/partest.h> #include <partest/partest.h>
...@@ -37,4 +37,4 @@ class NetworkSocketTest : public partest::TestCase { ...@@ -37,4 +37,4 @@ class NetworkSocketTest : public partest::TestCase {
void TestBasic(); void TestBasic();
}; };
#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_SOCKET_H_
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_
#define MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ #define MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_
#include <partest/partest.h> #include <partest/partest.h>
...@@ -37,4 +37,4 @@ class NetworkTaskTest : public partest::TestCase { ...@@ -37,4 +37,4 @@ class NetworkTaskTest : public partest::TestCase {
void TestBasic(); void TestBasic();
}; };
#endif // MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_ #endif // MTAPI_PLUGINS_C_MTAPI_NETWORK_C_TEST_EMBB_MTAPI_NETWORK_TEST_TASK_H_
...@@ -26,17 +26,17 @@ GroupSourcesMSVC(test) ...@@ -26,17 +26,17 @@ GroupSourcesMSVC(test)
set (EMBB_MTAPI_OPENCL_INCLUDE_DIRS "include" "src" "test") set (EMBB_MTAPI_OPENCL_INCLUDE_DIRS "include" "src" "test")
include_directories(${EMBB_MTAPI_OPENCL_INCLUDE_DIRS} include_directories(${EMBB_MTAPI_OPENCL_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../base_c/include
${CMAKE_CURRENT_BINARY_DIR}/../base_c/include ${CMAKE_CURRENT_BINARY_DIR}/../../base_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/include
${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/src ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src
) )
add_library(embb_mtapi_opencl_c ${EMBB_MTAPI_OPENCL_C_SOURCES} ${EMBB_MTAPI_OPENCL_C_HEADERS}) add_library(embb_mtapi_opencl_c ${EMBB_MTAPI_OPENCL_C_SOURCES} ${EMBB_MTAPI_OPENCL_C_HEADERS})
target_link_libraries(embb_mtapi_opencl_c embb_mtapi_c embb_base_c) target_link_libraries(embb_mtapi_opencl_c embb_mtapi_c embb_base_c)
if (BUILD_TESTS STREQUAL ON) if (BUILD_TESTS STREQUAL ON)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../partest/include)
add_executable (embb_mtapi_opencl_c_test ${EMBB_MTAPI_OPENCL_TEST_SOURCES}) add_executable (embb_mtapi_opencl_c_test ${EMBB_MTAPI_OPENCL_TEST_SOURCES})
target_link_libraries(embb_mtapi_opencl_c_test embb_mtapi_opencl_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_OPENCL_C_LIBS}) target_link_libraries(embb_mtapi_opencl_c_test embb_mtapi_opencl_c embb_mtapi_c partest embb_base_c ${compiler_libs} ${EMBB_MTAPI_OPENCL_C_LIBS})
CopyBin(BIN embb_mtapi_opencl_c_test DEST ${local_install_dir}) CopyBin(BIN embb_mtapi_opencl_c_test DEST ${local_install_dir})
......
...@@ -174,30 +174,40 @@ static void opencl_task_start( ...@@ -174,30 +174,40 @@ static void opencl_task_start(
err = clSetKernelArg(opencl_action->kernel, 0, sizeof(cl_mem), err = clSetKernelArg(opencl_action->kernel, 0, sizeof(cl_mem),
(const void*)&opencl_task->arguments); (const void*)&opencl_task->arguments);
err = clSetKernelArg(opencl_action->kernel, 1, sizeof(cl_int), err |= clSetKernelArg(opencl_action->kernel, 1, sizeof(cl_int),
(const void*)&opencl_task->arguments_size); (const void*)&opencl_task->arguments_size);
err = clSetKernelArg(opencl_action->kernel, 2, sizeof(cl_mem), err |= clSetKernelArg(opencl_action->kernel, 2, sizeof(cl_mem),
(const void*)&opencl_task->result_buffer); (const void*)&opencl_task->result_buffer);
err = clSetKernelArg(opencl_action->kernel, 3, sizeof(cl_int), err |= clSetKernelArg(opencl_action->kernel, 3, sizeof(cl_int),
(const void*)&opencl_task->result_buffer_size); (const void*)&opencl_task->result_buffer_size);
err = clEnqueueWriteBuffer(plugin->command_queue, err |= clEnqueueWriteBuffer(plugin->command_queue,
opencl_task->arguments, CL_FALSE, 0, opencl_task->arguments, CL_FALSE, 0,
(size_t)opencl_task->arguments_size, local_task->arguments, 0, NULL, NULL); (size_t)opencl_task->arguments_size, local_task->arguments,
err = clEnqueueNDRangeKernel(plugin->command_queue, 0, NULL, NULL);
opencl_action->kernel, 1, NULL,
&global_work_size, &opencl_action->local_work_size, 0, NULL, NULL); if (CL_SUCCESS == err) {
err = clEnqueueReadBuffer(plugin->command_queue, embb_mtapi_task_set_state(local_task, MTAPI_TASK_RUNNING);
opencl_task->result_buffer, CL_FALSE, 0,
(size_t)opencl_task->result_buffer_size, local_task->result_buffer, err |= clEnqueueNDRangeKernel(plugin->command_queue,
0, NULL, &opencl_task->kernel_finish_event); opencl_action->kernel, 1, NULL,
err = clSetEventCallback(opencl_task->kernel_finish_event, &global_work_size, &opencl_action->local_work_size, 0, NULL, NULL);
CL_COMPLETE, opencl_task_complete, opencl_task); err |= clEnqueueReadBuffer(plugin->command_queue,
err = clFlush(plugin->command_queue); opencl_task->result_buffer, CL_FALSE, 0,
(size_t)opencl_task->result_buffer_size, local_task->result_buffer,
embb_mtapi_task_set_state(local_task, MTAPI_TASK_RUNNING); 0, NULL, &opencl_task->kernel_finish_event);
local_status = MTAPI_SUCCESS; err |= clSetEventCallback(opencl_task->kernel_finish_event,
CL_COMPLETE, opencl_task_complete, opencl_task);
}
err |= clFlush(plugin->command_queue);
if (CL_SUCCESS != err) {
embb_mtapi_task_set_state(local_task, MTAPI_TASK_ERROR);
local_status = MTAPI_ERR_ACTION_FAILED;
} else {
local_status = MTAPI_SUCCESS;
}
} }
} }
} }
...@@ -259,7 +269,11 @@ void mtapi_opencl_plugin_initialize( ...@@ -259,7 +269,11 @@ void mtapi_opencl_plugin_initialize(
embb_mtapi_opencl_plugin_t * plugin = &embb_mtapi_opencl_plugin; embb_mtapi_opencl_plugin_t * plugin = &embb_mtapi_opencl_plugin;
err = embb_mtapi_opencl_link_at_runtime(); err = embb_mtapi_opencl_link_at_runtime();
if (err != 0) { if (err <= 0) {
// OpenCL not available, or wrong version
local_status = MTAPI_ERR_FUNC_NOT_IMPLEMENTED;
} else {
// all good, go ahead
err = clGetPlatformIDs(1, &plugin->platform_id, NULL); err = clGetPlatformIDs(1, &plugin->platform_id, NULL);
if (CL_SUCCESS == err) { if (CL_SUCCESS == err) {
err = clGetDeviceIDs(plugin->platform_id, CL_DEVICE_TYPE_DEFAULT, err = clGetDeviceIDs(plugin->platform_id, CL_DEVICE_TYPE_DEFAULT,
......
...@@ -263,7 +263,7 @@ int embb_mtapi_opencl_link_at_runtime() { ...@@ -263,7 +263,7 @@ int embb_mtapi_opencl_link_at_runtime() {
void * opencl_dll_handle = dlopen("libOpenCL.so", RTLD_LAZY); void * opencl_dll_handle = dlopen("libOpenCL.so", RTLD_LAZY);
#endif #endif
if (opencl_dll_handle == 0) if (opencl_dll_handle == 0)
return 0; return -1;
#ifdef EMBB_PLATFORM_COMPILER_MSVC #ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(push) #pragma warning(push)
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_
#define MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ #define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -37,4 +37,4 @@ int embb_mtapi_opencl_link_at_runtime(); ...@@ -37,4 +37,4 @@ int embb_mtapi_opencl_link_at_runtime();
} }
#endif #endif
#endif // MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_ #endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_SRC_EMBB_MTAPI_OPENCL_RUNTIMELINKER_H_
...@@ -34,5 +34,7 @@ LinkerTest::LinkerTest() { ...@@ -34,5 +34,7 @@ LinkerTest::LinkerTest() {
} }
void LinkerTest::TestBasic() { void LinkerTest::TestBasic() {
PT_EXPECT(embb_mtapi_opencl_link_at_runtime() != 0); int result = embb_mtapi_opencl_link_at_runtime();
bool success = result != 0;
PT_EXPECT(success);
} }
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_
#define MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ #define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_
#include <partest/partest.h> #include <partest/partest.h>
...@@ -37,4 +37,4 @@ class LinkerTest : public partest::TestCase { ...@@ -37,4 +37,4 @@ class LinkerTest : public partest::TestCase {
void TestBasic(); void TestBasic();
}; };
#endif // MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_ #endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_LINKER_H_
...@@ -75,6 +75,10 @@ void TaskTest::TestBasic() { ...@@ -75,6 +75,10 @@ void TaskTest::TestBasic() {
} }
mtapi_opencl_plugin_initialize(&status); mtapi_opencl_plugin_initialize(&status);
if (status == MTAPI_ERR_FUNC_NOT_IMPLEMENTED) {
// OpenCL unavailable
return;
}
MTAPI_CHECK_STATUS(status); MTAPI_CHECK_STATUS(status);
mtapi_initialize( mtapi_initialize(
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ #ifndef MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_
#define MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ #define MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_
#include <partest/partest.h> #include <partest/partest.h>
...@@ -37,4 +37,4 @@ class TaskTest : public partest::TestCase { ...@@ -37,4 +37,4 @@ class TaskTest : public partest::TestCase {
void TestBasic(); void TestBasic();
}; };
#endif // MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_ #endif // MTAPI_PLUGINS_C_MTAPI_OPENCL_C_TEST_EMBB_MTAPI_OPENCL_TEST_TASK_H_
...@@ -79,7 +79,7 @@ retval=0 ...@@ -79,7 +79,7 @@ retval=0
##Excluded files ##Excluded files
RAND_FILES=( embb_mtapi_test_group.cc embb_mtapi_test_queue.cc embb_mtapi_test_task.cc queue_test-inl.h ) RAND_FILES=( embb_mtapi_test_group.cc embb_mtapi_test_queue.cc embb_mtapi_test_task.cc queue_test-inl.h )
for project in base_c mtapi_c mtapi_network_c mtapi_opencl_c base_cpp mtapi_cpp tasks_cpp algorithms_cpp containers_cpp dataflow_cpp for project in base_c mtapi_c mtapi_plugins_c/mtapi_network_c mtapi_plugins_c/mtapi_opencl_c base_cpp mtapi_cpp tasks_cpp algorithms_cpp containers_cpp dataflow_cpp
do do
echo "-> Doing project: $project" echo "-> Doing project: $project"
dir=$d/$project dir=$d/$project
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <list> #include <list>
#include <embb/base/core_set.h> #include <embb/base/core_set.h>
#include <embb/base/mutex.h>
#include <embb/mtapi/c/mtapi.h> #include <embb/mtapi/c/mtapi.h>
#include <embb/tasks/action.h> #include <embb/tasks/action.h>
#include <embb/tasks/task.h> #include <embb/tasks/task.h>
...@@ -120,6 +121,15 @@ class Node { ...@@ -120,6 +121,15 @@ class Node {
static void Finalize(); static void Finalize();
/** /**
* Returns the number of available queues.
* \return The number of available queues
* \waitfree
*/
mtapi_uint_t GetQueueCount() const {
return queue_count_;
}
/**
* Returns the number of available cores. * Returns the number of available cores.
* \return The number of available cores * \return The number of available cores
* \waitfree * \waitfree
...@@ -218,11 +228,14 @@ class Node { ...@@ -218,11 +228,14 @@ class Node {
mtapi_size_t node_local_data_size, mtapi_size_t node_local_data_size,
mtapi_task_context_t * context); mtapi_task_context_t * context);
mtapi_uint_t queue_count_;
mtapi_uint_t core_count_; mtapi_uint_t core_count_;
mtapi_uint_t worker_thread_count_; mtapi_uint_t worker_thread_count_;
mtapi_action_hndl_t action_handle_; mtapi_action_hndl_t action_handle_;
std::list<Queue*> queues_; std::list<Queue*> queues_;
std::list<Group*> groups_; std::list<Group*> groups_;
embb::base::Spinlock queue_lock_;
embb::base::Spinlock group_lock_;
}; };
} // namespace tasks } // namespace tasks
......
...@@ -35,7 +35,7 @@ namespace tasks { ...@@ -35,7 +35,7 @@ namespace tasks {
ExecutionPolicy::ExecutionPolicy() : ExecutionPolicy::ExecutionPolicy() :
priority_(DefaultPriority) { priority_(DefaultPriority) {
#if MTAPI_CPP_AUTOMATIC_INITIALIZE #if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized Node::GetInstance(); // MTAPI has to be initialized
#endif #endif
mtapi_status_t status; mtapi_status_t status;
...@@ -48,7 +48,7 @@ ExecutionPolicy::ExecutionPolicy() : ...@@ -48,7 +48,7 @@ ExecutionPolicy::ExecutionPolicy() :
ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority)
:priority_(priority) { :priority_(priority) {
#if MTAPI_CPP_AUTOMATIC_INITIALIZE #if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized Node::GetInstance(); // MTAPI has to be initialized
#endif #endif
mtapi_status_t status; mtapi_status_t status;
...@@ -62,7 +62,7 @@ ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) ...@@ -62,7 +62,7 @@ ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority)
ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority)
:priority_(priority) { :priority_(priority) {
#if MTAPI_CPP_AUTOMATIC_INITIALIZE #if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized Node::GetInstance(); // MTAPI has to be initialized
#endif #endif
mtapi_status_t status; mtapi_status_t status;
...@@ -75,7 +75,7 @@ ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) ...@@ -75,7 +75,7 @@ ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority)
ExecutionPolicy::ExecutionPolicy(bool initial_affinity) ExecutionPolicy::ExecutionPolicy(bool initial_affinity)
:priority_(DefaultPriority) { :priority_(DefaultPriority) {
#if MTAPI_CPP_AUTOMATIC_INITIALIZE #if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized Node::GetInstance(); // MTAPI has to be initialized
#endif #endif
mtapi_status_t status; mtapi_status_t status;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <embb/base/memory_allocation.h> #include <embb/base/memory_allocation.h>
#include <embb/base/exceptions.h> #include <embb/base/exceptions.h>
#include <embb/base/thread.h>
#include <embb/tasks/tasks.h> #include <embb/tasks/tasks.h>
#if TASKS_CPP_AUTOMATIC_INITIALIZE #if TASKS_CPP_AUTOMATIC_INITIALIZE
#include <embb/base/mutex.h> #include <embb/base/mutex.h>
...@@ -74,6 +75,9 @@ Node::Node( ...@@ -74,6 +75,9 @@ Node::Node(
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"mtapi::Node could not initialize mtapi"); "mtapi::Node could not initialize mtapi");
} }
mtapi_node_get_attribute(node_id, MTAPI_NODE_MAX_QUEUES, &queue_count_,
sizeof(queue_count_), &status);
assert(MTAPI_SUCCESS == status);
core_count_ = info.hardware_concurrency; core_count_ = info.hardware_concurrency;
worker_thread_count_ = embb_core_set_count(&attr->core_affinity); worker_thread_count_ = embb_core_set_count(&attr->core_affinity);
action_handle_ = mtapi_action_create(TASKS_CPP_JOB, action_func, action_handle_ = mtapi_action_create(TASKS_CPP_JOB, action_func,
...@@ -234,7 +238,11 @@ void Node::Finalize() { ...@@ -234,7 +238,11 @@ void Node::Finalize() {
Group & Node::CreateGroup() { Group & Node::CreateGroup() {
Group * group = embb::base::Allocation::New<Group>(); Group * group = embb::base::Allocation::New<Group>();
while (!group_lock_.TryLock(1024)) {
embb::base::Thread::CurrentYield();
}
groups_.push_back(group); groups_.push_back(group);
group_lock_.Unlock();
return *group; return *group;
} }
...@@ -249,7 +257,11 @@ void Node::DestroyGroup(Group & group) { ...@@ -249,7 +257,11 @@ void Node::DestroyGroup(Group & group) {
Queue & Node::CreateQueue(mtapi_uint_t priority, bool ordered) { Queue & Node::CreateQueue(mtapi_uint_t priority, bool ordered) {
Queue * queue = embb::base::Allocation::New<Queue>(priority, ordered); Queue * queue = embb::base::Allocation::New<Queue>(priority, ordered);
while (!queue_lock_.TryLock(1024)) {
embb::base::Thread::CurrentYield();
}
queues_.push_back(queue); queues_.push_back(queue);
queue_lock_.Unlock();
return *queue; return *queue;
} }
......
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