Merge branch 'development'

# Conflicts:
#	.github/workflows/main.yml
This commit is contained in:
John Wellbelove 2020-08-09 17:25:01 +01:00
commit 987f7e49e2
28 changed files with 369 additions and 60 deletions

View File

@ -30,4 +30,32 @@ jobs:
name: Testfile
path: test/etl_tests
build-clang-9-Linux:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Build and run
run: |
export CC=clang-9
export CXX=clang++-9
cmake -D BUILD_TESTS=ON ./
make
./test/etl_tests
- name: Save artifacts
uses: actions/upload-artifact@v2
with:
name: Testfile
path: test/etl_tests
build-clang-10-osx:
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Build and run
run: |
export CC=clang
export CXX=clang++
cmake -D BUILD_TESTS=ON ./
make
./test/etl_tests

1
.gitignore vendored
View File

@ -258,3 +258,4 @@ build-test-Desktop_x86_windows_msvc2019_pe_32bit-Debug
test/vs2019/.vs
Corel Auto-Preserve
test/vs2019/Debug No Unit Tests
test/kdevelopbuild

View File

@ -61,6 +61,9 @@ namespace etl
memory_order_seq_cst
} memory_order;
//***************************************************************************
/// For all types except pointers
//***************************************************************************
template <typename T>
class atomic
{
@ -436,18 +439,21 @@ namespace etl
mutable volatile T value;
};
//***************************************************************************
/// Specialisation for pointers
//***************************************************************************
template <typename T>
class atomic<T*>
{
public:
atomic()
: value(ETL_NULLPTR)
: value(0U)
{
}
atomic(T* v)
: value(v)
: value(uintptr_t(v))
{
}
@ -540,7 +546,7 @@ namespace etl
operator T*() volatile const
{
return __sync_fetch_and_add(&value, 0);
return (T*)__sync_fetch_and_add(&value, 0);
}
// Is lock free?
@ -557,12 +563,12 @@ namespace etl
// Store
void store(T* v, etl::memory_order order = etl::memory_order_seq_cst)
{
__sync_lock_test_and_set(&value, v);
__sync_lock_test_and_set(&value, uintptr_t(v));
}
void store(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile
{
__sync_lock_test_and_set(&value, v);
__sync_lock_test_and_set(&value, uintptr_t(v));
}
// Load
@ -601,18 +607,18 @@ namespace etl
// Exchange
T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst)
{
return (T*)__sync_lock_test_and_set(&value, v);
return (T*)__sync_lock_test_and_set(&value, uintptr_t(v));
}
T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile
{
return (T*)__sync_lock_test_and_set(&value, v);
return (T*)__sync_lock_test_and_set(&value, uintptr_t(v));
}
// Compare exchange weak
bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst)
{
T* old = __sync_val_compare_and_swap(&value, expected, desired);
T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
if (old == expected)
{
@ -627,7 +633,7 @@ namespace etl
bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) volatile
{
T* old = __sync_val_compare_and_swap(&value, expected, desired);
T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
if (old == expected)
{
@ -642,7 +648,7 @@ namespace etl
bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure)
{
T* old = __sync_val_compare_and_swap(&value, expected, desired);
T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
if (old == expected)
{
@ -657,7 +663,7 @@ namespace etl
bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) volatile
{
T* old = __sync_val_compare_and_swap(&value, expected, desired);
T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired));
if (old == expected)
{
@ -740,7 +746,7 @@ namespace etl
atomic& operator =(const atomic&);
atomic& operator =(const atomic&) volatile;
mutable volatile T* value;
mutable volatile uintptr_t value;
};
typedef etl::atomic<char> atomic_char;

View File

@ -252,7 +252,7 @@ namespace etl
};
public:
//*************************************************************************
/// Iterator
//*************************************************************************
@ -377,12 +377,6 @@ namespace etl
return &p_buffer[index];
}
//***************************************************
bool operator <(const iterator& other) const
{
return ideque::distance(*this, other) > 0;
}
//***************************************************
friend iterator operator +(const iterator& lhs, difference_type offset)
{
@ -411,6 +405,38 @@ namespace etl
return !(lhs == rhs);
}
//***************************************************
friend bool operator < (const iterator& lhs, const iterator& rhs)
{
const difference_type lhs_index = lhs.get_index();
const difference_type rhs_index = rhs.get_index();
const difference_type reference_index = lhs.get_deque().begin().get_index();
const size_t buffer_size = lhs.get_deque().max_size() + 1;
const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
return lhs_distance < rhs_distance;
}
//***************************************************
friend bool operator <= (const iterator& lhs, const iterator& rhs)
{
return !(lhs > rhs);
}
//***************************************************
friend bool operator > (const iterator& lhs, const iterator& rhs)
{
return (rhs < lhs);
}
//***************************************************
friend bool operator >= (const iterator& lhs, const iterator& rhs)
{
return !(lhs < rhs);
}
//***************************************************
difference_type get_index() const
{
@ -439,6 +465,19 @@ namespace etl
private:
//***************************************************
difference_type distance(difference_type firstIndex, difference_type index_) const
{
if (index_ < firstIndex)
{
return p_deque->BUFFER_SIZE + index_ - firstIndex;
}
else
{
return index_ - firstIndex;
}
}
//***************************************************
iterator(difference_type index_, ideque& the_deque, pointer p_buffer_)
: index(index_)
@ -580,11 +619,7 @@ namespace etl
return &p_buffer[index];
}
//***************************************************
bool operator <(const const_iterator& other) const
{
return ideque::distance(*this, other) > 0;
}
//***************************************************
friend const_iterator operator +(const const_iterator& lhs, difference_type offset)
@ -614,6 +649,38 @@ namespace etl
return !(lhs == rhs);
}
//***************************************************
friend bool operator < (const const_iterator& lhs, const const_iterator& rhs)
{
const difference_type lhs_index = lhs.get_index();
const difference_type rhs_index = rhs.get_index();
const difference_type reference_index = lhs.get_deque().begin().get_index();
const size_t buffer_size = lhs.get_deque().max_size() + 1;
const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
return lhs_distance < rhs_distance;
}
//***************************************************
friend bool operator <= (const const_iterator& lhs, const const_iterator& rhs)
{
return !(lhs > rhs);
}
//***************************************************
friend bool operator > (const const_iterator& lhs, const const_iterator& rhs)
{
return (rhs < lhs);
}
//***************************************************
friend bool operator >= (const const_iterator& lhs, const const_iterator& rhs)
{
return !(lhs < rhs);
}
//***************************************************
difference_type get_index() const
{
@ -641,7 +708,7 @@ namespace etl
private:
//***************************************************
difference_type distance(difference_type firstIndex, difference_type index_)
difference_type distance(difference_type firstIndex, difference_type index_) const
{
if (index_ < firstIndex)
{

View File

@ -39,7 +39,7 @@ SOFTWARE.
#define ETL_VERSION_MAJOR 18
#define ETL_VERSION_MINOR 12
#define ETL_VERSION_PATCH 3
#define ETL_VERSION_PATCH 4
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_U16 ETL_STRINGIFY(ETL_VERSION_MAJOR) u"." ETL_STRINGIFY(ETL_VERSION_MINOR) u"." ETL_STRINGIFY(ETL_VERSION_PATCH)

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library",
"version": "18.12.3",
"version": "18.12.4",
"authors": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=18.12.3
version=18.12.4
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -1,3 +1,7 @@
===============================================================================
18.12.4
Resolve clang 9 compatibility issues.
===============================================================================
18.12.3
Resolve 0U constant ambiguity in string utility tests

View File

@ -173,7 +173,13 @@ add_executable(etl_tests
if(UNIX AND NOT APPLE)
# atomic is need on Linux with Clang
target_link_libraries(etl_tests UnitTest++ atomic)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(etl_tests UnitTest++ atomic Threads::Threads)
elseif(NOT UNIX AND APPLE)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(etl_tests UnitTest++)
else()
target_link_libraries(etl_tests UnitTest++)
endif()

View File

@ -63,6 +63,7 @@
</Compiler>
<Linker>
<Add option="-m32" />
<Add option="-lpthread" />
</Linker>
<ExtraCommands>
<Add after="${TARGET_OUTPUT_DIR}${TARGET_OUTPUT_BASENAME}" />
@ -97,6 +98,9 @@
<Add option="-D_DEBUG" />
<Add option="-DETL_NO_STL" />
</Compiler>
<Linker>
<Add option="-lpthread" />
</Linker>
<ExtraCommands>
<Add after="${TARGET_OUTPUT_DIR}${TARGET_OUTPUT_BASENAME}" />
<Mode after="always" />

View File

@ -32,6 +32,9 @@ SOFTWARE.
#include "etl/atomic/atomic_gcc_sync.h"
#include <atomic>
#include <thread>
#define REALTIME_TEST 1
namespace
{
@ -480,5 +483,44 @@ namespace
CHECK_EQUAL(compare_expected, test_expected);
CHECK_EQUAL(compare.load(), test.load());
}
//=========================================================================
#if REALTIME_TEST
etl::atomic_int32_t atomic_value = 0U;
etl::atomic<int> atomic_flag = false;
void thread1()
{
while (!atomic_flag.load());
for (int i = 0; i < 10000000; ++i)
{
++atomic_value;
}
}
void thread2()
{
while (!atomic_flag.load());
for (int i = 0; i < 10000000; ++i)
{
--atomic_value;
}
}
TEST(test_atomic_multi_thread)
{
std::thread t1(thread1);
std::thread t2(thread2);
atomic_flag.store(true);
t1.join();
t2.join();
CHECK_EQUAL(0, atomic_value.load());
}
#endif
};
}

View File

@ -32,6 +32,13 @@ SOFTWARE.
#include "etl/atomic/atomic_std.h"
#include <atomic>
#include <thread>
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif
#define REALTIME_TEST 1
namespace
{
@ -480,5 +487,61 @@ namespace
CHECK_EQUAL(compare_expected, test_expected);
CHECK_EQUAL(compare.load(), test.load());
}
//=========================================================================
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY1 SetThreadAffinityMask(GetCurrentThread(), 1)
#define FIX_PROCESSOR_AFFINITY2 SetThreadAffinityMask(GetCurrentThread(), 2)
#else
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY1
#define FIX_PROCESSOR_AFFINITY2
#endif
etl::atomic_int32_t atomic_value = 0U;
etl::atomic<int> start = false;
void thread1()
{
RAISE_THREAD_PRIORITY;
FIX_PROCESSOR_AFFINITY1;
while (!start.load());
for (int i = 0; i < 10000000; ++i)
{
++atomic_value;
}
}
void thread2()
{
RAISE_THREAD_PRIORITY;
FIX_PROCESSOR_AFFINITY2;
while (!start.load());
for (int i = 0; i < 10000000; ++i)
{
--atomic_value;
}
}
TEST(test_atomic_multi_thread)
{
std::thread t1(thread1);
std::thread t2(thread2);
start.store(true);
t1.join();
t2.join();
CHECK_EQUAL(0, atomic_value.load());
}
#endif
};
}

