diff --git a/legacy/eina/src/include/Eina.h b/legacy/eina/src/include/Eina.h
index dad45a2f67..eb0263f6c2 100644
--- a/legacy/eina/src/include/Eina.h
+++ b/legacy/eina/src/include/Eina.h
@@ -148,6 +148,7 @@ extern "C" {
#include "eina_benchmark.h"
#include "eina_convert.h"
#include "eina_cpu.h"
+#include "eina_sched.h"
#include "eina_tiler.h"
#include "eina_hamster.h"
#include "eina_matrixsparse.h"
diff --git a/legacy/eina/src/include/Makefile.am b/legacy/eina/src/include/Makefile.am
index 98b12f276b..f04b2978f8 100644
--- a/legacy/eina/src/include/Makefile.am
+++ b/legacy/eina/src/include/Makefile.am
@@ -42,6 +42,7 @@ eina_trash.h \
eina_iterator.h \
eina_main.h \
eina_cpu.h \
+eina_sched.h \
eina_tiler.h \
eina_hamster.h \
eina_matrixsparse.h \
diff --git a/legacy/eina/src/include/eina_sched.h b/legacy/eina/src/include/eina_sched.h
new file mode 100644
index 0000000000..607b9f5b85
--- /dev/null
+++ b/legacy/eina/src/include/eina_sched.h
@@ -0,0 +1,26 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2010 ProFUSION embedded systems
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see .
+ */
+
+#ifndef EINA_SCHED_H_
+#define EINA_SCHED_H_
+
+#include "eina_types.h"
+
+EAPI void eina_sched_prio_drop(void);
+
+#endif /* EINA_SCHED_H_ */
diff --git a/legacy/eina/src/lib/Makefile.am b/legacy/eina/src/lib/Makefile.am
index 70185498ec..49587d3414 100644
--- a/legacy/eina/src/lib/Makefile.am
+++ b/legacy/eina/src/lib/Makefile.am
@@ -37,6 +37,7 @@ eina_binshare.c \
eina_stringshare.c \
eina_ustringshare.c \
eina_cpu.c \
+eina_sched.c \
eina_tiler.c \
eina_hamster.c \
eina_safety_checks.c \
diff --git a/legacy/eina/src/lib/eina_sched.c b/legacy/eina/src/lib/eina_sched.c
new file mode 100644
index 0000000000..d1c84de495
--- /dev/null
+++ b/legacy/eina/src/lib/eina_sched.c
@@ -0,0 +1,93 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2010 ProFUSION embedded systems
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see .
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef EFL_HAVE_THREADS
+# include
+# ifdef __linux__
+# include
+# include
+# include
+# include
+# endif
+#endif
+
+#include "eina_log.h"
+
+#define RTNICENESS 5
+#define NICENESS 5
+
+/**
+ * @brief Lower priority of current thread.
+ *
+ * It's used by worker threads so they use up background cpu and do not stall
+ * the main thread If current thread is running with real-time priority, we
+ * decrease our priority by @c RTNICENESS. This is done in a portable way.
+ *
+ * Otherwise (we are running with SCHED_OTHER policy) there's no portable way to
+ * set the nice level on current thread. In Linux, it does work and it's the
+ * only one that is implemented as of now. In this case the nice level is
+ * incremented on this thread by @c NICENESS.
+ */
+EAPI void
+eina_sched_prio_drop(void)
+{
+#ifdef EFL_HAVE_THREADS
+ struct sched_param param;
+ int pol, prio, ret;
+ pthread_t pthread_id;
+
+ pthread_id = pthread_self();
+ ret = pthread_getschedparam(pthread_id, &pol, ¶m);
+ if (ret)
+ {
+ EINA_LOG_ERR("Unable to query sched parameters");
+ return;
+ }
+
+ if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO))
+ {
+ prio = sched_get_priority_max(pol);
+ param.sched_priority += RTNICENESS;
+ if (prio > 0 && param.sched_priority > prio)
+ param.sched_priority = prio;
+
+ pthread_setschedparam(pthread_id, pol, ¶m);
+ }
+#ifdef __linux__
+ else
+ {
+ errno = 0;
+ prio = getpriority(PRIO_PROCESS, 0);
+ if (errno == 0)
+ {
+ prio += NICENESS;
+ if (prio > 19)
+ prio = 19;
+
+ setpriority(PRIO_PROCESS, 0, prio);
+ }
+ }
+#endif
+#else
+ EINA_LOG_ERR("Eina does not have support for threads enabled");
+#endif
+}
diff --git a/legacy/eina/src/tests/Makefile.am b/legacy/eina/src/tests/Makefile.am
index a414348dd6..b0a3f8e37b 100644
--- a/legacy/eina/src/tests/Makefile.am
+++ b/legacy/eina/src/tests/Makefile.am
@@ -39,6 +39,7 @@ eina_test_ustr.c \
eina_test_binshare.c \
eina_test_array.c \
eina_test_error.c \
+eina_test_sched.c \
eina_test_log.c \
eina_test_magic.c \
eina_test_inlist.c \
diff --git a/legacy/eina/src/tests/eina_suite.c b/legacy/eina/src/tests/eina_suite.c
index 78f2d8ac96..39584408fe 100644
--- a/legacy/eina/src/tests/eina_suite.c
+++ b/legacy/eina/src/tests/eina_suite.c
@@ -62,6 +62,7 @@ static const Eina_Test_Case etc[] = {
{ "String", eina_test_str },
{ "Unicode String", eina_test_ustr },
{ "QuadTree", eina_test_quadtree },
+ { "Sched", eina_test_sched },
{ NULL, NULL }
};
diff --git a/legacy/eina/src/tests/eina_suite.h b/legacy/eina/src/tests/eina_suite.h
index b63cb608ce..c7dedca8e8 100644
--- a/legacy/eina/src/tests/eina_suite.h
+++ b/legacy/eina/src/tests/eina_suite.h
@@ -50,5 +50,6 @@ void eina_test_str(TCase *tc);
void eina_test_ustr(TCase *tc);
void eina_test_quadtree(TCase *tc);
void eina_test_fp(TCase *tc);
+void eina_test_sched(TCase *tc);
#endif /* EINA_SUITE_H_ */
diff --git a/legacy/eina/src/tests/eina_test_sched.c b/legacy/eina/src/tests/eina_test_sched.c
new file mode 100644
index 0000000000..19c187fa72
--- /dev/null
+++ b/legacy/eina/src/tests/eina_test_sched.c
@@ -0,0 +1,85 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2008 Cedric Bail
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see .
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if defined(EFL_HAVE_THREADS) && defined __linux__
+#include
+#include
+#include
+#endif
+
+#include "eina_suite.h"
+#include "Eina.h"
+
+#if defined(EFL_HAVE_THREADS) && defined __linux__
+
+/*
+ * TODO: Test if RT priorities are right. However, make check should be run as
+ * root.
+ */
+
+static void *
+_thread_run(void *arg __UNUSED__)
+{
+ int niceval = getpriority(PRIO_PROCESS, 0);
+ int niceval2;
+ eina_sched_prio_drop();
+
+ niceval2 = getpriority(PRIO_PROCESS, 0);
+ fail_if((niceval2 != 19) && (niceval2 != niceval+5));
+
+ return NULL;
+}
+
+START_TEST(eina_test_sched_prio_drop)
+{
+ int niceval = getpriority(PRIO_PROCESS, 0);
+ int niceval2;
+ pthread_t tid;
+
+ eina_init();
+
+ pthread_create(&tid, NULL, _thread_run, NULL);
+
+ niceval2 = getpriority(PRIO_PROCESS, 0);
+ /* niceness of main thread should not have changed */
+ fail_if(niceval2 != niceval);
+
+ pthread_join(tid, NULL);
+ /* niceness of main thread should not have changed */
+ fail_if(niceval2 != niceval);
+
+ eina_shutdown();
+}
+END_TEST
+#else
+START_TEST(eina_test_sched_prio_drop)
+{
+ fail_if(1);
+}
+END_TEST
+#endif
+
+void
+eina_test_sched(TCase *tc)
+{
+ tcase_add_test(tc, eina_test_sched_prio_drop);
+}