diff --git a/base_c/include/embb/base/c/thread.h b/base_c/include/embb/base/c/thread.h index 98f84ab..e33c128 100644 --- a/base_c/include/embb/base/c/thread.h +++ b/base_c/include/embb/base/c/thread.h @@ -133,7 +133,7 @@ void embb_thread_yield(); * Creates and runs a thread. * * \pre The given thread is not running and has not yet been successfully - joined. + * joined. * \post On success, the given thread has started to run. * \return EMBB_SUCCESS if the thread could be created. \n * EMBB_NOMEM if there was insufficient amount of memory \n @@ -158,6 +158,36 @@ int embb_thread_create( ); /** + * Creates and runs a thread. + * + * \pre The given thread is not running and has not yet been successfully + * joined. + * \post On success, the given thread has started to run. + * \return EMBB_SUCCESS if the thread could be created. \n + * EMBB_NOMEM if there was insufficient amount of memory \n + * EMBB_ERROR otherwise. + * \memory Dynamically allocates a small constant amount of memory to store the + * function and argument pointers. This memory is freed when the thread + * is joined. + * \notthreadsafe + * \see embb_thread_join() + */ +int embb_thread_create_with_priority( + embb_thread_t* thread, + /**< [OUT] Thread to be run */ + const embb_core_set_t* core_set, + /**< [IN] Set of cores on which the thread shall be executed. Can be NULL to + indicate automatic thread scheduling by the OS. */ + embb_thread_priority_t priority, + /**< [IN] Priority to run the thread at. */ + embb_thread_start_t function, + /**< [IN] Function which is executed by the thread when started. Has to be of + type embb_thread_start_t. */ + void* arg + /**< [IN/OUT] Argument to thread start function. Can be NULL. */ + ); + +/** * Waits until the given thread has finished execution. * * \pre The given thread has been successfully created using @@ -190,11 +220,6 @@ int embb_thread_equal( /**< [IN] Second thread (right-hand side of equality sign) */ ); -int embb_thread_set_priority( - embb_thread_t* thread, - embb_thread_priority_t priority - ); - #ifdef __cplusplus } /* Close extern "C" { */ #endif diff --git a/base_c/src/thread.c b/base_c/src/thread.c index 1c99304..19d7111 100644 --- a/base_c/src/thread.c +++ b/base_c/src/thread.c @@ -40,6 +40,15 @@ void embb_thread_set_max_count(unsigned int max) { embb_internal_thread_index_set_max(max); } +int embb_thread_create( + embb_thread_t* thread, + const embb_core_set_t* core_set, + embb_thread_start_t func, + void *arg) { + return embb_thread_create_with_priority(thread, core_set, + EMBB_THREAD_PRIORITY_NORMAL, func, arg); +} + #ifdef EMBB_PLATFORM_THREADING_WINTHREADS /** @@ -78,8 +87,12 @@ void embb_thread_yield() { SwitchToThread(); } -int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, - embb_thread_start_t func, void *arg) { +int embb_thread_create_with_priority( + embb_thread_t* thread, + const embb_core_set_t* core_set, + embb_thread_priority_t priority, + embb_thread_start_t func, + void *arg) { if (thread == NULL) { return EMBB_ERROR; } @@ -121,6 +134,36 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, } } + int internal_priority; + switch (priority) { + case EMBB_THREAD_PRIORITY_IDLE: + internal_priority = THREAD_PRIORITY_IDLE; + break; + case EMBB_THREAD_PRIORITY_LOWEST: + internal_priority = THREAD_PRIORITY_LOWEST; + break; + case EMBB_THREAD_PRIORITY_BELOW_NORMAL: + internal_priority = THREAD_PRIORITY_BELOW_NORMAL; + break; + case EMBB_THREAD_PRIORITY_ABOVE_NORMAL: + internal_priority = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case EMBB_THREAD_PRIORITY_HIGHEST: + internal_priority = THREAD_PRIORITY_HIGHEST; + break; + case EMBB_THREAD_PRIORITY_TIME_CRITICAL: + internal_priority = THREAD_PRIORITY_TIME_CRITICAL; + break; + case EMBB_THREAD_PRIORITY_NORMAL: + default: + internal_priority = THREAD_PRIORITY_NORMAL; + break; + } + BOOL result = SetThreadPriority(thread->embb_internal_handle, internal_priority); + if (result == 0) { + return EMBB_ERROR; + } + return EMBB_SUCCESS; } @@ -168,37 +211,6 @@ int embb_thread_set_priority( embb_thread_t* thread, embb_thread_priority_t priority ) { - int internal_priority; - switch (priority) { - case EMBB_THREAD_PRIORITY_IDLE: - internal_priority = THREAD_PRIORITY_IDLE; - break; - case EMBB_THREAD_PRIORITY_LOWEST: - internal_priority = THREAD_PRIORITY_LOWEST; - break; - case EMBB_THREAD_PRIORITY_BELOW_NORMAL: - internal_priority = THREAD_PRIORITY_BELOW_NORMAL; - break; - case EMBB_THREAD_PRIORITY_ABOVE_NORMAL: - internal_priority = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case EMBB_THREAD_PRIORITY_HIGHEST: - internal_priority = THREAD_PRIORITY_HIGHEST; - break; - case EMBB_THREAD_PRIORITY_TIME_CRITICAL: - internal_priority = THREAD_PRIORITY_TIME_CRITICAL; - break; - case EMBB_THREAD_PRIORITY_NORMAL: - default: - internal_priority = THREAD_PRIORITY_NORMAL; - break; - } - BOOL result = SetThreadPriority(thread->embb_internal_handle, internal_priority); - if (result != 0) { - return EMBB_SUCCESS; - } else { - return EMBB_ERROR; - } } #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */ @@ -217,12 +229,18 @@ int embb_thread_set_priority( #include /* Used to get number of processors */ #endif /* EMBB_PLATFORM_HAS_HEADER_SYSINFO */ +#include +#include +#include +#include + /** * Used to wrap client thread start function and argument when calling internal * thread start function embb_internal_thread_start. */ typedef struct embb_internal_thread_arg_t { embb_thread_start_t func; + int priority; void* arg; int result; } embb_internal_thread_arg_t; @@ -234,6 +252,10 @@ typedef struct embb_internal_thread_arg_t { * argument. */ void* embb_internal_thread_start(void* internalArg) { + pid_t tid; + tid = syscall(SYS_gettid); + setpriority(PRIO_PROCESS, tid, + ((embb_internal_thread_arg_t*)internalArg)->priority); ((embb_internal_thread_arg_t*)internalArg)->result = ((embb_internal_thread_arg_t*)internalArg)->func( ((struct embb_internal_thread_arg_t*)internalArg)->arg); @@ -251,8 +273,12 @@ void embb_thread_yield() { pthread_yield(); } -int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, - embb_thread_start_t func, void* arg) { +int embb_thread_create_with_priority( + embb_thread_t* thread, + const embb_core_set_t* core_set, + embb_thread_priority_t priority, + embb_thread_start_t func, + void* arg) { if (thread == NULL) { return EMBB_ERROR; } @@ -298,6 +324,31 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, thread->embb_internal_arg->func = func; thread->embb_internal_arg->arg = arg; + switch (priority) { + case EMBB_THREAD_PRIORITY_IDLE: + thread->embb_internal_arg->priority = 19; + break; + case EMBB_THREAD_PRIORITY_LOWEST: + thread->embb_internal_arg->priority = 2; + break; + case EMBB_THREAD_PRIORITY_BELOW_NORMAL: + thread->embb_internal_arg->priority = 1; + break; + case EMBB_THREAD_PRIORITY_ABOVE_NORMAL: + thread->embb_internal_arg->priority = -1; + break; + case EMBB_THREAD_PRIORITY_HIGHEST: + thread->embb_internal_arg->priority = -2; + break; + case EMBB_THREAD_PRIORITY_TIME_CRITICAL: + thread->embb_internal_arg->priority = -19; + break; + case EMBB_THREAD_PRIORITY_NORMAL: + default: + thread->embb_internal_arg->priority = 0; + break; + } + status = pthread_create( &(thread->embb_internal_handle), /* pthread handle */ &attr, /* additional attributes, @@ -336,12 +387,4 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) { return pthread_equal(lhs->embb_internal_handle, rhs->embb_internal_handle); } -int embb_thread_set_priority( - embb_thread_t* /*thread*/, - embb_thread_priority_t /*priority*/ -) { - // not implemented yet - return EMBB_ERROR; -} - #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */ diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.c b/mtapi_c/src/embb_mtapi_thread_context_t.c index 5f64104..9645461 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.c +++ b/mtapi_c/src/embb_mtapi_thread_context_t.c @@ -137,14 +137,14 @@ mtapi_boolean_t embb_mtapi_thread_context_start( embb_tss_set(&(that->tss_id), that); embb_atomic_store_int(&that->run, 1); } else { - err = embb_thread_create(&that->thread, &core_set, worker_func, that); + err = embb_thread_create_with_priority( + &that->thread, &core_set, that->thread_priority, 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; } - embb_thread_set_priority(&that->thread, that->thread_priority); /* wait for worker to come up */ while (0 == embb_atomic_load_int(&that->run)) { embb_thread_yield();