mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-16 12:45:13 +01:00
Merge branch 'thread-pool-slow-really-stops-unused' into 'main'
glib/test/thread-pool-slow: Ensure all unused threads are really stopped Closes #2685 See merge request GNOME/glib!2804
This commit is contained in:
commit
6997ebcfd7
@ -167,8 +167,6 @@ g_thread_pool_wait_for_new_pool (void)
|
|||||||
local_max_idle_time = g_atomic_int_get (&max_idle_time);
|
local_max_idle_time = g_atomic_int_get (&max_idle_time);
|
||||||
last_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial);
|
last_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial);
|
||||||
|
|
||||||
g_atomic_int_inc (&unused_threads);
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((guint) g_atomic_int_get (&unused_threads) >= local_max_unused_threads)
|
if ((guint) g_atomic_int_get (&unused_threads) >= local_max_unused_threads)
|
||||||
@ -237,8 +235,6 @@ g_thread_pool_wait_for_new_pool (void)
|
|||||||
}
|
}
|
||||||
while (pool == wakeup_thread_marker);
|
while (pool == wakeup_thread_marker);
|
||||||
|
|
||||||
g_atomic_int_add (&unused_threads, -1);
|
|
||||||
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,12 +401,16 @@ g_thread_pool_thread_proxy (gpointer data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_atomic_int_inc (&unused_threads);
|
||||||
g_async_queue_unlock (pool->queue);
|
g_async_queue_unlock (pool->queue);
|
||||||
|
|
||||||
if (free_pool)
|
if (free_pool)
|
||||||
g_thread_pool_free_internal (pool);
|
g_thread_pool_free_internal (pool);
|
||||||
|
|
||||||
if ((pool = g_thread_pool_wait_for_new_pool ()) == NULL)
|
pool = g_thread_pool_wait_for_new_pool ();
|
||||||
|
g_atomic_int_add (&unused_threads, -1);
|
||||||
|
|
||||||
|
if (pool == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
g_async_queue_lock (pool->queue);
|
g_async_queue_lock (pool->queue);
|
||||||
|
@ -62,47 +62,85 @@ test_thread_functions (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thread_wait_func (gpointer data,
|
test_thread_stop_unused (void)
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
guint timeout_ms = GPOINTER_TO_UINT (data);
|
GThreadPool *pool;
|
||||||
guint *n_threads_executed = user_data;
|
guint i;
|
||||||
|
guint limit = 100;
|
||||||
|
|
||||||
g_usleep (timeout_ms);
|
/* Spawn a few threads. */
|
||||||
|
g_thread_pool_set_max_unused_threads (-1);
|
||||||
|
pool = g_thread_pool_new ((GFunc) g_usleep, NULL, -1, FALSE, NULL);
|
||||||
|
|
||||||
g_atomic_int_inc (n_threads_executed);
|
for (i = 0; i < limit; i++)
|
||||||
|
g_thread_pool_push (pool, GUINT_TO_POINTER (1000), NULL);
|
||||||
|
|
||||||
|
/* Wait for the threads to migrate. */
|
||||||
|
while (g_thread_pool_get_num_threads (pool) != 0)
|
||||||
|
g_usleep (100);
|
||||||
|
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_threads (pool), ==, 0);
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_unused_threads (), >, 0);
|
||||||
|
|
||||||
|
/* Wait for threads to die. */
|
||||||
|
g_thread_pool_stop_unused_threads ();
|
||||||
|
|
||||||
|
while (g_thread_pool_get_num_unused_threads () != 0)
|
||||||
|
g_usleep (100);
|
||||||
|
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_unused_threads (), ==, 0);
|
||||||
|
|
||||||
|
g_thread_pool_set_max_unused_threads (MAX_THREADS);
|
||||||
|
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_threads (pool), ==, 0);
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_unused_threads (), ==, 0);
|
||||||
|
|
||||||
|
g_thread_pool_free (pool, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_thread_stop_unused (void)
|
test_thread_stop_unused_multiple (void)
|
||||||
{
|
{
|
||||||
GThreadPool *pool;
|
GThreadPool *pools[10];
|
||||||
guint i;
|
guint i, j;
|
||||||
guint limit = 100;
|
const guint limit = 10;
|
||||||
guint n_threads_executed = 0;
|
gboolean all_stopped;
|
||||||
|
|
||||||
/* Spawn a few threads. */
|
/* Spawn a few threads. */
|
||||||
g_thread_pool_set_max_unused_threads (-1);
|
g_thread_pool_set_max_unused_threads (-1);
|
||||||
pool = g_thread_pool_new (thread_wait_func, &n_threads_executed, -1, FALSE, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < limit; i++)
|
for (i = 0; i < G_N_ELEMENTS (pools); i++)
|
||||||
g_thread_pool_push (pool, GUINT_TO_POINTER (1000), NULL);
|
{
|
||||||
|
pools[i] = g_thread_pool_new ((GFunc) g_usleep, NULL, -1, FALSE, NULL);
|
||||||
|
|
||||||
/* Wait for the threads to migrate. */
|
for (j = 0; j < limit; j++)
|
||||||
while ((guint) g_atomic_int_get (&n_threads_executed) < limit)
|
g_thread_pool_push (pools[i], GUINT_TO_POINTER (100), NULL);
|
||||||
g_usleep (100);
|
}
|
||||||
|
|
||||||
g_thread_pool_stop_unused_threads ();
|
all_stopped = FALSE;
|
||||||
|
while (!all_stopped)
|
||||||
|
{
|
||||||
|
all_stopped = TRUE;
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (pools); i++)
|
||||||
|
all_stopped &= (g_thread_pool_get_num_threads (pools[i]) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for threads to die. */
|
for (i = 0; i < G_N_ELEMENTS (pools); i++)
|
||||||
while (g_thread_pool_get_num_unused_threads () != 0)
|
{
|
||||||
g_usleep (100);
|
g_assert_cmpuint (g_thread_pool_get_num_threads (pools[i]), ==, 0);
|
||||||
|
g_assert_cmpuint (g_thread_pool_get_num_unused_threads (), >, 0);
|
||||||
|
}
|
||||||
|
|
||||||
g_assert_cmpint (g_thread_pool_get_num_unused_threads (), ==, 0);
|
/* Wait for threads to die. */
|
||||||
|
g_thread_pool_stop_unused_threads ();
|
||||||
|
|
||||||
g_thread_pool_set_max_unused_threads (MAX_THREADS);
|
while (g_thread_pool_get_num_unused_threads () != 0)
|
||||||
|
g_usleep (100);
|
||||||
|
|
||||||
g_thread_pool_free (pool, FALSE, TRUE);
|
g_assert_cmpuint (g_thread_pool_get_num_unused_threads (), ==, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (pools); i++)
|
||||||
|
g_thread_pool_free (pools[i], FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -346,6 +384,9 @@ test_check_start_and_stop (gpointer user_data)
|
|||||||
test_thread_stop_unused ();
|
test_thread_stop_unused ();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
|
test_thread_stop_unused_multiple ();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
test_thread_idle_time ();
|
test_thread_idle_time ();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -375,7 +416,7 @@ test_check_start_and_stop (gpointer user_data)
|
|||||||
G_UNLOCK (thread_counter_sort);
|
G_UNLOCK (thread_counter_sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_number == 7) {
|
if (test_number == 8) {
|
||||||
guint idle;
|
guint idle;
|
||||||
|
|
||||||
idle = g_thread_pool_get_num_unused_threads ();
|
idle = g_thread_pool_get_num_unused_threads ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user