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(); ...@@ -133,7 +133,7 @@ void embb_thread_yield();
* Creates and runs a thread. * Creates and runs a thread.
* *
* \pre The given thread is not running and has not yet been successfully * \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. * \post On success, the given thread has started to run.
* \return EMBB_SUCCESS if the thread could be created. \n * \return EMBB_SUCCESS if the thread could be created. \n
* EMBB_NOMEM if there was insufficient amount of memory \n * EMBB_NOMEM if there was insufficient amount of memory \n
...@@ -158,6 +158,36 @@ int embb_thread_create( ...@@ -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. * Waits until the given thread has finished execution.
* *
* \pre The given thread has been successfully created using * \pre The given thread has been successfully created using
...@@ -190,11 +220,6 @@ int embb_thread_equal( ...@@ -190,11 +220,6 @@ int embb_thread_equal(
/**< [IN] Second thread (right-hand side of equality sign) */ /**< [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 #ifdef __cplusplus
} /* Close extern "C" { */ } /* Close extern "C" { */
#endif #endif
......
...@@ -40,6 +40,15 @@ void embb_thread_set_max_count(unsigned int max) { ...@@ -40,6 +40,15 @@ void embb_thread_set_max_count(unsigned int max) {
embb_internal_thread_index_set_max(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 #ifdef EMBB_PLATFORM_THREADING_WINTHREADS
/** /**
...@@ -78,8 +87,12 @@ void embb_thread_yield() { ...@@ -78,8 +87,12 @@ void embb_thread_yield() {
SwitchToThread(); SwitchToThread();
} }
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, int embb_thread_create_with_priority(
embb_thread_start_t func, void *arg) { 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) { if (thread == NULL) {
return EMBB_ERROR; return EMBB_ERROR;
} }
...@@ -121,6 +134,36 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, ...@@ -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; return EMBB_SUCCESS;
} }
...@@ -168,37 +211,6 @@ int embb_thread_set_priority( ...@@ -168,37 +211,6 @@ int embb_thread_set_priority(
embb_thread_t* thread, embb_thread_t* thread,
embb_thread_priority_t priority 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 */ #endif /* EMBB_PLATFORM_THREADING_WINTHREADS */
...@@ -217,12 +229,18 @@ int embb_thread_set_priority( ...@@ -217,12 +229,18 @@ int embb_thread_set_priority(
#include <sys/sysinfo.h> /* Used to get number of processors */ #include <sys/sysinfo.h> /* Used to get number of processors */
#endif /* EMBB_PLATFORM_HAS_HEADER_SYSINFO */ #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 * Used to wrap client thread start function and argument when calling internal
* thread start function embb_internal_thread_start. * thread start function embb_internal_thread_start.
*/ */
typedef struct embb_internal_thread_arg_t { typedef struct embb_internal_thread_arg_t {
embb_thread_start_t func; embb_thread_start_t func;
int priority;
void* arg; void* arg;
int result; int result;
} embb_internal_thread_arg_t; } embb_internal_thread_arg_t;
...@@ -234,6 +252,10 @@ typedef struct embb_internal_thread_arg_t { ...@@ -234,6 +252,10 @@ typedef struct embb_internal_thread_arg_t {
* argument. * argument.
*/ */
void* embb_internal_thread_start(void* internalArg) { 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)->result =
((embb_internal_thread_arg_t*)internalArg)->func( ((embb_internal_thread_arg_t*)internalArg)->func(
((struct embb_internal_thread_arg_t*)internalArg)->arg); ((struct embb_internal_thread_arg_t*)internalArg)->arg);
...@@ -251,8 +273,12 @@ void embb_thread_yield() { ...@@ -251,8 +273,12 @@ void embb_thread_yield() {
pthread_yield(); pthread_yield();
} }
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, int embb_thread_create_with_priority(
embb_thread_start_t func, void* arg) { 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) { if (thread == NULL) {
return EMBB_ERROR; return EMBB_ERROR;
} }
...@@ -298,6 +324,31 @@ int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, ...@@ -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->func = func;
thread->embb_internal_arg->arg = arg; 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( status = pthread_create(
&(thread->embb_internal_handle), /* pthread handle */ &(thread->embb_internal_handle), /* pthread handle */
&attr, /* additional attributes, &attr, /* additional attributes,
...@@ -336,12 +387,4 @@ int embb_thread_equal(const embb_thread_t* lhs, const embb_thread_t* rhs) { ...@@ -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); 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 */ #endif /* EMBB_PLATFORM_THREADING_POSIXTHREADS */
...@@ -137,14 +137,14 @@ mtapi_boolean_t embb_mtapi_thread_context_start( ...@@ -137,14 +137,14 @@ mtapi_boolean_t embb_mtapi_thread_context_start(
embb_tss_set(&(that->tss_id), that); embb_tss_set(&(that->tss_id), that);
embb_atomic_store_int(&that->run, 1); embb_atomic_store_int(&that->run, 1);
} else { } 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) { if (EMBB_SUCCESS != err) {
embb_mtapi_log_error( embb_mtapi_log_error(
"embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not " "embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not "
"create thread %d on core %d\n", that->worker_index, that->core_num); "create thread %d on core %d\n", that->worker_index, that->core_num);
return MTAPI_FALSE; return MTAPI_FALSE;
} }
embb_thread_set_priority(&that->thread, that->thread_priority);
/* wait for worker to come up */ /* wait for worker to come up */
while (0 == embb_atomic_load_int(&that->run)) { while (0 == embb_atomic_load_int(&that->run)) {
embb_thread_yield(); 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