Commit 302cef3c by Michael Schmid

mainly worked on atomic methods, should now work with FreeRTOS

parent 1218ddc3
...@@ -151,7 +151,7 @@ if(NOT __TriCore__) ...@@ -151,7 +151,7 @@ if(NOT __TriCore__)
list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test") list(APPEND EXPECTED_EMBB_TEST_EXECUTABLES "embb_mtapi_opencl_c_test")
endif() endif()
else() else()
message("-- MTAPI plugins will not be build on target 'TriCore'.") message("-- MTAPI plugins will not be build on target 'TriCore'")
endif() endif()
......
...@@ -123,13 +123,16 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") ...@@ -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) \ #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_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) { \ (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) { \
\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
__asm__ __volatile__ ("add" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[new_value],%[new_value], %[pointer_to_value]\n\t" \ 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" \ "dsync" \
: [new_value]"+r" (new_value) \ : [result] "+r" (result), [tmp1]"+r" (tmp1), [pointer_to_value]"+m" (*pointer_to_value) \
: [pointer_to_value]"r" (*pointer_to_value) \ : [new_value]"r" (new_value) \
: "memory", "cc" ); \ : "memory", "cc" ); \
return new_value; \ return result; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
...@@ -137,7 +140,7 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "") ...@@ -137,7 +140,7 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "")
EMBB_DEFINE_FETCH_AND_ADD(1, ".b") EMBB_DEFINE_FETCH_AND_ADD(1, ".b")
EMBB_DEFINE_FETCH_AND_ADD(2, ".h") EMBB_DEFINE_FETCH_AND_ADD(2, ".h")
EMBB_DEFINE_FETCH_AND_ADD(4, "") EMBB_DEFINE_FETCH_AND_ADD(4, ".w")
#else #else
#error "Unknown architecture" #error "Unknown architecture"
......
...@@ -117,7 +117,8 @@ EMBB_DEFINE_LOAD(4, "") ...@@ -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) { \ 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 */ \ /* no fence required for loads */ \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) result; \ 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) \ : [result]"=r" (result) \
: [value]"m" (*pointer_to_value) \ : [value]"m" (*pointer_to_value) \
: "memory"); \ : "memory"); \
...@@ -130,7 +131,8 @@ EMBB_DEFINE_LOAD(4, "") ...@@ -130,7 +131,8 @@ EMBB_DEFINE_LOAD(4, "")
EMBB_DEFINE_LOAD(1, ".b") EMBB_DEFINE_LOAD(1, ".b")
EMBB_DEFINE_LOAD(2, ".h") EMBB_DEFINE_LOAD(2, ".h")
EMBB_DEFINE_LOAD(4, ".w") EMBB_DEFINE_LOAD(4, ".w")
#else #else
#error "Unknown architecture" #error "Unknown architecture"
......
...@@ -188,6 +188,8 @@ int embb_condition_destroy(embb_condition_t* condition_var) { ...@@ -188,6 +188,8 @@ int embb_condition_destroy(embb_condition_t* condition_var) {
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS #ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#include <errno.h>
int embb_condition_init(embb_condition_t* condition_var) { int embb_condition_init(embb_condition_t* condition_var) {
if (condition_var == NULL) { if (condition_var == NULL) {
return EMBB_ERROR; return EMBB_ERROR;
...@@ -222,7 +224,22 @@ int embb_condition_wait(embb_condition_t* condition_var, embb_mutex_t* mutex) { ...@@ -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, int embb_condition_wait_until(embb_condition_t* condition_var,
embb_mutex_t* mutex, const embb_time_t* time) { 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) { int embb_condition_destroy(embb_condition_t* condition_var) {
......
...@@ -362,7 +362,7 @@ embb_thread_start_t func, void *arg) { ...@@ -362,7 +362,7 @@ embb_thread_start_t func, void *arg) {
status = xTaskCreate( (TaskFunction_t) embb_internal_thread_start, // entry function status = xTaskCreate( (TaskFunction_t) embb_internal_thread_start, // entry function
"EMBB_Task", // task name (not needed) "EMBB_Task", // task name (not needed)
300, // stack size 500, // stack size
thread->embb_internal_arg, // parameters thread->embb_internal_arg, // parameters
1, // priority 1, // priority
thread->embb_internal_handle); // thread handle thread->embb_internal_handle); // thread handle
...@@ -397,8 +397,17 @@ int embb_thread_join(embb_thread_t* thread, int *result_code) { ...@@ -397,8 +397,17 @@ int embb_thread_join(embb_thread_t* thread, int *result_code) {
if (thread == NULL) { if (thread == NULL) {
return EMBB_ERROR; 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 (thread->embb_internal_arg != NULL) {
if (result_code != NULL) { if (result_code != NULL) {
......
...@@ -105,10 +105,27 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { ...@@ -105,10 +105,27 @@ int embb_time_in(embb_time_t* time, const embb_duration_t* duration) {
#ifdef EMBB_PLATFORM_THREADING_RTOSTASKS #ifdef EMBB_PLATFORM_THREADING_RTOSTASKS
#include <FreeRTOS/task.h>
int embb_time_in(embb_time_t* time, const embb_duration_t* duration) { 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 */ #endif /* EMBB_PLATFORM_THREADING_RTOSTASKS */
\ No newline at end of file
...@@ -141,7 +141,7 @@ unsigned long long internal::Microseconds::Max() { ...@@ -141,7 +141,7 @@ unsigned long long internal::Microseconds::Max() {
#if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000 #if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000
return ULLONG_MAX; return ULLONG_MAX;
#else #else
return EMBB_DURATION_MAX_SECONDS * 1000000; // sc: warning integer overflow return EMBB_DURATION_MAX_SECONDS * 1000000ull; // scm34681: warning integer overflow
#endif #endif
} }
...@@ -172,7 +172,7 @@ unsigned long long internal::Nanoseconds::Max() { ...@@ -172,7 +172,7 @@ unsigned long long internal::Nanoseconds::Max() {
#if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000000 #if EMBB_DURATION_MAX_SECONDS < ULLONG_MAX / 1000000000
return ULLONG_MAX; return ULLONG_MAX;
#else #else
return EMBB_DURATION_MAX_SECONDS * 1000000000; return EMBB_DURATION_MAX_SECONDS * 1000000000ull;
#endif #endif
} }
......
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