Skip to content
This repository has been archived by the owner on Nov 17, 2020. It is now read-only.

Commit

Permalink
Until now every thread pool always had at least one tread waiting to …
Browse files Browse the repository at this point in the history
…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: ----------------------------------------------------------------------
  • Loading branch information
Sebastian Wilhelmi authored and Sebastian Wilhelmi committed Apr 17, 2001
1 parent 5256898 commit 313ed5d
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 30 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-0
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-10
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-12
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-2
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-4
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-6
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
10 changes: 10 additions & 0 deletions ChangeLog.pre-2-8
Original file line number Diff line number Diff line change
@@ -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>

* configure.in: Remove warnings about conflicts with the
Expand Down
68 changes: 53 additions & 15 deletions glib/gthreadpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static void
g_thread_pool_thread_proxy (gpointer data)
{
GRealThreadPool *pool = data;
gboolean watcher = FALSE;

g_async_queue_lock (pool->queue);
while (TRUE)
Expand All @@ -76,23 +77,48 @@ g_thread_pool_thread_proxy (gpointer data)

if (g_thread_should_run (pool, len))
{
task = g_async_queue_pop_unlocked (pool->queue);

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 */
if (watcher)
{
g_async_queue_push_unlocked (pool->queue, task);
goto_global_pool = TRUE;
/* 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;
}

task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
}
else if (pool->running || !pool->immediate)
else
{
g_async_queue_unlock (pool->queue);
pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->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);
goto_global_pool = TRUE;
}
else if (pool->running || !pool->immediate)
{
g_async_queue_unlock (pool->queue);
pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->queue);
}
}
len = g_async_queue_length_unlocked (pool->queue);
}

Expand All @@ -101,9 +127,21 @@ g_thread_pool_thread_proxy (gpointer data)
g_cond_broadcast (inform_cond);
goto_global_pool = TRUE;
}
else if (len >= 0)
/* At this pool there is no thread waiting */
goto_global_pool = FALSE;
else if (len > 0)
{
/* At this pool there are no threads waiting, but tasks are. */
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)
{
Expand Down
68 changes: 53 additions & 15 deletions gthreadpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static void
g_thread_pool_thread_proxy (gpointer data)
{
GRealThreadPool *pool = data;
gboolean watcher = FALSE;

g_async_queue_lock (pool->queue);
while (TRUE)
Expand All @@ -76,23 +77,48 @@ g_thread_pool_thread_proxy (gpointer data)

if (g_thread_should_run (pool, len))
{
task = g_async_queue_pop_unlocked (pool->queue);

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 */
if (watcher)
{
g_async_queue_push_unlocked (pool->queue, task);
goto_global_pool = TRUE;
/* 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;
}

task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
}
else if (pool->running || !pool->immediate)
else
{
g_async_queue_unlock (pool->queue);
pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->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);
goto_global_pool = TRUE;
}
else if (pool->running || !pool->immediate)
{
g_async_queue_unlock (pool->queue);
pool->pool.thread_func (task, pool->pool.user_data);
g_async_queue_lock (pool->queue);
}
}
len = g_async_queue_length_unlocked (pool->queue);
}

Expand All @@ -101,9 +127,21 @@ g_thread_pool_thread_proxy (gpointer data)
g_cond_broadcast (inform_cond);
goto_global_pool = TRUE;
}
else if (len >= 0)
/* At this pool there is no thread waiting */
goto_global_pool = FALSE;
else if (len > 0)
{
/* At this pool there are no threads waiting, but tasks are. */
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)
{
Expand Down

0 comments on commit 313ed5d

Please sign in to comment.