mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-27 17:52:58 +02:00
Renamed g_thread_create to g_thread_create_full and added macro
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * gthread.c, gthread.h: Renamed g_thread_create to g_thread_create_full and added macro g_thread_create, which omits 'stack_size', 'bound' and 'priority' parameters. Also removed 'bound' from GThread struct. * gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above changes. GThreadPool lost the 'priority' and 'bound' members. g_thread_pool_new the 'stack_size', 'bound' and 'priority' parameters. * tests/mainloop-test.c, tests/thread-test.c, tests/threadpool-test.c: Adapted to the above changes.
This commit is contained in:
committed by
Sebastian Wilhelmi
parent
a70206f177
commit
227d18bc46
13
ChangeLog
13
ChangeLog
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -1,5 +1,18 @@
|
|||||||
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-18 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* gthread.c, gthread.h: Renamed g_thread_create to
|
||||||
|
g_thread_create_full and added macro g_thread_create, which omits
|
||||||
|
'stack_size', 'bound' and 'priority' parameters. Also removed
|
||||||
|
'bound' from GThread struct.
|
||||||
|
|
||||||
|
* gthreadpool.h, gthreadpool.c: Adapted GThreadPool to the above
|
||||||
|
changes. GThreadPool lost the 'priority' and 'bound'
|
||||||
|
members. g_thread_pool_new the 'stack_size', 'bound' and
|
||||||
|
'priority' parameters.
|
||||||
|
|
||||||
|
* tests/mainloop-test.c, tests/thread-test.c,
|
||||||
|
tests/threadpool-test.c: Adapted to the above changes.
|
||||||
|
|
||||||
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
* gmem.c (g_mem_profile): Fixed mutex deadlock.
|
||||||
|
|
||||||
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-05-17 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
@@ -541,13 +541,13 @@ g_thread_create_proxy (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GThread*
|
GThread*
|
||||||
g_thread_create (GThreadFunc func,
|
g_thread_create_full (GThreadFunc func,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
gulong stack_size,
|
gulong stack_size,
|
||||||
gboolean joinable,
|
gboolean joinable,
|
||||||
gboolean bound,
|
gboolean bound,
|
||||||
GThreadPriority priority,
|
GThreadPriority priority,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GRealThread* result = g_new (GRealThread, 1);
|
GRealThread* result = g_new (GRealThread, 1);
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
@@ -556,7 +556,6 @@ g_thread_create (GThreadFunc func,
|
|||||||
g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
|
g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
|
||||||
|
|
||||||
result->thread.joinable = joinable;
|
result->thread.joinable = joinable;
|
||||||
result->thread.bound = bound;
|
|
||||||
result->thread.priority = priority;
|
result->thread.priority = priority;
|
||||||
result->thread.func = func;
|
result->thread.func = func;
|
||||||
result->thread.data = data;
|
result->thread.data = data;
|
||||||
@@ -653,7 +652,6 @@ g_thread_self (void)
|
|||||||
created by GLib. */
|
created by GLib. */
|
||||||
thread = g_new (GRealThread, 1);
|
thread = g_new (GRealThread, 1);
|
||||||
thread->thread.joinable = FALSE; /* This is a save guess */
|
thread->thread.joinable = FALSE; /* This is a save guess */
|
||||||
thread->thread.bound = TRUE; /* This isn't important at all */
|
|
||||||
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
|
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
|
||||||
just a guess */
|
just a guess */
|
||||||
thread->thread.func = NULL;
|
thread->thread.func = NULL;
|
||||||
|
@@ -59,7 +59,6 @@ struct _GThread
|
|||||||
GThreadFunc func;
|
GThreadFunc func;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
gboolean joinable;
|
gboolean joinable;
|
||||||
gboolean bound;
|
|
||||||
GThreadPriority priority;
|
GThreadPriority priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,7 +193,11 @@ GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
|||||||
(private_key, value))
|
(private_key, value))
|
||||||
#define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
|
#define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
|
||||||
|
|
||||||
GThread* g_thread_create (GThreadFunc func,
|
#define g_thread_create(func, data, joinable, error) \
|
||||||
|
(g_thread_create_full (func, data, 0, joinable, FALSE, \
|
||||||
|
G_THREAD_PRIORITY_NORMAL, error))
|
||||||
|
|
||||||
|
GThread* g_thread_create_full (GThreadFunc func,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
gulong stack_size,
|
gulong stack_size,
|
||||||
gboolean joinable,
|
gboolean joinable,
|
||||||
|
@@ -31,7 +31,6 @@ typedef struct _GRealThreadPool GRealThreadPool;
|
|||||||
struct _GRealThreadPool
|
struct _GRealThreadPool
|
||||||
{
|
{
|
||||||
GThreadPool pool;
|
GThreadPool pool;
|
||||||
gulong stack_size;
|
|
||||||
GAsyncQueue* queue;
|
GAsyncQueue* queue;
|
||||||
gint max_threads;
|
gint max_threads;
|
||||||
gint num_threads;
|
gint num_threads;
|
||||||
@@ -45,8 +44,8 @@ struct _GRealThreadPool
|
|||||||
* GThreadPool address) */
|
* GThreadPool address) */
|
||||||
static const gpointer stop_this_thread_marker = (gpointer) &g_thread_pool_new;
|
static const gpointer stop_this_thread_marker = (gpointer) &g_thread_pool_new;
|
||||||
|
|
||||||
/* Here all unused threads are waiting, depending on their priority */
|
/* Here all unused threads are waiting */
|
||||||
static GAsyncQueue *unused_thread_queue[G_THREAD_PRIORITY_URGENT + 1][2];
|
static GAsyncQueue *unused_thread_queue;
|
||||||
static gint unused_threads = 0;
|
static gint unused_threads = 0;
|
||||||
static gint max_unused_threads = 0;
|
static gint max_unused_threads = 0;
|
||||||
G_LOCK_DEFINE_STATIC (unused_threads);
|
G_LOCK_DEFINE_STATIC (unused_threads);
|
||||||
@@ -73,8 +72,7 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
gpointer task;
|
gpointer task;
|
||||||
gboolean goto_global_pool =
|
gboolean goto_global_pool = !pool->pool.exclusive;
|
||||||
!pool->pool.exclusive && pool->stack_size == 0;
|
|
||||||
gint len = g_async_queue_length_unlocked (pool->queue);
|
gint len = g_async_queue_length_unlocked (pool->queue);
|
||||||
|
|
||||||
if (g_thread_should_run (pool, len))
|
if (g_thread_should_run (pool, len))
|
||||||
@@ -147,8 +145,6 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
|
|
||||||
if (goto_global_pool)
|
if (goto_global_pool)
|
||||||
{
|
{
|
||||||
GAsyncQueue *unused_queue =
|
|
||||||
unused_thread_queue[pool->pool.priority][pool->pool.bound ? 1 : 0];
|
|
||||||
pool->num_threads--;
|
pool->num_threads--;
|
||||||
|
|
||||||
if (!pool->running && !pool->waiting)
|
if (!pool->running && !pool->waiting)
|
||||||
@@ -167,27 +163,27 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
else
|
else
|
||||||
g_async_queue_unlock (pool->queue);
|
g_async_queue_unlock (pool->queue);
|
||||||
|
|
||||||
g_async_queue_lock (unused_queue);
|
g_async_queue_lock (unused_thread_queue);
|
||||||
|
|
||||||
G_LOCK (unused_threads);
|
G_LOCK (unused_threads);
|
||||||
if ((unused_threads >= max_unused_threads &&
|
if ((unused_threads >= max_unused_threads &&
|
||||||
max_unused_threads != -1) || pool->stack_size != 0)
|
max_unused_threads != -1))
|
||||||
{
|
{
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
g_async_queue_unlock (unused_queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
/* Stop this thread */
|
/* Stop this thread */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
unused_threads++;
|
unused_threads++;
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
|
||||||
pool = g_async_queue_pop_unlocked (unused_queue);
|
pool = g_async_queue_pop_unlocked (unused_thread_queue);
|
||||||
|
|
||||||
G_LOCK (unused_threads);
|
G_LOCK (unused_threads);
|
||||||
unused_threads--;
|
unused_threads--;
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
|
||||||
g_async_queue_unlock (unused_queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
|
|
||||||
if (pool == stop_this_thread_marker)
|
if (pool == stop_this_thread_marker)
|
||||||
/* Stop this thread */
|
/* Stop this thread */
|
||||||
@@ -208,35 +204,26 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
GThreadPriority priority = pool->pool.priority;
|
|
||||||
guint bound = pool->pool.bound ? 1 : 0;
|
|
||||||
GAsyncQueue *queue = unused_thread_queue[priority][bound];
|
|
||||||
|
|
||||||
if (pool->num_threads >= pool->max_threads && pool->max_threads != -1)
|
if (pool->num_threads >= pool->max_threads && pool->max_threads != -1)
|
||||||
/* Enough threads are already running */
|
/* Enough threads are already running */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_async_queue_lock (queue);
|
g_async_queue_lock (unused_thread_queue);
|
||||||
|
|
||||||
if (g_async_queue_length_unlocked (queue) < 0)
|
if (g_async_queue_length_unlocked (unused_thread_queue) < 0)
|
||||||
{
|
{
|
||||||
/* First we try a thread with the right priority */
|
g_async_queue_push_unlocked (unused_thread_queue, pool);
|
||||||
g_async_queue_push_unlocked (queue, pool);
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_async_queue_unlock (queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
|
|
||||||
/* We will not search for threads with other priorities, because changing
|
|
||||||
* priority is quite unportable */
|
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
/* No thread was found, we have to start a new one */
|
/* No thread was found, we have to start a new one */
|
||||||
g_thread_create (g_thread_pool_thread_proxy, pool,
|
g_thread_create (g_thread_pool_thread_proxy, pool, FALSE, &local_error);
|
||||||
pool->stack_size, FALSE,
|
|
||||||
bound, priority, &local_error);
|
|
||||||
|
|
||||||
if (local_error)
|
if (local_error)
|
||||||
{
|
{
|
||||||
@@ -257,17 +244,10 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
* is called
|
* is called
|
||||||
* @max_threads: the maximal number of threads to execute concurrently in
|
* @max_threads: the maximal number of threads to execute concurrently in
|
||||||
* the new thread pool, -1 means no limit
|
* the new thread pool, -1 means no limit
|
||||||
* @stack_size: the stack size for the threads of the new thread pool,
|
|
||||||
* 0 means using the standard
|
|
||||||
* @bound: should the threads of the new thread pool be bound?
|
|
||||||
* @priority: a priority for the threads of the new thread pool
|
|
||||||
* @exclusive: should this thread pool be exclusive?
|
* @exclusive: should this thread pool be exclusive?
|
||||||
* @error: return location for error
|
* @error: return location for error
|
||||||
*
|
*
|
||||||
* This function creates a new thread pool. All threads created within
|
* This function creates a new thread pool.
|
||||||
* this thread pool will have the priority @priority and the stack
|
|
||||||
* size @stack_size and will be bound if and only if @bound is
|
|
||||||
* true.
|
|
||||||
*
|
*
|
||||||
* Whenever you call g_thread_pool_push(), either a new thread is
|
* Whenever you call g_thread_pool_push(), either a new thread is
|
||||||
* created or an unused one is reused. At most @max_threads threads
|
* created or an unused one is reused. At most @max_threads threads
|
||||||
@@ -286,12 +266,6 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
* non-exclusive thread pools. This implies that @max_threads may not
|
* non-exclusive thread pools. This implies that @max_threads may not
|
||||||
* be -1 for exclusive thread pools.
|
* be -1 for exclusive thread pools.
|
||||||
*
|
*
|
||||||
* Note, that only threads from a thread pool with a @stack_size of 0
|
|
||||||
* (which means using the standard stack size) will be globally
|
|
||||||
* reused. Threads from a thread pool with a non-zero stack size will
|
|
||||||
* stay only in this thread pool until it is freed and can thus not be
|
|
||||||
* controlled by the g_thread_pool_set_unused_threads() function.
|
|
||||||
*
|
|
||||||
* @error can be NULL to ignore errors, or non-NULL to report
|
* @error can be NULL to ignore errors, or non-NULL to report
|
||||||
* errors. An error can only occur, when @exclusive is set to @TRUE and
|
* errors. An error can only occur, when @exclusive is set to @TRUE and
|
||||||
* not all @max_threads threads could be created.
|
* not all @max_threads threads could be created.
|
||||||
@@ -302,9 +276,6 @@ GThreadPool*
|
|||||||
g_thread_pool_new (GFunc func,
|
g_thread_pool_new (GFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint max_threads,
|
gint max_threads,
|
||||||
gulong stack_size,
|
|
||||||
gboolean bound,
|
|
||||||
GThreadPriority priority,
|
|
||||||
gboolean exclusive,
|
gboolean exclusive,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -320,10 +291,7 @@ g_thread_pool_new (GFunc func,
|
|||||||
|
|
||||||
retval->pool.func = func;
|
retval->pool.func = func;
|
||||||
retval->pool.user_data = user_data;
|
retval->pool.user_data = user_data;
|
||||||
retval->pool.bound = bound;
|
|
||||||
retval->pool.priority = priority;
|
|
||||||
retval->pool.exclusive = exclusive;
|
retval->pool.exclusive = exclusive;
|
||||||
retval->stack_size = stack_size;
|
|
||||||
retval->queue = g_async_queue_new ();
|
retval->queue = g_async_queue_new ();
|
||||||
retval->max_threads = max_threads;
|
retval->max_threads = max_threads;
|
||||||
retval->num_threads = 0;
|
retval->num_threads = 0;
|
||||||
@@ -335,12 +303,7 @@ g_thread_pool_new (GFunc func,
|
|||||||
{
|
{
|
||||||
inform_mutex = g_mutex_new ();
|
inform_mutex = g_mutex_new ();
|
||||||
inform_cond = g_cond_new ();
|
inform_cond = g_cond_new ();
|
||||||
for (priority = G_THREAD_PRIORITY_LOW;
|
unused_thread_queue = g_async_queue_new ();
|
||||||
priority < G_THREAD_PRIORITY_URGENT + 1; priority++)
|
|
||||||
{
|
|
||||||
unused_thread_queue[priority][0] = g_async_queue_new ();
|
|
||||||
unused_thread_queue[priority][1] = g_async_queue_new ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_UNLOCK (init);
|
G_UNLOCK (init);
|
||||||
@@ -659,37 +622,13 @@ g_thread_pool_set_max_unused_threads (gint max_threads)
|
|||||||
|
|
||||||
if (max_unused_threads < unused_threads && max_unused_threads != -1)
|
if (max_unused_threads < unused_threads && max_unused_threads != -1)
|
||||||
{
|
{
|
||||||
guint close_down_num = unused_threads - max_unused_threads;
|
guint i;
|
||||||
|
|
||||||
while (close_down_num > 0)
|
g_async_queue_lock (unused_thread_queue);
|
||||||
{
|
for (i = unused_threads - max_unused_threads; i > 0; i--)
|
||||||
GThreadPriority priority;
|
g_async_queue_push_unlocked (unused_thread_queue,
|
||||||
guint bound;
|
stop_this_thread_marker);
|
||||||
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
guint old_close_down_num = close_down_num;
|
|
||||||
for (priority = G_THREAD_PRIORITY_LOW;
|
|
||||||
priority < G_THREAD_PRIORITY_URGENT + 1 && close_down_num > 0;
|
|
||||||
priority++)
|
|
||||||
{
|
|
||||||
for (bound = 0; bound < 2; bound++)
|
|
||||||
{
|
|
||||||
GAsyncQueue *queue = unused_thread_queue[priority][bound];
|
|
||||||
g_async_queue_lock (queue);
|
|
||||||
|
|
||||||
if (g_async_queue_length_unlocked (queue) < 0)
|
|
||||||
{
|
|
||||||
g_async_queue_push_unlocked (queue,
|
|
||||||
stop_this_thread_marker);
|
|
||||||
close_down_num--;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_async_queue_unlock (queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just to make sure, there are no counting problems */
|
|
||||||
g_assert (old_close_down_num != close_down_num);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
@@ -42,22 +42,17 @@ struct _GThreadPool
|
|||||||
{
|
{
|
||||||
GFunc func;
|
GFunc func;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
gboolean bound;
|
|
||||||
GThreadPriority priority;
|
|
||||||
gboolean exclusive;
|
gboolean exclusive;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get a thread pool with the function func, at most max_threads may
|
/* Get a thread pool with the function func, at most max_threads may
|
||||||
* run at a time (max_threads == -1 means no limit), stack_size, bound,
|
* run at a time (max_threads == -1 means no limit), exclusive == TRUE
|
||||||
* priority like in g_thread_create, exclusive == TRUE means, that the threads
|
* means, that the threads shouldn't be shared and that they will be
|
||||||
* shouldn't be shared and that they will be prestarted (otherwise they are
|
* prestarted (otherwise they are started as needed) user_data is the
|
||||||
* started as needed) user_data is the 2nd argument to the func */
|
* 2nd argument to the func */
|
||||||
GThreadPool* g_thread_pool_new (GFunc func,
|
GThreadPool* g_thread_pool_new (GFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint max_threads,
|
gint max_threads,
|
||||||
gulong stack_size,
|
|
||||||
gboolean bound,
|
|
||||||
GThreadPriority priority,
|
|
||||||
gboolean exclusive,
|
gboolean exclusive,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
16
gthread.c
16
gthread.c
@@ -541,13 +541,13 @@ g_thread_create_proxy (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GThread*
|
GThread*
|
||||||
g_thread_create (GThreadFunc func,
|
g_thread_create_full (GThreadFunc func,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
gulong stack_size,
|
gulong stack_size,
|
||||||
gboolean joinable,
|
gboolean joinable,
|
||||||
gboolean bound,
|
gboolean bound,
|
||||||
GThreadPriority priority,
|
GThreadPriority priority,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GRealThread* result = g_new (GRealThread, 1);
|
GRealThread* result = g_new (GRealThread, 1);
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
@@ -556,7 +556,6 @@ g_thread_create (GThreadFunc func,
|
|||||||
g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
|
g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
|
||||||
|
|
||||||
result->thread.joinable = joinable;
|
result->thread.joinable = joinable;
|
||||||
result->thread.bound = bound;
|
|
||||||
result->thread.priority = priority;
|
result->thread.priority = priority;
|
||||||
result->thread.func = func;
|
result->thread.func = func;
|
||||||
result->thread.data = data;
|
result->thread.data = data;
|
||||||
@@ -653,7 +652,6 @@ g_thread_self (void)
|
|||||||
created by GLib. */
|
created by GLib. */
|
||||||
thread = g_new (GRealThread, 1);
|
thread = g_new (GRealThread, 1);
|
||||||
thread->thread.joinable = FALSE; /* This is a save guess */
|
thread->thread.joinable = FALSE; /* This is a save guess */
|
||||||
thread->thread.bound = TRUE; /* This isn't important at all */
|
|
||||||
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
|
thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
|
||||||
just a guess */
|
just a guess */
|
||||||
thread->thread.func = NULL;
|
thread->thread.func = NULL;
|
||||||
|
@@ -59,7 +59,6 @@ struct _GThread
|
|||||||
GThreadFunc func;
|
GThreadFunc func;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
gboolean joinable;
|
gboolean joinable;
|
||||||
gboolean bound;
|
|
||||||
GThreadPriority priority;
|
GThreadPriority priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,7 +193,11 @@ GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
|||||||
(private_key, value))
|
(private_key, value))
|
||||||
#define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
|
#define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
|
||||||
|
|
||||||
GThread* g_thread_create (GThreadFunc func,
|
#define g_thread_create(func, data, joinable, error) \
|
||||||
|
(g_thread_create_full (func, data, 0, joinable, FALSE, \
|
||||||
|
G_THREAD_PRIORITY_NORMAL, error))
|
||||||
|
|
||||||
|
GThread* g_thread_create_full (GThreadFunc func,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
gulong stack_size,
|
gulong stack_size,
|
||||||
gboolean joinable,
|
gboolean joinable,
|
||||||
|
103
gthreadpool.c
103
gthreadpool.c
@@ -31,7 +31,6 @@ typedef struct _GRealThreadPool GRealThreadPool;
|
|||||||
struct _GRealThreadPool
|
struct _GRealThreadPool
|
||||||
{
|
{
|
||||||
GThreadPool pool;
|
GThreadPool pool;
|
||||||
gulong stack_size;
|
|
||||||
GAsyncQueue* queue;
|
GAsyncQueue* queue;
|
||||||
gint max_threads;
|
gint max_threads;
|
||||||
gint num_threads;
|
gint num_threads;
|
||||||
@@ -45,8 +44,8 @@ struct _GRealThreadPool
|
|||||||
* GThreadPool address) */
|
* GThreadPool address) */
|
||||||
static const gpointer stop_this_thread_marker = (gpointer) &g_thread_pool_new;
|
static const gpointer stop_this_thread_marker = (gpointer) &g_thread_pool_new;
|
||||||
|
|
||||||
/* Here all unused threads are waiting, depending on their priority */
|
/* Here all unused threads are waiting */
|
||||||
static GAsyncQueue *unused_thread_queue[G_THREAD_PRIORITY_URGENT + 1][2];
|
static GAsyncQueue *unused_thread_queue;
|
||||||
static gint unused_threads = 0;
|
static gint unused_threads = 0;
|
||||||
static gint max_unused_threads = 0;
|
static gint max_unused_threads = 0;
|
||||||
G_LOCK_DEFINE_STATIC (unused_threads);
|
G_LOCK_DEFINE_STATIC (unused_threads);
|
||||||
@@ -73,8 +72,7 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
gpointer task;
|
gpointer task;
|
||||||
gboolean goto_global_pool =
|
gboolean goto_global_pool = !pool->pool.exclusive;
|
||||||
!pool->pool.exclusive && pool->stack_size == 0;
|
|
||||||
gint len = g_async_queue_length_unlocked (pool->queue);
|
gint len = g_async_queue_length_unlocked (pool->queue);
|
||||||
|
|
||||||
if (g_thread_should_run (pool, len))
|
if (g_thread_should_run (pool, len))
|
||||||
@@ -147,8 +145,6 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
|
|
||||||
if (goto_global_pool)
|
if (goto_global_pool)
|
||||||
{
|
{
|
||||||
GAsyncQueue *unused_queue =
|
|
||||||
unused_thread_queue[pool->pool.priority][pool->pool.bound ? 1 : 0];
|
|
||||||
pool->num_threads--;
|
pool->num_threads--;
|
||||||
|
|
||||||
if (!pool->running && !pool->waiting)
|
if (!pool->running && !pool->waiting)
|
||||||
@@ -167,27 +163,27 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
else
|
else
|
||||||
g_async_queue_unlock (pool->queue);
|
g_async_queue_unlock (pool->queue);
|
||||||
|
|
||||||
g_async_queue_lock (unused_queue);
|
g_async_queue_lock (unused_thread_queue);
|
||||||
|
|
||||||
G_LOCK (unused_threads);
|
G_LOCK (unused_threads);
|
||||||
if ((unused_threads >= max_unused_threads &&
|
if ((unused_threads >= max_unused_threads &&
|
||||||
max_unused_threads != -1) || pool->stack_size != 0)
|
max_unused_threads != -1))
|
||||||
{
|
{
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
g_async_queue_unlock (unused_queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
/* Stop this thread */
|
/* Stop this thread */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
unused_threads++;
|
unused_threads++;
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
|
||||||
pool = g_async_queue_pop_unlocked (unused_queue);
|
pool = g_async_queue_pop_unlocked (unused_thread_queue);
|
||||||
|
|
||||||
G_LOCK (unused_threads);
|
G_LOCK (unused_threads);
|
||||||
unused_threads--;
|
unused_threads--;
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
|
||||||
g_async_queue_unlock (unused_queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
|
|
||||||
if (pool == stop_this_thread_marker)
|
if (pool == stop_this_thread_marker)
|
||||||
/* Stop this thread */
|
/* Stop this thread */
|
||||||
@@ -208,35 +204,26 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
GThreadPriority priority = pool->pool.priority;
|
|
||||||
guint bound = pool->pool.bound ? 1 : 0;
|
|
||||||
GAsyncQueue *queue = unused_thread_queue[priority][bound];
|
|
||||||
|
|
||||||
if (pool->num_threads >= pool->max_threads && pool->max_threads != -1)
|
if (pool->num_threads >= pool->max_threads && pool->max_threads != -1)
|
||||||
/* Enough threads are already running */
|
/* Enough threads are already running */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_async_queue_lock (queue);
|
g_async_queue_lock (unused_thread_queue);
|
||||||
|
|
||||||
if (g_async_queue_length_unlocked (queue) < 0)
|
if (g_async_queue_length_unlocked (unused_thread_queue) < 0)
|
||||||
{
|
{
|
||||||
/* First we try a thread with the right priority */
|
g_async_queue_push_unlocked (unused_thread_queue, pool);
|
||||||
g_async_queue_push_unlocked (queue, pool);
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_async_queue_unlock (queue);
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
|
|
||||||
/* We will not search for threads with other priorities, because changing
|
|
||||||
* priority is quite unportable */
|
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
/* No thread was found, we have to start a new one */
|
/* No thread was found, we have to start a new one */
|
||||||
g_thread_create (g_thread_pool_thread_proxy, pool,
|
g_thread_create (g_thread_pool_thread_proxy, pool, FALSE, &local_error);
|
||||||
pool->stack_size, FALSE,
|
|
||||||
bound, priority, &local_error);
|
|
||||||
|
|
||||||
if (local_error)
|
if (local_error)
|
||||||
{
|
{
|
||||||
@@ -257,17 +244,10 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
* is called
|
* is called
|
||||||
* @max_threads: the maximal number of threads to execute concurrently in
|
* @max_threads: the maximal number of threads to execute concurrently in
|
||||||
* the new thread pool, -1 means no limit
|
* the new thread pool, -1 means no limit
|
||||||
* @stack_size: the stack size for the threads of the new thread pool,
|
|
||||||
* 0 means using the standard
|
|
||||||
* @bound: should the threads of the new thread pool be bound?
|
|
||||||
* @priority: a priority for the threads of the new thread pool
|
|
||||||
* @exclusive: should this thread pool be exclusive?
|
* @exclusive: should this thread pool be exclusive?
|
||||||
* @error: return location for error
|
* @error: return location for error
|
||||||
*
|
*
|
||||||
* This function creates a new thread pool. All threads created within
|
* This function creates a new thread pool.
|
||||||
* this thread pool will have the priority @priority and the stack
|
|
||||||
* size @stack_size and will be bound if and only if @bound is
|
|
||||||
* true.
|
|
||||||
*
|
*
|
||||||
* Whenever you call g_thread_pool_push(), either a new thread is
|
* Whenever you call g_thread_pool_push(), either a new thread is
|
||||||
* created or an unused one is reused. At most @max_threads threads
|
* created or an unused one is reused. At most @max_threads threads
|
||||||
@@ -286,12 +266,6 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
|
|||||||
* non-exclusive thread pools. This implies that @max_threads may not
|
* non-exclusive thread pools. This implies that @max_threads may not
|
||||||
* be -1 for exclusive thread pools.
|
* be -1 for exclusive thread pools.
|
||||||
*
|
*
|
||||||
* Note, that only threads from a thread pool with a @stack_size of 0
|
|
||||||
* (which means using the standard stack size) will be globally
|
|
||||||
* reused. Threads from a thread pool with a non-zero stack size will
|
|
||||||
* stay only in this thread pool until it is freed and can thus not be
|
|
||||||
* controlled by the g_thread_pool_set_unused_threads() function.
|
|
||||||
*
|
|
||||||
* @error can be NULL to ignore errors, or non-NULL to report
|
* @error can be NULL to ignore errors, or non-NULL to report
|
||||||
* errors. An error can only occur, when @exclusive is set to @TRUE and
|
* errors. An error can only occur, when @exclusive is set to @TRUE and
|
||||||
* not all @max_threads threads could be created.
|
* not all @max_threads threads could be created.
|
||||||
@@ -302,9 +276,6 @@ GThreadPool*
|
|||||||
g_thread_pool_new (GFunc func,
|
g_thread_pool_new (GFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint max_threads,
|
gint max_threads,
|
||||||
gulong stack_size,
|
|
||||||
gboolean bound,
|
|
||||||
GThreadPriority priority,
|
|
||||||
gboolean exclusive,
|
gboolean exclusive,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -320,10 +291,7 @@ g_thread_pool_new (GFunc func,
|
|||||||
|
|
||||||
retval->pool.func = func;
|
retval->pool.func = func;
|
||||||
retval->pool.user_data = user_data;
|
retval->pool.user_data = user_data;
|
||||||
retval->pool.bound = bound;
|
|
||||||
retval->pool.priority = priority;
|
|
||||||
retval->pool.exclusive = exclusive;
|
retval->pool.exclusive = exclusive;
|
||||||
retval->stack_size = stack_size;
|
|
||||||
retval->queue = g_async_queue_new ();
|
retval->queue = g_async_queue_new ();
|
||||||
retval->max_threads = max_threads;
|
retval->max_threads = max_threads;
|
||||||
retval->num_threads = 0;
|
retval->num_threads = 0;
|
||||||
@@ -335,12 +303,7 @@ g_thread_pool_new (GFunc func,
|
|||||||
{
|
{
|
||||||
inform_mutex = g_mutex_new ();
|
inform_mutex = g_mutex_new ();
|
||||||
inform_cond = g_cond_new ();
|
inform_cond = g_cond_new ();
|
||||||
for (priority = G_THREAD_PRIORITY_LOW;
|
unused_thread_queue = g_async_queue_new ();
|
||||||
priority < G_THREAD_PRIORITY_URGENT + 1; priority++)
|
|
||||||
{
|
|
||||||
unused_thread_queue[priority][0] = g_async_queue_new ();
|
|
||||||
unused_thread_queue[priority][1] = g_async_queue_new ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_UNLOCK (init);
|
G_UNLOCK (init);
|
||||||
@@ -659,37 +622,13 @@ g_thread_pool_set_max_unused_threads (gint max_threads)
|
|||||||
|
|
||||||
if (max_unused_threads < unused_threads && max_unused_threads != -1)
|
if (max_unused_threads < unused_threads && max_unused_threads != -1)
|
||||||
{
|
{
|
||||||
guint close_down_num = unused_threads - max_unused_threads;
|
guint i;
|
||||||
|
|
||||||
while (close_down_num > 0)
|
g_async_queue_lock (unused_thread_queue);
|
||||||
{
|
for (i = unused_threads - max_unused_threads; i > 0; i--)
|
||||||
GThreadPriority priority;
|
g_async_queue_push_unlocked (unused_thread_queue,
|
||||||
guint bound;
|
stop_this_thread_marker);
|
||||||
|
g_async_queue_unlock (unused_thread_queue);
|
||||||
guint old_close_down_num = close_down_num;
|
|
||||||
for (priority = G_THREAD_PRIORITY_LOW;
|
|
||||||
priority < G_THREAD_PRIORITY_URGENT + 1 && close_down_num > 0;
|
|
||||||
priority++)
|
|
||||||
{
|
|
||||||
for (bound = 0; bound < 2; bound++)
|
|
||||||
{
|
|
||||||
GAsyncQueue *queue = unused_thread_queue[priority][bound];
|
|
||||||
g_async_queue_lock (queue);
|
|
||||||
|
|
||||||
if (g_async_queue_length_unlocked (queue) < 0)
|
|
||||||
{
|
|
||||||
g_async_queue_push_unlocked (queue,
|
|
||||||
stop_this_thread_marker);
|
|
||||||
close_down_num--;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_async_queue_unlock (queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just to make sure, there are no counting problems */
|
|
||||||
g_assert (old_close_down_num != close_down_num);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_UNLOCK (unused_threads);
|
G_UNLOCK (unused_threads);
|
||||||
|
@@ -42,22 +42,17 @@ struct _GThreadPool
|
|||||||
{
|
{
|
||||||
GFunc func;
|
GFunc func;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
gboolean bound;
|
|
||||||
GThreadPriority priority;
|
|
||||||
gboolean exclusive;
|
gboolean exclusive;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get a thread pool with the function func, at most max_threads may
|
/* Get a thread pool with the function func, at most max_threads may
|
||||||
* run at a time (max_threads == -1 means no limit), stack_size, bound,
|
* run at a time (max_threads == -1 means no limit), exclusive == TRUE
|
||||||
* priority like in g_thread_create, exclusive == TRUE means, that the threads
|
* means, that the threads shouldn't be shared and that they will be
|
||||||
* shouldn't be shared and that they will be prestarted (otherwise they are
|
* prestarted (otherwise they are started as needed) user_data is the
|
||||||
* started as needed) user_data is the 2nd argument to the func */
|
* 2nd argument to the func */
|
||||||
GThreadPool* g_thread_pool_new (GFunc func,
|
GThreadPool* g_thread_pool_new (GFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gint max_threads,
|
gint max_threads,
|
||||||
gulong stack_size,
|
|
||||||
gboolean bound,
|
|
||||||
GThreadPriority priority,
|
|
||||||
gboolean exclusive,
|
gboolean exclusive,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
@@ -267,8 +267,7 @@ create_adder_thread (void)
|
|||||||
sub_channels[0] = in_channels[0];
|
sub_channels[0] = in_channels[0];
|
||||||
sub_channels[1] = out_channels[1];
|
sub_channels[1] = out_channels[1];
|
||||||
|
|
||||||
g_thread_create (adder_thread, sub_channels, 0,
|
g_thread_create (adder_thread, sub_channels, FALSE, &err);
|
||||||
FALSE, TRUE, G_THREAD_PRIORITY_NORMAL, &err);
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@@ -27,9 +27,8 @@ test_g_mutex (void)
|
|||||||
|
|
||||||
g_assert (g_mutex_trylock (test_g_mutex_mutex));
|
g_assert (g_mutex_trylock (test_g_mutex_mutex));
|
||||||
g_assert (G_TRYLOCK (test_g_mutex));
|
g_assert (G_TRYLOCK (test_g_mutex));
|
||||||
thread = g_thread_create (test_g_mutex_thread,
|
thread = g_thread_create (test_g_mutex_thread, GINT_TO_POINTER (42),
|
||||||
GINT_TO_POINTER (42),
|
TRUE, NULL);
|
||||||
0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL, NULL);
|
|
||||||
g_usleep (G_USEC_PER_SEC);
|
g_usleep (G_USEC_PER_SEC);
|
||||||
test_g_mutex_int = 42;
|
test_g_mutex_int = 42;
|
||||||
G_UNLOCK (test_g_mutex);
|
G_UNLOCK (test_g_mutex);
|
||||||
@@ -68,8 +67,7 @@ test_g_static_rec_mutex (void)
|
|||||||
|
|
||||||
g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex));
|
g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex));
|
||||||
thread = g_thread_create (test_g_static_rec_mutex_thread,
|
thread = g_thread_create (test_g_static_rec_mutex_thread,
|
||||||
GINT_TO_POINTER (42),
|
GINT_TO_POINTER (42), TRUE, NULL);
|
||||||
0, TRUE, TRUE, G_THREAD_PRIORITY_NORMAL, NULL);
|
|
||||||
g_usleep (G_USEC_PER_SEC);
|
g_usleep (G_USEC_PER_SEC);
|
||||||
g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex));
|
g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex));
|
||||||
g_usleep (G_USEC_PER_SEC);
|
g_usleep (G_USEC_PER_SEC);
|
||||||
@@ -180,9 +178,7 @@ test_g_static_private (void)
|
|||||||
for (i = 0; i < THREADS; i++)
|
for (i = 0; i < THREADS; i++)
|
||||||
{
|
{
|
||||||
threads[i] = g_thread_create (test_g_static_private_thread,
|
threads[i] = g_thread_create (test_g_static_private_thread,
|
||||||
GINT_TO_POINTER (i),
|
GINT_TO_POINTER (i), TRUE, NULL);
|
||||||
0, TRUE, TRUE,
|
|
||||||
G_THREAD_PRIORITY_NORMAL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Busy wait is not nice but that's just a test */
|
/* Busy wait is not nice but that's just a test */
|
||||||
@@ -269,8 +265,7 @@ test_g_static_rw_lock ()
|
|||||||
for (i = 0; i < THREADS; i++)
|
for (i = 0; i < THREADS; i++)
|
||||||
{
|
{
|
||||||
threads[i] = g_thread_create (test_g_static_rw_lock_thread,
|
threads[i] = g_thread_create (test_g_static_rw_lock_thread,
|
||||||
0, 0, TRUE, TRUE,
|
NULL, TRUE, NULL);
|
||||||
G_THREAD_PRIORITY_NORMAL, NULL);
|
|
||||||
}
|
}
|
||||||
g_usleep (G_USEC_PER_SEC);
|
g_usleep (G_USEC_PER_SEC);
|
||||||
test_g_static_rw_lock_run = FALSE;
|
test_g_static_rw_lock_run = FALSE;
|
||||||
|
@@ -32,12 +32,9 @@ main (int argc,
|
|||||||
guint i;
|
guint i;
|
||||||
g_thread_init (NULL);
|
g_thread_init (NULL);
|
||||||
|
|
||||||
pool1 = g_thread_pool_new (thread_pool_func, 3, 0, FALSE,
|
pool1 = g_thread_pool_new (thread_pool_func, NULL, 3, FALSE, NULL);
|
||||||
G_THREAD_PRIORITY_NORMAL, FALSE, NULL, NULL);
|
pool2 = g_thread_pool_new (thread_pool_func, NULL, 5, TRUE, NULL);
|
||||||
pool2 = g_thread_pool_new (thread_pool_func, 5, 0, FALSE,
|
pool3 = g_thread_pool_new (thread_pool_func, NULL, 7, TRUE, NULL);
|
||||||
G_THREAD_PRIORITY_LOW, FALSE, NULL, NULL);
|
|
||||||
pool3 = g_thread_pool_new (thread_pool_func, 7, 0, FALSE,
|
|
||||||
G_THREAD_PRIORITY_LOW, TRUE, NULL, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < RUNS; i++)
|
for (i = 0; i < RUNS; i++)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user