View File

@ -55,6 +55,7 @@ namespace
public:
Test()
: p_controller(nullptr)
{
}
@ -684,7 +685,8 @@ namespace
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
etl::callback_timer<3> controller;

View File

@ -533,11 +533,39 @@ namespace
{
DataNDC data(SIZE, N0);
DataNDC::iterator first = data.begin() + 1;
DataNDC::iterator second = data.begin() + 4;
DataNDC::iterator first = data.begin() + 1;
DataNDC::iterator second = data.begin() + 1;
DataNDC::iterator third = data.begin() + 4;
CHECK(first < second);
CHECK(first == second);
CHECK(second == first);
CHECK(!(first == third));
CHECK(!(third == first));
CHECK(!(first != second));
CHECK(!(second != first));
CHECK(first != third);
CHECK(third != first);
CHECK(!(first < second));
CHECK(!(second < first));
CHECK(first < third);
CHECK(!(third < first));
CHECK(first <= second);
CHECK(second <= first);
CHECK(first <= third);
CHECK(!(third <= first));
CHECK(!(first > second));
CHECK(!(second > first));
CHECK(!(first > third));
CHECK(third > first);
CHECK(first >= second);
CHECK(second >= first);
CHECK(!(first >= third));
CHECK(third >= first);
}
//*************************************************************************
@ -545,11 +573,39 @@ namespace
{
DataNDC data(SIZE, N0);
DataNDC::const_iterator first = data.cbegin() + 1;
DataNDC::const_iterator second = data.cbegin() + 4;
DataNDC::const_iterator first = data.begin() + 1;
DataNDC::const_iterator second = data.begin() + 1;
DataNDC::const_iterator third = data.begin() + 4;
CHECK(first < second);
CHECK(first == second);
CHECK(second == first);
CHECK(!(first == third));
CHECK(!(third == first));
CHECK(!(first != second));
CHECK(!(second != first));
CHECK(first != third);
CHECK(third != first);
CHECK(!(first < second));
CHECK(!(second < first));
CHECK(first < third);
CHECK(!(third < first));
CHECK(first <= second);
CHECK(second <= first);
CHECK(first <= third);
CHECK(!(third <= first));
CHECK(!(first > second));
CHECK(!(second > first));
CHECK(!(first > third));
CHECK(third > first);
CHECK(first >= second);
CHECK(second >= first);
CHECK(!(first >= third));
CHECK(third >= first);
}
//*************************************************************************

