From 302cef3c8b03cd5a7e470c8834273538c2abe79f Mon Sep 17 00:00:00 2001 From: Michael Schmid Date: Mon, 12 Dec 2016 16:08:06 +0100 Subject: [PATCH] mainly worked on atomic methods, should now work with FreeRTOS --- CMakeLists.txt | 2 +- base_c/include/embb/base/c/internal/atomic/fetch_and_add.h | 15 +++++++++------ base_c/include/embb/base/c/internal/atomic/load.h | 6 ++++-- base_c/src/condition_variable.c | 19 ++++++++++++++++++- base_c/src/thread.c | 15 ++++++++++++--- base_c/src/time.c | 21 +++++++++++++++++++-- base_cpp/src/duration.cc | 4 ++-- 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e87110..3940f53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,7 @@ if(NOT __TriCore__) list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test") endif() else() - message("-- MTAPI plugins will not be build on target 'TriCore'.") + message("-- MTAPI plugins will not be build on target 'TriCore'") endif() diff --git a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h index 566daa5..0be5510 100644 --- a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h +++ b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h @@ -123,13 +123,16 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") #define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \ EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) \ (EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) { \ - \ - __asm__ __volatile__ ("add" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[new_value],%[new_value], %[pointer_to_value]\n\t" \ + EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ + result,tmp1; \ + __asm__ __volatile__ ("ld" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[result], %[pointer_to_value]\n\t" \ + "add %[tmp1],%[new_value], %[result]\n\t" \ + "st" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[pointer_to_value], %[tmp1]\n\t" \ "dsync" \ - : [new_value]"+r" (new_value) \ - : [pointer_to_value]"r" (*pointer_to_value) \ + : [result] "+r" (result), [tmp1]"+r" (tmp1), [pointer_to_value]"+m" (*pointer_to_value) \ + : [new_value]"r" (new_value) \ : "memory", "cc" ); \ - return new_value; \ + return result; \ } #else #error "No atomic fetch and store implementation found" @@ -137,7 +140,7 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") EMBB_DEFINE_FETCH_AND_ADD(1, ".b") EMBB_DEFINE_FETCH_AND_ADD(2, ".h") -EMBB_DEFINE_FETCH_AND_ADD(4, "") +EMBB_DEFINE_FETCH_AND_ADD(4, ".w") #else #error "Unknown architecture" diff --git a/base_c/include/embb/base/c/internal/atomic/load.h b/base_c/include/embb/base/c/internal/atomic/load.h index 0b24e30..469793a 100644 --- a/base_c/include/embb/base/c/internal/atomic/load.h +++ b/base_c/include/embb/base/c/internal/atomic/load.h @@ -117,7 +117,8 @@ EMBB_DEFINE_LOAD(4, "") EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value) { \ /* no fence required for loads */ \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ - __asm__ __volatile__("ld" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[result], %[value]" \ + __asm__ __volatile__("ld" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[result], %[value]\n\t" \ + "dsync"\ : [result]"=r" (result) \ : [value]"m" (*pointer_to_value) \ : "memory"); \ @@ -130,7 +131,8 @@ EMBB_DEFINE_LOAD(4, "") EMBB_DEFINE_LOAD(1, ".b") EMBB_DEFINE_LOAD(2, ".h") -EMBB_DEFINE_LOAD(4, ".w") +EMBB_DEFINE_LOAD(4, ".w") + #else #error "Unknown architecture" diff --git a/base_c/src/condition_variable.c b/base_c/src/condition_variable.c index 7ddd745..5c3396a 100644 --- a/base_c/src/condition_variable.c +++ b/base_c/src/condition_variable.c @@ -188,6 +188,8 @@ int embb_condition_destroy(embb_condition_t* condition_var) { #ifdef EMBB_PLATFORM_THREADING_RTOSTASKS +#include + int embb_condition_init(embb_condition_t* condition_var) { if (condition_var == NULL) { return EMBB_ERROR; @@ -222,7 +224,22 @@ int embb_condition_wait(embb_condition_t* condition_var, embb_mutex_t* mutex) { int embb_condition_wait_until(embb_condition_t* condition_var, embb_mutex_t* mutex, const embb_time_t* time) { - return EMBB_ERROR; /* scm34681: try something else */ + if (condition_var == NULL || mutex == NULL || time == NULL) { + return EMBB_ERROR; + } + /* Convert EMBB time to Unix time format */ + struct timespec unix_time; + unix_time.tv_sec = time->seconds; + unix_time.tv_nsec = time->nanoseconds; + int result = cond_wait_timedwait(condition_var, mutex, &unix_time); + + if (result == ETIMEDOUT) { + return EMBB_TIMEDOUT; + } + if (result != 0) { + return EMBB_ERROR; + } + return EMBB_SUCCESS; } int embb_condition_destroy(embb_condition_t* condition_var) { diff --git a/base_c/src/thread.c b/base_c/src/thread.c index be449c1..3f0f05d 100644 --- a/base_c/src/thread.c +++ b/base_c/src/thread.c @@ -362,7 +362,7 @@ embb_thread_start_t func, void *arg) { status = xTaskCreate( (TaskFunction_t) embb_internal_thread_start, // entry function "EMBB_Task", // task name (not needed) - 300, // stack size + 500, // stack size thread->embb_internal_arg, // parameters 1, // priority thread->embb_internal_handle); // thread handle @@ -397,8 +397,17 @@ int embb_thread_join(embb_thread_t* thread, int *result_code) { if (thread == NULL) { return EMBB_ERROR; } - int status = 0; - while(thread->embb_internal_handle != NULL && status++ < 10000); // scm34681: rework + + TickType_t xTicksToWait = 0xFFFFFFFF; + TimeOut_t xTimeOut; + + vTaskSetTimeOutState( &xTimeOut ); + + while(thread->embb_internal_handle != NULL) { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE ) { + break; + } + } if (thread->embb_internal_arg != NULL) { if (result_code != NULL) { diff --git a/base_c/src/time.c b/base_c/src/time.c index 1b9171b..37d5251 100644 --- a/base_c/src/time.c +++ b/base_c/src/time.c @@ -105,10 +105,27 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { #ifdef EMBB_PLATFORM_THREADING_RTOSTASKS +#include + int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { + if (time == NULL || duration == NULL) { + return EMBB_ERROR; + } + + //scm34681: implement correctly for different ticks/second + //scm34681: check for overflow of tick count + uint32_t ticks_count = xTaskGetTickCount(); + time->seconds = ticks_count / 1000; + time->nanoseconds = (ticks_count % 1000) * 1000000; + + if (time->seconds + duration->seconds > EMBB_TIME_MAX_SECONDS) { + return EMBB_OVERFLOW; + } + + time->seconds += duration->seconds; + time->nanoseconds += duration->nanoseconds; - return EMBB_ERROR; // scm34681: try something else - + return EMBB_SUCCESS; } #endif /* EMBB_PLATFORM_THREADING_RTOSTASKS */ \ No newline at end of file diff --git a/base_cpp/src/duration.cc b/base_cpp/src/duration.cc index fd146e0..11bc3df 100644 --- a/base_cpp/src/duration.cc +++ b/base_cpp/src/duration.cc @@ -141,7 +141,7 @@ unsigned long long internal::Microseconds::Max() { #if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000 return ULLONG_MAX; #else - return EMBB_DURATION_MAX_SECONDS * 1000000; // sc: warning integer overflow + return EMBB_DURATION_MAX_SECONDS * 1000000ull; // scm34681: warning integer overflow #endif } @@ -172,7 +172,7 @@ unsigned long long internal::Nanoseconds::Max() { #if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000000 return ULLONG_MAX; #else - return EMBB_DURATION_MAX_SECONDS * 1000000000; + return EMBB_DURATION_MAX_SECONDS * 1000000000ull; #endif } -- libgit2 0.26.0