Merge branch 'threadpool-sched-getattr-runtime-check' into 'master'

Add runtime checks and a fallback if we can't get the thread scheduler settings

Closes #2007

See merge request GNOME/glib!1327
This commit is contained in:
Philip Withnall 2020-01-20 10:14:11 +00:00
commit 2a0b1d8ba0
6 changed files with 47 additions and 34 deletions

View File

@ -1162,7 +1162,7 @@ g_system_thread_free (GRealThread *thread)
g_slice_free (GThreadPosix, pt);
}
void
gboolean
g_system_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings)
{
/* FIXME: Implement the same for macOS and the BSDs so it doesn't go through
@ -1202,11 +1202,18 @@ g_system_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_sett
}
else
{
g_error ("Failed to get thread scheduler attributes: %s", g_strerror (errsv));
g_debug ("Failed to get thread scheduler attributes: %s", g_strerror (errsv));
g_free (scheduler_settings->attr);
return FALSE;
}
}
}
while (res == -1);
return TRUE;
#else
return FALSE;
#endif
}

View File

@ -428,11 +428,13 @@ g_thread_win32_proxy (gpointer data)
return 0;
}
void
gboolean
g_system_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings)
{
HANDLE current_thread = GetCurrentThread ();
scheduler_settings->thread_prio = GetThreadPriority (current_thread);
return TRUE;
}
GRealThread *

View File

@ -902,11 +902,12 @@ g_thread_new_internal (const gchar *name,
name, func, data, error);
}
void
gboolean
g_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings)
{
g_return_if_fail (scheduler_settings != NULL);
g_system_thread_get_scheduler_settings (scheduler_settings);
g_return_val_if_fail (scheduler_settings != NULL, FALSE);
return g_system_thread_get_scheduler_settings (scheduler_settings);
}
/**

View File

@ -114,9 +114,9 @@ static gint max_unused_threads = 2;
static gint kill_unused_threads = 0;
static guint max_idle_time = 15 * 1000;
#ifdef HAVE_GTHREAD_SCHEDULER_SETTINGS
static GThreadSchedulerSettings shared_thread_scheduler_settings;
#else
static gboolean have_shared_thread_scheduler_settings = FALSE;
typedef struct
{
/* Either thread or error are set in the end. Both transfer-full. */
@ -127,7 +127,6 @@ typedef struct
static GCond spawn_thread_cond;
static GAsyncQueue *spawn_thread_queue;
#endif
static void g_thread_pool_queue_push_unlocked (GRealThreadPool *pool,
gpointer data);
@ -294,7 +293,6 @@ g_thread_pool_wait_for_new_task (GRealThreadPool *pool)
return task;
}
#ifndef HAVE_GTHREAD_SCHEDULER_SETTINGS
static gpointer
g_thread_pool_spawn_thread (gpointer data)
{
@ -326,7 +324,6 @@ g_thread_pool_spawn_thread (gpointer data)
return NULL;
}
#endif
static gpointer
g_thread_pool_thread_proxy (gpointer data)
@ -475,23 +472,26 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
* providing them if supported by the GThread implementation or by
* going via our helper thread.
*/
#ifdef HAVE_GTHREAD_SCHEDULER_SETTINGS
thread = g_thread_new_internal (name, g_thread_proxy, g_thread_pool_thread_proxy, pool, 0, &shared_thread_scheduler_settings, error);
#else
SpawnThreadData spawn_thread_data = { (GThreadPool *) pool, NULL, NULL };
if (have_shared_thread_scheduler_settings)
{
thread = g_thread_new_internal (name, g_thread_proxy, g_thread_pool_thread_proxy, pool, 0, &shared_thread_scheduler_settings, error);
}
else
{
SpawnThreadData spawn_thread_data = { (GThreadPool *) pool, NULL, NULL };
g_async_queue_lock (spawn_thread_queue);
g_async_queue_lock (spawn_thread_queue);
g_async_queue_push_unlocked (spawn_thread_queue, &spawn_thread_data);
g_async_queue_push_unlocked (spawn_thread_queue, &spawn_thread_data);
while (!spawn_thread_data.thread && !spawn_thread_data.error)
g_cond_wait (&spawn_thread_cond, _g_async_queue_get_mutex (spawn_thread_queue));
while (!spawn_thread_data.thread && !spawn_thread_data.error)
g_cond_wait (&spawn_thread_cond, _g_async_queue_get_mutex (spawn_thread_queue));
thread = spawn_thread_data.thread;
if (!thread)
g_propagate_error (error, g_steal_pointer (&spawn_thread_data.error));
g_async_queue_unlock (spawn_thread_queue);
#endif
thread = spawn_thread_data.thread;
if (!thread)
g_propagate_error (error, g_steal_pointer (&spawn_thread_data.error));
g_async_queue_unlock (spawn_thread_queue);
}
}
if (thread == NULL)
@ -605,13 +605,16 @@ g_thread_pool_new (GFunc func,
*/
if (!exclusive)
{
#ifdef HAVE_GTHREAD_SCHEDULER_SETTINGS
g_thread_get_scheduler_settings (&shared_thread_scheduler_settings);
#else
spawn_thread_queue = g_async_queue_new ();
g_cond_init (&spawn_thread_cond);
g_thread_new ("pool-spawner", g_thread_pool_spawn_thread, NULL);
#endif
if (g_thread_get_scheduler_settings (&shared_thread_scheduler_settings))
{
have_shared_thread_scheduler_settings = TRUE;
}
else
{
spawn_thread_queue = g_async_queue_new ();
g_cond_init (&spawn_thread_cond);
g_thread_new ("pool-spawner", g_thread_pool_spawn_thread, NULL);
}
}
}
G_UNLOCK (init);

View File

@ -74,7 +74,7 @@ void g_system_thread_free (GRealThread *thread);
void g_system_thread_exit (void);
void g_system_thread_set_name (const gchar *name);
void g_system_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings);
gboolean g_system_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings);
/* gthread.c */
GThread *g_thread_new_internal (const gchar *name,
@ -85,7 +85,7 @@ GThread *g_thread_new_internal (const gchar *name,
const GThreadSchedulerSettings *scheduler_settings,
GError **error);
void g_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings);
gboolean g_thread_get_scheduler_settings (GThreadSchedulerSettings *scheduler_settings);
gpointer g_thread_proxy (gpointer thread);

View File

@ -1731,7 +1731,7 @@ else
glib_conf.set('HAVE_PTHREAD_GETNAME_NP', 1)
endif
if cc.has_header_symbol('sys/syscall.h', 'SYS_sched_getattr,')
if cc.has_header_symbol('sys/syscall.h', 'SYS_sched_getattr')
glib_conf.set('HAVE_SYS_SCHED_GETATTR', 1)
endif