Commit 3e00afd6 by Marcus Winter

base_c: added thread priority implementation for linux

mtapi_c: adapted to new thread interface
parent 2cacd20f
......@@ -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
......
......@@ -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 <sys/sysinfo.h> /* Used to get number of processors */
#endif /* EMBB_PLATFORM_HAS_HEADER_SYSINFO */
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
/**
* 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 */
......@@ -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();
......
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