Until now every thread pool always had at least one tread waiting to avoid

2001-04-17  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>

	* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
	thread pool always had at least one tread waiting to avoid
	switching overhead in case a new task would be added soon after
	one finished. This however means a big waste of threads, if many
	mostly inactive thread pools are involved. Now such a waiting
	thread will only wait for half a second (This value is of course
	very randomly picked) and go to the global threadpool afterwards.

MCVS: ----------------------------------------------------------------------
This commit is contained in:
Sebastian Wilhelmi 2001-04-17 11:48:45 +00:00 committed by Sebastian Wilhelmi
parent 525689823d
commit 313ed5dc19
10 changed files with 186 additions and 30 deletions

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -1,3 +1,13 @@
2001-04-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c (g_thread_pool_thread_proxy): Until now every
thread pool always had at least one tread waiting to avoid
switching overhead in case a new task would be added soon after
one finished. This however means a big waste of threads, if many
mostly inactive thread pools are involved. Now such a waiting
thread will only wait for half a second (This value is of course
very randomly picked) and go to the global threadpool afterwards.
Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com> Mon Apr 16 12:04:52 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Remove warnings about conflicts with the * configure.in: Remove warnings about conflicts with the

View File

@ -65,6 +65,7 @@ static void
g_thread_pool_thread_proxy (gpointer data) g_thread_pool_thread_proxy (gpointer data)
{ {
GRealThreadPool *pool = data; GRealThreadPool *pool = data;
gboolean watcher = FALSE;
g_async_queue_lock (pool->queue); g_async_queue_lock (pool->queue);
while (TRUE) while (TRUE)
@ -76,12 +77,37 @@ g_thread_pool_thread_proxy (gpointer data)
if (g_thread_should_run (pool, len)) if (g_thread_should_run (pool, len))
{ {
task = g_async_queue_pop_unlocked (pool->queue); if (watcher)
{
/* This thread is actually not needed here, but it waits
* for some time anyway. If during that time a new
* request arrives, this saves process
* swicthes. Otherwise the thread will go to the global
* pool afterwards */
GTimeVal end_time;
g_get_current_time (&end_time);
end_time.tv_usec += G_USEC_PER_SEC / 2; /* Halv a second */
if (end_time.tv_usec >= G_USEC_PER_SEC)
{
end_time.tv_usec -= G_USEC_PER_SEC;
end_time.tv_sec += 1;
}
if (pool->num_threads > pool->max_threads && pool->max_threads != -1) task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
/* We are in fact a superfluous threads, so we go to the }
* global pool and just hand the data further to the next one else
* waiting in the queue */ {
task = g_async_queue_pop_unlocked (pool->queue);
}
if (task)
{
watcher = FALSE;
if (pool->num_threads > pool->max_threads &&
pool->max_threads != -1)
/* We are in fact a superfluous threads, so we go to
* the global pool and just hand the data further to
* the next one waiting in the queue */
{ {
g_async_queue_push_unlocked (pool->queue, task); g_async_queue_push_unlocked (pool->queue, task);
goto_global_pool = TRUE; goto_global_pool = TRUE;
@ -92,7 +118,7 @@ g_thread_pool_thread_proxy (gpointer data)
pool->pool.thread_func (task, pool->pool.user_data); pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->queue); g_async_queue_lock (pool->queue);
} }
}
len = g_async_queue_length_unlocked (pool->queue); len = g_async_queue_length_unlocked (pool->queue);
} }
@ -101,9 +127,21 @@ g_thread_pool_thread_proxy (gpointer data)
g_cond_broadcast (inform_cond); g_cond_broadcast (inform_cond);
goto_global_pool = TRUE; goto_global_pool = TRUE;
} }
else if (len >= 0) else if (len > 0)
/* At this pool there is no thread waiting */ {
/* At this pool there are no threads waiting, but tasks are. */
goto_global_pool = FALSE; goto_global_pool = FALSE;
}
else if (len == 0 && !watcher && !pool->pool.exclusive)
{
/* Here neither threads nor tasks are queued and we didn't
* just return from a timed wait. We now wait for a limited
* time at this pool for new tasks to avoid costly context
* switches. */
goto_global_pool = FALSE;
watcher = TRUE;
}
if (goto_global_pool) if (goto_global_pool)
{ {

View File

@ -65,6 +65,7 @@ static void
g_thread_pool_thread_proxy (gpointer data) g_thread_pool_thread_proxy (gpointer data)
{ {
GRealThreadPool *pool = data; GRealThreadPool *pool = data;
gboolean watcher = FALSE;
g_async_queue_lock (pool->queue); g_async_queue_lock (pool->queue);
while (TRUE) while (TRUE)
@ -76,12 +77,37 @@ g_thread_pool_thread_proxy (gpointer data)
if (g_thread_should_run (pool, len)) if (g_thread_should_run (pool, len))
{ {
task = g_async_queue_pop_unlocked (pool->queue); if (watcher)
{
/* This thread is actually not needed here, but it waits
* for some time anyway. If during that time a new
* request arrives, this saves process
* swicthes. Otherwise the thread will go to the global
* pool afterwards */
GTimeVal end_time;
g_get_current_time (&end_time);
end_time.tv_usec += G_USEC_PER_SEC / 2; /* Halv a second */
if (end_time.tv_usec >= G_USEC_PER_SEC)
{
end_time.tv_usec -= G_USEC_PER_SEC;
end_time.tv_sec += 1;
}
if (pool->num_threads > pool->max_threads && pool->max_threads != -1) task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
/* We are in fact a superfluous threads, so we go to the }
* global pool and just hand the data further to the next one else
* waiting in the queue */ {
task = g_async_queue_pop_unlocked (pool->queue);
}
if (task)
{
watcher = FALSE;
if (pool->num_threads > pool->max_threads &&
pool->max_threads != -1)
/* We are in fact a superfluous threads, so we go to
* the global pool and just hand the data further to
* the next one waiting in the queue */
{ {
g_async_queue_push_unlocked (pool->queue, task); g_async_queue_push_unlocked (pool->queue, task);
goto_global_pool = TRUE; goto_global_pool = TRUE;
@ -92,7 +118,7 @@ g_thread_pool_thread_proxy (gpointer data)
pool->pool.thread_func (task, pool->pool.user_data); pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->queue); g_async_queue_lock (pool->queue);
} }
}
len = g_async_queue_length_unlocked (pool->queue); len = g_async_queue_length_unlocked (pool->queue);
} }
@ -101,9 +127,21 @@ g_thread_pool_thread_proxy (gpointer data)
g_cond_broadcast (inform_cond); g_cond_broadcast (inform_cond);
goto_global_pool = TRUE; goto_global_pool = TRUE;
} }
else if (len >= 0) else if (len > 0)
/* At this pool there is no thread waiting */ {
/* At this pool there are no threads waiting, but tasks are. */
goto_global_pool = FALSE; goto_global_pool = FALSE;
}
else if (len == 0 && !watcher && !pool->pool.exclusive)
{
/* Here neither threads nor tasks are queued and we didn't
* just return from a timed wait. We now wait for a limited
* time at this pool for new tasks to avoid costly context
* switches. */
goto_global_pool = FALSE;
watcher = TRUE;
}
if (goto_global_pool) if (goto_global_pool)
{ {