View File

@ -601,7 +601,8 @@ namespace
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
etl::message_timer<3> controller;

View File

@ -41,7 +41,7 @@ SOFTWARE.
#if ETL_HAS_MUTEX
#if defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif

View File

@ -41,7 +41,7 @@ SOFTWARE.
#if ETL_HAS_MUTEX
#if defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif

View File

@ -38,7 +38,7 @@ SOFTWARE.
#if ETL_HAS_ATOMIC
#if defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif

View File

@ -38,7 +38,7 @@ SOFTWARE.
#if ETL_HAS_ATOMIC
#if defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif

View File

@ -571,12 +571,13 @@ namespace
}
//*************************************************************************
#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT)
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
size_t ticks = 0;

View File

@ -589,12 +589,13 @@ namespace
}
//*************************************************************************
#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT)
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
size_t ticks = 0;

View File

@ -574,12 +574,13 @@ namespace
}
//*************************************************************************
#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT)
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
size_t ticks = 0;

View File

@ -34,7 +34,7 @@ SOFTWARE.
#include <mutex>
#include <vector>
#if defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS)
#include <Windows.h>
#endif
@ -591,12 +591,13 @@ namespace
}
//*************************************************************************
#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT)
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#if REALTIME_TEST
#if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported
#define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
#define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1);
#else
#error No thread priority modifier defined
#define RAISE_THREAD_PRIORITY
#define FIX_PROCESSOR_AFFINITY
#endif
size_t ticks = 0;

