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