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); +}