View File

@ -41,10 +41,10 @@ SOFTWARE.
namespace
{
using String = etl::string<50>;
using String = etl::string<50>;
using IString = etl::istring;
using Stream = etl::string_stream;
using Format = etl::format_spec;
using Stream = etl::string_stream;
using Format = etl::format_spec;
//***********************************
struct Custom
@ -59,7 +59,10 @@ namespace
ss << STR("X = ") << value.x << STR(" : Y = ") << value.y;
return ss;
}
}
namespace etl
{
//***********************************
std::ostream& operator << (std::ostream& os, const IString& str)
{
@ -70,7 +73,10 @@ namespace
return os;
}
}
namespace
{
SUITE(test_string_stream)
{
//*************************************************************************

View File

@ -41,10 +41,10 @@ SOFTWARE.
namespace
{
using String = etl::u16string<50>;
using String = etl::u16string<50>;
using IString = etl::iu16string;
using Stream = etl::u16string_stream;
using Format = etl::u16format_spec;
using Stream = etl::u16string_stream;
using Format = etl::u16format_spec;
//***********************************
struct Custom
@ -59,7 +59,10 @@ namespace
ss << STR("X = ") << value.x << STR(" : Y = ") << value.y;
return ss;
}
}
namespace etl
{
//***********************************
std::ostream& operator << (std::ostream& os, const IString& str)
{
@ -70,7 +73,10 @@ namespace
return os;
}
}
namespace
{
SUITE(test_string_stream)
{
//*************************************************************************

View File

@ -41,10 +41,10 @@ SOFTWARE.
namespace
{
using String = etl::u32string<50>;
using String = etl::u32string<50>;
using IString = etl::iu32string;
using Stream = etl::u32string_stream;
using Format = etl::u32format_spec;
using Stream = etl::u32string_stream;
using Format = etl::u32format_spec;
//***********************************
struct Custom
@ -59,7 +59,10 @@ namespace
ss << STR("X = ") << value.x << STR(" : Y = ") << value.y;
return ss;
}
}
namespace etl
{
//***********************************
std::ostream& operator << (std::ostream& os, const IString& str)
{
@ -70,7 +73,10 @@ namespace
return os;
}
}
namespace
{
SUITE(test_string_stream)
{
//*************************************************************************

View File

@ -59,7 +59,10 @@ namespace
ss << STR("X = ") << value.x << STR(" : Y = ") << value.y;
return ss;
}
}
namespace etl
{
//***********************************
std::ostream& operator << (std::ostream& os, const IString& str)
{
@ -70,6 +73,10 @@ namespace
return os;
}
}
namespace
{
SUITE(test_string_stream)
{