summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac7
-rw-r--r--m4/efl_threads.m411
-rw-r--r--src/lib/eina/eina_thread.c54
-rw-r--r--src/lib/eina/eina_thread.h2
4 files changed, 61 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac
index d49f167162..61df05fc2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -522,6 +522,11 @@ if ! test "x${efl_have_pthread_barrier}" = "xno" ; then
fi
AC_SUBST(EINA_CONFIGURE_HAVE_PTHREAD_BARRIER)
+if ! test "x${efl_have_setaffinity}" = "xno" ; then
+ EINA_CONFIGURE_HAVE_PTHREAD_SETAFFINITY="#define EINA_HAVE_PTHREAD_AFFINITY"
+fi
+AC_SUBST(EINA_CONFIGURE_HAVE_PTHREAD_SETAFFINITY)
+
EINA_CONFIG(HAVE_DEBUG_THREADS, test "$want_debug_threads" = "yes")
### Modules
@@ -814,7 +819,7 @@ if test "x${have_windows}" = "xyes" ; then
echo " Windows version......: ${_efl_windows_version}"
fi
echo " Build Profile........: ${build_profile}"
-echo " Threads Type.........: ${efl_have_threads} (spinlocks: ${efl_have_posix_threads_spinlock}) (barrier: ${efl_have_pthread_barrier})"
+echo " Threads Type.........: ${efl_have_threads} (spinlocks: ${efl_have_posix_threads_spinlock}) (barrier: ${efl_have_pthread_barrier}) (affinity: ${efl_have_setaffinity})"
echo " Cryptographic System.: ${build_crypto}"
echo
echo "Tests..................: make check (Coverage: ${_efl_enable_coverage})"
diff --git a/m4/efl_threads.m4 b/m4/efl_threads.m4
index bd3a818eb0..a1bcc0308d 100644
--- a/m4/efl_threads.m4
+++ b/m4/efl_threads.m4
@@ -74,6 +74,17 @@ pthread_barrier_init(&barrier, NULL, 1);
]])],
[efl_have_pthread_barrier="yes"],
[efl_have_pthread_barrier="no"])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+#include <stdlib.h>
+#include <pthread.h>
+#include <sched.h>
+ ]],
+ [[
+pthread_attr_setaffinity_np(NULL, 0, NULL);
+ ]])],
+ [efl_have_setaffinity="yes"],
+ [efl_have_setaffinity="no"])
CFLAGS=${SAVE_CFLAGS}
LIBS=${SAVE_LIBS}
diff --git a/src/lib/eina/eina_thread.c b/src/lib/eina/eina_thread.c
index e7a5fcdc3d..e0d438fddf 100644
--- a/src/lib/eina/eina_thread.c
+++ b/src/lib/eina/eina_thread.c
@@ -101,6 +101,7 @@ _eina_thread_win32_cb(LPVOID lpParam)
static Eina_Bool
_eina_thread_win32_create(Eina_Thread *t,
+ int affinity,
Eina_Thread_Cb func,
const void *data)
{
@@ -161,10 +162,11 @@ _eina_thread_win32_join(Eina_Thread t)
return ret;
}
-# define PHE(x, y) _eina_thread_win32_equal(x, y)
-# define PHS() _eina_thread_win32_self()
-# define PHC(x, f, d) _eina_thread_win32_create(x, f, d)
-# define PHJ(x) _eina_thread_win32_join(x)
+# define PHE(x, y) _eina_thread_win32_equal(x, y)
+# define PHS() _eina_thread_win32_self()
+# define PHC(x, a, f, d) _eina_thread_win32_create(x, a, f, d)
+# define PHJ(x) _eina_thread_win32_join(x)
+# define PHA(a)
# else
# include <pthread.h>
@@ -187,10 +189,40 @@ _eina_thread_join(Eina_Thread t)
return NULL;
}
-# define PHE(x, y) pthread_equal(x, y)
-# define PHS() pthread_self()
-# define PHC(x, f, d) pthread_create(x, NULL, (void*) f, d)
-# define PHJ(x) _eina_thread_join(x)
+static Eina_Bool
+_eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), void *data)
+{
+ Eina_Bool r;
+ pthread_attr_t attr;
+#ifdef EINA_HAVE_PTHREAD_AFFINITY
+ cpu_set_t cpu;
+ int cpunum;
+#endif
+
+ pthread_attr_init(&attr);
+#ifdef EINA_HAVE_PTHREAD_AFFINITY
+ if (affinity >= 0)
+ {
+ cpunum = eina_cpu_count();
+
+ CPU_ZERO(&cpu);
+ CPU_SET(affinity % cpunum, &cpu);
+ pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
+ }
+#else
+ (void) affinity;
+#endif
+ /* setup initial locks */
+ r = pthread_create(t, &attr, func, data) == 0;
+ pthread_attr_destroy(&attr);
+
+ return r;
+}
+
+# define PHE(x, y) pthread_equal(x, y)
+# define PHS() pthread_self()
+# define PHC(x, a, f, d) _eina_thread_create(x, a, f, d)
+# define PHJ(x) _eina_thread_join(x)
# endif
#else
@@ -204,7 +236,7 @@ struct _Eina_Thread_Call
const void *data;
Eina_Thread_Priority prio;
- Eina_Bool affinity;
+ int affinity;
};
#include "eina_thread.h"
@@ -241,7 +273,7 @@ eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
EAPI Eina_Bool
eina_thread_create(Eina_Thread *t,
- Eina_Thread_Priority prio, Eina_Bool affinity,
+ Eina_Thread_Priority prio, int affinity,
Eina_Thread_Cb func, const void *data)
{
Eina_Thread_Call *c;
@@ -254,7 +286,7 @@ eina_thread_create(Eina_Thread *t,
c->prio = prio;
c->affinity = affinity;
- if (PHC(t, _eina_internal_call, c) == 0)
+ if (PHC(t, affinity, _eina_internal_call, c))
return EINA_TRUE;
free(c);
diff --git a/src/lib/eina/eina_thread.h b/src/lib/eina/eina_thread.h
index e615e27c43..85bcb33417 100644
--- a/src/lib/eina/eina_thread.h
+++ b/src/lib/eina/eina_thread.h
@@ -67,7 +67,7 @@ typedef enum _Eina_Thread_Priority
EAPI Eina_Thread eina_thread_self(void);
EAPI Eina_Bool eina_thread_equal(Eina_Thread t1, Eina_Thread t2);
EAPI Eina_Bool eina_thread_create(Eina_Thread *t,
- Eina_Thread_Priority prio, Eina_Bool affinity,
+ Eina_Thread_Priority prio, int affinity,
Eina_Thread_Cb func, const void *data);
EAPI void *eina_thread_join(Eina_Thread t);