forked from enlightenment/efl
fix ecore-thread scheduler starvation issue.
SVN revision: 71404
This commit is contained in:
parent
01e40c8253
commit
4bf005eede
|
@ -671,4 +671,7 @@
|
||||||
accessind already deleted ecore-con clients. use client
|
accessind already deleted ecore-con clients. use client
|
||||||
ref/unref to fix it. No backport of this fix as it requires a
|
ref/unref to fix it. No backport of this fix as it requires a
|
||||||
new feature.
|
new feature.
|
||||||
|
* Fix ecore-thread scheduling issue where re-scheduled threads
|
||||||
|
will hold a loop busy and not allow feedback workers to run,
|
||||||
|
so now have fairer scheduling.
|
||||||
|
* Allow 16 * cpu num for worker threads (default still cpu num)
|
||||||
|
|
|
@ -2120,7 +2120,7 @@ EAPI int ecore_thread_max_get(void);
|
||||||
* @param num The new maximum
|
* @param num The new maximum
|
||||||
*
|
*
|
||||||
* This sets a new value for the maximum number of concurrently running
|
* This sets a new value for the maximum number of concurrently running
|
||||||
* Ecore_Thread's. It @b must an integer between 1 and (2 * @c x), where @c x
|
* Ecore_Thread's. It @b must an integer between 1 and (16 * @c x), where @c x
|
||||||
* is the number for CPUs available.
|
* is the number for CPUs available.
|
||||||
*
|
*
|
||||||
* @see ecore_thread_max_get()
|
* @see ecore_thread_max_get()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -398,44 +399,40 @@ static void
|
||||||
_ecore_short_job(PH(thread))
|
_ecore_short_job(PH(thread))
|
||||||
{
|
{
|
||||||
Ecore_Pthread_Worker *work;
|
Ecore_Pthread_Worker *work;
|
||||||
|
int cancel;
|
||||||
|
|
||||||
while (_ecore_pending_job_threads)
|
LKL(_ecore_pending_job_threads_mutex);
|
||||||
|
|
||||||
|
if (!_ecore_pending_job_threads)
|
||||||
{
|
{
|
||||||
int cancel;
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = eina_list_data_get(_ecore_pending_job_threads);
|
||||||
|
_ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads,
|
||||||
|
_ecore_pending_job_threads);
|
||||||
|
|
||||||
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
|
||||||
|
LKL(work->cancel_mutex);
|
||||||
|
cancel = work->cancel;
|
||||||
|
LKU(work->cancel_mutex);
|
||||||
|
work->self = thread;
|
||||||
|
if (!cancel)
|
||||||
|
work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
|
||||||
|
|
||||||
|
if (work->reschedule)
|
||||||
|
{
|
||||||
|
work->reschedule = EINA_FALSE;
|
||||||
|
|
||||||
LKL(_ecore_pending_job_threads_mutex);
|
LKL(_ecore_pending_job_threads_mutex);
|
||||||
|
_ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work);
|
||||||
if (!_ecore_pending_job_threads)
|
|
||||||
{
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
work = eina_list_data_get(_ecore_pending_job_threads);
|
|
||||||
_ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads,
|
|
||||||
_ecore_pending_job_threads);
|
|
||||||
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
}
|
||||||
LKL(work->cancel_mutex);
|
else
|
||||||
cancel = work->cancel;
|
{
|
||||||
LKU(work->cancel_mutex);
|
ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
|
||||||
work->self = thread;
|
|
||||||
if (!cancel)
|
|
||||||
work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
|
|
||||||
|
|
||||||
if (work->reschedule)
|
|
||||||
{
|
|
||||||
work->reschedule = EINA_FALSE;
|
|
||||||
|
|
||||||
LKL(_ecore_pending_job_threads_mutex);
|
|
||||||
_ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work);
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,44 +440,40 @@ static void
|
||||||
_ecore_feedback_job(PH(thread))
|
_ecore_feedback_job(PH(thread))
|
||||||
{
|
{
|
||||||
Ecore_Pthread_Worker *work;
|
Ecore_Pthread_Worker *work;
|
||||||
|
int cancel;
|
||||||
|
|
||||||
while (_ecore_pending_job_threads_feedback)
|
LKL(_ecore_pending_job_threads_mutex);
|
||||||
|
|
||||||
|
if (!_ecore_pending_job_threads_feedback)
|
||||||
{
|
{
|
||||||
int cancel;
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = eina_list_data_get(_ecore_pending_job_threads_feedback);
|
||||||
|
_ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback,
|
||||||
|
_ecore_pending_job_threads_feedback);
|
||||||
|
|
||||||
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
|
||||||
|
LKL(work->cancel_mutex);
|
||||||
|
cancel = work->cancel;
|
||||||
|
LKU(work->cancel_mutex);
|
||||||
|
work->self = thread;
|
||||||
|
if (!cancel)
|
||||||
|
work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
|
||||||
|
|
||||||
|
if (work->reschedule)
|
||||||
|
{
|
||||||
|
work->reschedule = EINA_FALSE;
|
||||||
|
|
||||||
LKL(_ecore_pending_job_threads_mutex);
|
LKL(_ecore_pending_job_threads_mutex);
|
||||||
|
_ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, work);
|
||||||
if (!_ecore_pending_job_threads_feedback)
|
|
||||||
{
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
work = eina_list_data_get(_ecore_pending_job_threads_feedback);
|
|
||||||
_ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback,
|
|
||||||
_ecore_pending_job_threads_feedback);
|
|
||||||
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
LKU(_ecore_pending_job_threads_mutex);
|
||||||
|
}
|
||||||
LKL(work->cancel_mutex);
|
else
|
||||||
cancel = work->cancel;
|
{
|
||||||
LKU(work->cancel_mutex);
|
ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
|
||||||
work->self = thread;
|
|
||||||
if (!cancel)
|
|
||||||
work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
|
|
||||||
|
|
||||||
if (work->reschedule)
|
|
||||||
{
|
|
||||||
work->reschedule = EINA_FALSE;
|
|
||||||
|
|
||||||
LKL(_ecore_pending_job_threads_mutex);
|
|
||||||
_ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, work);
|
|
||||||
LKU(_ecore_pending_job_threads_mutex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,8 +512,8 @@ _ecore_thread_worker(void *data __UNUSED__)
|
||||||
eina_sched_prio_drop();
|
eina_sched_prio_drop();
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
if (_ecore_pending_job_threads) _ecore_short_job(PHS());
|
_ecore_short_job(PHS());
|
||||||
if (_ecore_pending_job_threads_feedback) _ecore_feedback_job(PHS());
|
_ecore_feedback_job(PHS());
|
||||||
|
|
||||||
/* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */
|
/* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */
|
||||||
|
|
||||||
|
@ -536,7 +529,7 @@ restart:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Sleep(1); /* around 50ms */
|
Sleep(1); /* around 50ms */
|
||||||
#else
|
#else
|
||||||
usleep(200);
|
usleep(50);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LKL(_ecore_pending_job_threads_mutex);
|
LKL(_ecore_pending_job_threads_mutex);
|
||||||
|
@ -1188,7 +1181,7 @@ ecore_thread_max_set(int num)
|
||||||
EINA_MAIN_LOOP_CHECK_RETURN;
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
||||||
if (num < 1) return;
|
if (num < 1) return;
|
||||||
/* avoid doing something hilarious by blocking dumb users */
|
/* avoid doing something hilarious by blocking dumb users */
|
||||||
if (num >= (2 * eina_cpu_count())) return;
|
if (num >= (16 * eina_cpu_count())) num = 16 * eina_cpu_count();
|
||||||
|
|
||||||
_ecore_thread_count_max = num;
|
_ecore_thread_count_max = num;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue