diff options
Diffstat (limited to 'src/lib/eina/eina_thread.c')
-rw-r--r-- | src/lib/eina/eina_thread.c | 295 |
1 files changed, 6 insertions, 289 deletions
diff --git a/src/lib/eina/eina_thread.c b/src/lib/eina/eina_thread.c index 75623edb0a..abb04a1bf5 100644 --- a/src/lib/eina/eina_thread.c +++ b/src/lib/eina/eina_thread.c @@ -20,284 +20,15 @@ # include "config.h" #endif -#include <stdlib.h> +#include <stddef.h> -#include "eina_config.h" -#include "eina_lock.h" /* it will include pthread.h with proper flags */ -#include "eina_thread.h" -#include "eina_sched.h" -#include "eina_cpu.h" - -/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ -#include "eina_safety_checks.h" - -#include "eina_debug_private.h" - -#include <pthread.h> -#include <errno.h> -#ifndef _WIN32 -# include <signal.h> -#endif -# include <string.h> - -#if defined(EINA_HAVE_PTHREAD_AFFINITY) || defined(EINA_HAVE_PTHREAD_SETNAME) -#ifndef __linux__ -#include <pthread_np.h> -#define cpu_set_t cpuset_t -#endif -#endif - -static inline void * -_eina_thread_join(Eina_Thread t) -{ - void *ret = NULL; - int err = pthread_join((pthread_t)t, &ret); - - if (err == 0) return ret; - return NULL; -} - -static inline Eina_Bool -_eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), void *data) -{ - int err; - pthread_attr_t attr; -#ifndef _WIN32 - sigset_t oldset, newset; -#endif - - if (pthread_attr_init(&attr) != 0) - { - return EINA_FALSE; - } - if (affinity >= 0) - { -#ifdef EINA_HAVE_PTHREAD_AFFINITY - cpu_set_t cpu; - - CPU_ZERO(&cpu); - CPU_SET(affinity, &cpu); - pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); -#endif - } - - /* setup initial locks */ -#ifndef _WIN32 - sigemptyset(&newset); - sigaddset(&newset, SIGPIPE); - sigaddset(&newset, SIGALRM); - sigaddset(&newset, SIGCHLD); - sigaddset(&newset, SIGUSR1); - sigaddset(&newset, SIGUSR2); - sigaddset(&newset, SIGHUP); - sigaddset(&newset, SIGQUIT); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGTERM); -# ifdef SIGPWR - sigaddset(&newset, SIGPWR); -# endif - pthread_sigmask(SIG_BLOCK, &newset, &oldset); -#endif - err = pthread_create((pthread_t *)t, &attr, func, data); -#ifndef _WIN32 - pthread_sigmask(SIG_SETMASK, &oldset, NULL); -#endif - pthread_attr_destroy(&attr); - - if (err == 0) return EINA_TRUE; - - return EINA_FALSE; -} - -static inline Eina_Bool -_eina_thread_equal(Eina_Thread t1, Eina_Thread t2) -{ - return pthread_equal((pthread_t)t1, (pthread_t)t2); -} - -static inline Eina_Thread -_eina_thread_self(void) -{ - return (Eina_Thread)pthread_self(); -} - - -typedef struct _Eina_Thread_Call Eina_Thread_Call; -struct _Eina_Thread_Call -{ - Eina_Thread_Cb func; - const void *data; - - Eina_Thread_Priority prio; - int affinity; -}; - -static void * -_eina_internal_call(void *context) -{ - Eina_Thread_Call *c = context; - void *r; - pthread_t self; - - // Default this thread to not cancellable as per Eina documentation - eina_thread_cancellable_set(EINA_FALSE, NULL); - - EINA_THREAD_CLEANUP_PUSH(free, c); - - self = pthread_self(); - - if (c->prio == EINA_THREAD_IDLE) - { - struct sched_param params; - int min; -#ifdef SCHED_IDLE - int pol = SCHED_IDLE; -#else - int pol; - pthread_getschedparam(self, &pol, ¶ms); +#ifdef HAVE_PTHREAD_H +# include <pthread.h> #endif - min = sched_get_priority_min(pol); - params.sched_priority = min; - pthread_setschedparam(self, pol, ¶ms); - } - else if (c->prio == EINA_THREAD_BACKGROUND) - { - struct sched_param params; - int min, max; -#ifdef SCHED_BATCH - int pol = SCHED_BATCH; -#else - int pol; - pthread_getschedparam(self, &pol, ¶ms); -#endif - min = sched_get_priority_min(pol); - max = sched_get_priority_max(pol); - params.sched_priority = (max - min) / 2; - pthread_setschedparam(self, pol, ¶ms); - } -// do nothing for normal -// else if (c->prio == EINA_THREAD_NORMAL) -// { -// } - else if (c->prio == EINA_THREAD_URGENT) - { - struct sched_param params; - int max, pol; - - pthread_getschedparam(self, &pol, ¶ms); - max = sched_get_priority_max(pol); - params.sched_priority += 5; - if (params.sched_priority > max) params.sched_priority = max; - pthread_setschedparam(self, pol, ¶ms); - } - - _eina_debug_thread_add(&self); - EINA_THREAD_CLEANUP_PUSH(_eina_debug_thread_del, &self); - r = c->func((void*) c->data, eina_thread_self()); - EINA_THREAD_CLEANUP_POP(EINA_TRUE); - EINA_THREAD_CLEANUP_POP(EINA_TRUE); - return r; -} - -EINA_API Eina_Thread -eina_thread_self(void) -{ - return _eina_thread_self(); -} - -EINA_API Eina_Bool -eina_thread_equal(Eina_Thread t1, Eina_Thread t2) -{ - return !!_eina_thread_equal(t1, t2); -} - -EINA_API Eina_Bool -eina_thread_create(Eina_Thread *t, - Eina_Thread_Priority prio, int affinity, - Eina_Thread_Cb func, const void *data) -{ - Eina_Thread_Call *c; - - EINA_SAFETY_ON_NULL_RETURN_VAL(t, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE); - - c = malloc(sizeof (Eina_Thread_Call)); - if (!c) return EINA_FALSE; - - c->func = func; - c->data = data; - c->prio = prio; - c->affinity = affinity; - - // valgrind complains c is lost - but it's not - it is handed to the - // child thread to be freed when c->func returns in _eina_internal_call(). - if (_eina_thread_create(t, affinity, _eina_internal_call, c)) - return EINA_TRUE; - - free(c); - return EINA_FALSE; -} - -EINA_API void * -eina_thread_join(Eina_Thread t) -{ - return _eina_thread_join(t); -} - -EINA_API Eina_Bool -eina_thread_name_set(Eina_Thread t, const char *name) -{ -#ifdef EINA_HAVE_PTHREAD_SETNAME - char buf[16]; - if (name) - { - strncpy(buf, name, 15); - buf[15] = 0; - } - else buf[0] = 0; -#ifndef __linux__ - pthread_set_name_np((pthread_t)t, buf); - return EINA_TRUE; -#else - if (pthread_setname_np((pthread_t)t, buf) == 0) return EINA_TRUE; -#endif -#else - (void)t; - (void)name; -#endif - return EINA_FALSE; -} - -EINA_API Eina_Bool -eina_thread_cancel(Eina_Thread t) -{ - if (!t) return EINA_FALSE; - return pthread_cancel((pthread_t)t) == 0; -} - -EINA_API Eina_Bool -eina_thread_cancellable_set(Eina_Bool cancellable, Eina_Bool *was_cancellable) -{ - int state = cancellable ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE; - int old = 0; - int r; - - /* enforce deferred in case users changed to asynchronous themselves */ - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old); - - r = pthread_setcancelstate(state, &old); - if (was_cancellable && r == 0) - *was_cancellable = (old == PTHREAD_CANCEL_ENABLE); - - return r == 0; -} - -EINA_API void -eina_thread_cancel_checkpoint(void) -{ - pthread_testcancel(); -} +#include "eina_types.h" +#include "eina_config.h" +#include "eina_thread.h" EINA_API void * eina_thread_cancellable_run(Eina_Thread_Cancellable_Run_Cb cb, Eina_Free_Cb cleanup_cb, void *data) @@ -312,17 +43,3 @@ eina_thread_cancellable_run(Eina_Thread_Cancellable_Run_Cb cb, Eina_Free_Cb clea eina_thread_cancellable_set(old, NULL); return ret; } - -EINA_API const void *EINA_THREAD_JOIN_CANCELED = PTHREAD_CANCELED; - -Eina_Bool -eina_thread_init(void) -{ - return EINA_TRUE; -} - -Eina_Bool -eina_thread_shutdown(void) -{ - return EINA_TRUE; -} |