Commit 8633a17d by Marcus Winter

Merge branch 'development' into embb517_mutex_based_atomics

parents c015aa4c 560a935d
Embedded Multicore Building Blocks (EMB²) Embedded Multicore Building Blocks (EMB²)
========================================= =========================================
Version 0.4.0
-------------
### Features:
- Added consistency checking functionality to dataflow
- Added C++ wrapper for base_c logging functions
- Reworked dataflow_cpp interface for easier usage
### Changes and improvements:
- Improved network plugin with better error checking and task cancellation support
- Revised dataflow_cpp so that network token count can now be set at runtime
- Added automatic determination of token count to dataflow_cpp
- Added checks for NULL pointers in C interface functions
- Extended mtapi_info_t to conform to the standard
- Fixed CodeSonar warnings across the code base
- Changed spinlock implementation to yield every 1024 spins now
- Changed asserts on interface visible parameters to execeptions
- Enabled reuse of main thread, which is configurable via node attributes
### Bug fixes:
- Fixed problem causing low performance on the Jetson TK1 board
- Fixed bug in mtapi_c causing a task wait to hang
- Fixes issue with the AMD APP SDK in the OpenCL plugin
- Fixed problem with automatic initialization in tasks_cpp
- Fixed memory leaks in tests
### Build system:
- Removed dependency on an installed OpenCL SDK
- Moved all MTAPI plugins into folder mtapi_plugins_c
- Resolved MSVC warnings and build problem
### Documentation:
- Updated README to reflect new directory structure
- Updated Doxygen documentation of dataflow_cpp for the improved interface
- Updated tutorial and examples to show the usage of dataflow_cpp
Version 0.3.2 Version 0.3.2
------------- -------------
...@@ -63,34 +101,32 @@ Version 0.3.0 ...@@ -63,34 +101,32 @@ Version 0.3.0
------------- -------------
### Features: ### Features:
- mtapi_c: * MTAPI:
- Implemented action plugin API - Implemented action plugin API
- Implemented load balancing for distributed/heterogeneous systems - Implemented load balancing for distributed/heterogeneous systems
- Implemented OpenCL action plugin - Implemented OpenCL action plugin
- Implemented network action plugin - Implemented network action plugin
- mtapi_cpp: - Added support for distributed/heterogeneous systems
- Added support for distributed/heterogeneous systems
### Changes and improvements: ### Changes and improvements:
- mtapi_c: * Base:
- Added multi-instance task support and test
- Improved notification of worker threads
- mtapi_cpp:
- Moved interface for homogeneous systems to tasks_cpp
- base_cpp:
- Moved tick types to internal namespace and added duration typedefs - Moved tick types to internal namespace and added duration typedefs
- dataflow_cpp: * MTAPI:
- Removed spinlocks - Added multi-instance task support and test
- Simplified registration of processes (only sources need to be added) - Improved notification of worker threads
- Increased number of task queues in unit test - Moved interface for homogeneous systems to tasks_cpp
- Added assertion in unit test * Algorithms:
- Improved exception handling - Restricted partitioners to random access iterators
- Removed stray include - Added unit tests for partitioners on large ranges
- Refactored to use tasks_cpp - Refactored to use tasks_cpp
- algorithms_cpp: * Dataflow:
- Restricted partitioners to random access iterators - Removed spinlocks
- Added unit tests for partitioners on large ranges - Simplified registration of processes (only sources need to be added)
- Refactored to use tasks_cpp - Increased number of task queues in unit test
- Added assertion in unit test
- Improved exception handling
- Removed stray include
- Refactored to use tasks_cpp
### Bug fixes: ### Bug fixes:
- Fixed unit test for dataflow_cpp - Fixed unit test for dataflow_cpp
......
# Copyright (c) 2014-2016, Siemens AG. All rights reserved. # Copyright (c) 2014-2016, Siemens AG. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
# #
# 1. Redistributions of source code must retain the above copyright notice, # 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer. # this list of conditions and the following disclaimer.
# #
# 2. Redistributions in binary form must reproduce the above copyright notice, # 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation # this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution. # and/or other materials provided with the distribution.
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
...@@ -27,8 +27,8 @@ cmake_minimum_required (VERSION 2.8.9) ...@@ -27,8 +27,8 @@ cmake_minimum_required (VERSION 2.8.9)
# Version number # Version number
set (EMBB_BASE_VERSION_MAJOR 0) set (EMBB_BASE_VERSION_MAJOR 0)
set (EMBB_BASE_VERSION_MINOR 3) set (EMBB_BASE_VERSION_MINOR 4)
set (EMBB_BASE_VERSION_PATCH 2) set (EMBB_BASE_VERSION_PATCH 0)
# Fix compilation for CMake versions >= 3.1 # Fix compilation for CMake versions >= 3.1
# #
......
...@@ -44,7 +44,6 @@ namespace base { ...@@ -44,7 +44,6 @@ namespace base {
* \{ * \{
* \par Description * \par Description
* *
12345678901234567890123456789012345678901234567890123456789012345678901234567890
* The mutex concept is used for thread synchronization and provides a lock. * The mutex concept is used for thread synchronization and provides a lock.
* At any point in time, only one thread can exclusively hold the lock and * At any point in time, only one thread can exclusively hold the lock and
* the lock is held until the thread explicitly releases it. * the lock is held until the thread explicitly releases it.
......
...@@ -552,8 +552,9 @@ enum mtapi_node_attributes_enum { ...@@ -552,8 +552,9 @@ enum mtapi_node_attributes_enum {
the node */ the node */
MTAPI_NODE_MAX_ACTIONS_PER_JOB, /**< maximum number of actions in a job MTAPI_NODE_MAX_ACTIONS_PER_JOB, /**< maximum number of actions in a job
allowed by the node */ allowed by the node */
MTAPI_NODE_MAX_PRIORITIES /**< maximum number of priorities MTAPI_NODE_MAX_PRIORITIES, /**< maximum number of priorities
allowed by the node */ allowed by the node */
MTAPI_NODE_REUSE_MAIN_THREAD /**< reuse main thread as worker */
}; };
/** size of the \a MTAPI_NODE_CORE_AFFINITY attribute */ /** size of the \a MTAPI_NODE_CORE_AFFINITY attribute */
#define MTAPI_NODE_CORE_AFFINITY_SIZE sizeof(embb_core_set_t) #define MTAPI_NODE_CORE_AFFINITY_SIZE sizeof(embb_core_set_t)
...@@ -577,6 +578,8 @@ enum mtapi_node_attributes_enum { ...@@ -577,6 +578,8 @@ enum mtapi_node_attributes_enum {
#define MTAPI_NODE_MAX_ACTIONS_PER_JOB_SIZE sizeof(mtapi_uint_t) #define MTAPI_NODE_MAX_ACTIONS_PER_JOB_SIZE sizeof(mtapi_uint_t)
/** size of the \a MTAPI_NODE_MAX_PRIORITIES attribute */ /** size of the \a MTAPI_NODE_MAX_PRIORITIES attribute */
#define MTAPI_NODE_MAX_PRIORITIES_SIZE sizeof(mtapi_uint_t) #define MTAPI_NODE_MAX_PRIORITIES_SIZE sizeof(mtapi_uint_t)
/** size of the \a MTAPI_NODE_REUSE_MAIN_THREAD attribute */
#define MTAPI_NODE_REUSE_MAIN_THREAD_SIZE sizeof(mtapi_boolean_t)
/* example attribute value */ /* example attribute value */
#define MTAPI_NODE_TYPE_SMP 1 #define MTAPI_NODE_TYPE_SMP 1
...@@ -688,6 +691,8 @@ struct mtapi_node_attributes_struct { ...@@ -688,6 +691,8 @@ struct mtapi_node_attributes_struct {
mtapi_uint_t max_actions_per_job; /**< stores mtapi_uint_t max_actions_per_job; /**< stores
MTAPI_NODE_MAX_ACTIONS_PER_JOB */ MTAPI_NODE_MAX_ACTIONS_PER_JOB */
mtapi_uint_t max_priorities; /**< stores MTAPI_NODE_MAX_PRIORITIES */ mtapi_uint_t max_priorities; /**< stores MTAPI_NODE_MAX_PRIORITIES */
mtapi_boolean_t reuse_main_thread; /**< stores
MTAPI_NODE_REUSE_MAIN_THREAD */
}; };
/** /**
......
...@@ -54,6 +54,7 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize_with_node_worker_and_core( ...@@ -54,6 +54,7 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize_with_node_worker_and_core(
that->core_num = core_num; that->core_num = core_num;
that->priorities = node->attributes.max_priorities; that->priorities = node->attributes.max_priorities;
that->is_initialized = MTAPI_FALSE; that->is_initialized = MTAPI_FALSE;
that->is_main_thread = (worker_index == 0) ? node->attributes.reuse_main_thread : MTAPI_FALSE;
embb_atomic_store_int(&that->run, 0); embb_atomic_store_int(&that->run, 0);
that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate( that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate(
...@@ -121,17 +122,29 @@ mtapi_boolean_t embb_mtapi_thread_context_start( ...@@ -121,17 +122,29 @@ mtapi_boolean_t embb_mtapi_thread_context_start(
embb_core_set_add(&core_set, that->core_num); embb_core_set_add(&core_set, that->core_num);
/* create thread */ /* create thread */
err = embb_thread_create(&that->thread, &core_set, worker_func, that); if (that->is_main_thread) {
if (EMBB_SUCCESS != err) { /* reuse main thread */
embb_mtapi_log_error( that->thread = embb_thread_current();
"embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not " err = embb_tss_create(&that->tss_id);
"create thread %d on core %d\n", that->worker_index, that->core_num); if (EMBB_SUCCESS != err) {
return MTAPI_FALSE; /* report error to scheduler */
} embb_atomic_store_int(&that->run, -1);
return MTAPI_FALSE;
/* wait for worker to come up */ }
while (0 == embb_atomic_load_int(&that->run)) { embb_tss_set(&(that->tss_id), that);
embb_thread_yield(); embb_atomic_store_int(&that->run, 1);
} else {
err = embb_thread_create(&that->thread, &core_set, worker_func, that);
if (EMBB_SUCCESS != err) {
embb_mtapi_log_error(
"embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not "
"create thread %d on core %d\n", that->worker_index, that->core_num);
return MTAPI_FALSE;
}
/* wait for worker to come up */
while (0 == embb_atomic_load_int(&that->run)) {
embb_thread_yield();
}
} }
if (0 < embb_atomic_load_int(&that->run)) { if (0 < embb_atomic_load_int(&that->run)) {
...@@ -146,7 +159,9 @@ void embb_mtapi_thread_context_stop(embb_mtapi_thread_context_t* that) { ...@@ -146,7 +159,9 @@ void embb_mtapi_thread_context_stop(embb_mtapi_thread_context_t* that) {
if (0 < embb_atomic_load_int(&that->run)) { if (0 < embb_atomic_load_int(&that->run)) {
embb_atomic_store_int(&that->run, 0); embb_atomic_store_int(&that->run, 0);
embb_condition_notify_one(&that->work_available); embb_condition_notify_one(&that->work_available);
embb_thread_join(&(that->thread), &result); if (MTAPI_FALSE == that->is_main_thread) {
embb_thread_join(&(that->thread), &result);
}
} }
} }
...@@ -158,6 +173,9 @@ void embb_mtapi_thread_context_finalize(embb_mtapi_thread_context_t* that) { ...@@ -158,6 +173,9 @@ void embb_mtapi_thread_context_finalize(embb_mtapi_thread_context_t* that) {
embb_mtapi_log_trace("embb_mtapi_thread_context_finalize() called\n"); embb_mtapi_log_trace("embb_mtapi_thread_context_finalize() called\n");
if (that->is_initialized) { if (that->is_initialized) {
if (that->is_main_thread) {
embb_tss_delete(&that->tss_id);
}
embb_condition_destroy(&that->work_available); embb_condition_destroy(&that->work_available);
embb_mutex_destroy(&that->work_available_mutex); embb_mutex_destroy(&that->work_available_mutex);
} }
......
...@@ -68,6 +68,7 @@ struct embb_mtapi_thread_context_struct { ...@@ -68,6 +68,7 @@ struct embb_mtapi_thread_context_struct {
embb_atomic_int run; embb_atomic_int run;
mtapi_status_t status; mtapi_status_t status;
mtapi_boolean_t is_initialized; mtapi_boolean_t is_initialized;
mtapi_boolean_t is_main_thread;
}; };
#include <embb_mtapi_thread_context_t_fwd.h> #include <embb_mtapi_thread_context_t_fwd.h>
......
...@@ -52,6 +52,7 @@ void mtapi_nodeattr_init( ...@@ -52,6 +52,7 @@ void mtapi_nodeattr_init(
attributes->max_jobs = MTAPI_NODE_MAX_JOBS_DEFAULT; attributes->max_jobs = MTAPI_NODE_MAX_JOBS_DEFAULT;
attributes->max_actions_per_job = MTAPI_NODE_MAX_ACTIONS_PER_JOB_DEFAULT; attributes->max_actions_per_job = MTAPI_NODE_MAX_ACTIONS_PER_JOB_DEFAULT;
attributes->max_priorities = MTAPI_NODE_MAX_PRIORITIES_DEFAULT; attributes->max_priorities = MTAPI_NODE_MAX_PRIORITIES_DEFAULT;
attributes->reuse_main_thread = MTAPI_FALSE;
embb_core_set_init(&attributes->core_affinity, 1); embb_core_set_init(&attributes->core_affinity, 1);
attributes->num_cores = embb_core_set_count(&attributes->core_affinity); attributes->num_cores = embb_core_set_count(&attributes->core_affinity);
...@@ -143,6 +144,11 @@ void mtapi_nodeattr_set( ...@@ -143,6 +144,11 @@ void mtapi_nodeattr_set(
&attributes->max_priorities, attribute, attribute_size); &attributes->max_priorities, attribute, attribute_size);
break; break;
case MTAPI_NODE_REUSE_MAIN_THREAD:
local_status = embb_mtapi_attr_set_mtapi_boolean_t(
&attributes->reuse_main_thread, attribute, attribute_size);
break;
default: default:
/* attribute unknown */ /* attribute unknown */
local_status = MTAPI_ERR_ATTR_NUM; local_status = MTAPI_ERR_ATTR_NUM;
......
...@@ -53,8 +53,12 @@ void NetworkSocketTest::TestBasic() { ...@@ -53,8 +53,12 @@ void NetworkSocketTest::TestBasic() {
err = embb_mtapi_network_socket_initialize(&server_sock); err = embb_mtapi_network_socket_initialize(&server_sock);
PT_EXPECT(err != 0); PT_EXPECT(err != 0);
err = embb_mtapi_network_socket_bind_and_listen( uint16_t port = 4700;
&server_sock, "127.0.0.1", 4711, 5); do {
port++;
err = embb_mtapi_network_socket_bind_and_listen(
&server_sock, "127.0.0.1", port, 5);
} while (err == 0 && port < 4800);
PT_EXPECT(err != 0); PT_EXPECT(err != 0);
err = embb_mtapi_network_socket_select(&server_sock, 1, 1); err = embb_mtapi_network_socket_select(&server_sock, 1, 1);
...@@ -62,7 +66,7 @@ void NetworkSocketTest::TestBasic() { ...@@ -62,7 +66,7 @@ void NetworkSocketTest::TestBasic() {
err = embb_mtapi_network_socket_initialize(&client_sock); err = embb_mtapi_network_socket_initialize(&client_sock);
PT_EXPECT(err != 0); PT_EXPECT(err != 0);
err = embb_mtapi_network_socket_connect(&client_sock, "127.0.0.1", 4711); err = embb_mtapi_network_socket_connect(&client_sock, "127.0.0.1", port);
PT_EXPECT(err != 0); PT_EXPECT(err != 0);
err = embb_mtapi_network_socket_select(&server_sock, 1, -1); err = embb_mtapi_network_socket_select(&server_sock, 1, -1);
......
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