thread/impl: Add API to tell whether its realtime scheduled

Will be used by thread impl's to decide whether they can rely on real
time scheduling or not.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
Jonas Ådahl 2022-10-26 19:33:49 +02:00
parent e92e4fe64d
commit 6da3e9eb69
4 changed files with 33 additions and 3 deletions

View File

@ -56,6 +56,8 @@ typedef struct _MetaThreadImplPrivate
GMainContext *thread_context;
GSource *impl_source;
GAsyncQueue *task_queue;
gboolean is_realtime;
} MetaThreadImplPrivate;
struct _MetaThreadTask
@ -551,7 +553,8 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
}
void
meta_thread_impl_run (MetaThreadImpl *thread_impl)
meta_thread_impl_run (MetaThreadImpl *thread_impl,
MetaThreadImplRunFlags flags)
{
MetaThreadImplPrivate *priv =
meta_thread_impl_get_instance_private (thread_impl);
@ -559,7 +562,9 @@ meta_thread_impl_run (MetaThreadImpl *thread_impl)
meta_assert_in_thread_impl (priv->thread);
priv->loop = g_main_loop_new (priv->thread_context, FALSE);
priv->is_realtime = !!(flags & META_THREAD_IMPL_RUN_FLAG_REALTIME);
g_main_loop_run (priv->loop);
priv->is_realtime = FALSE;
}
void
@ -572,3 +577,12 @@ meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
g_async_queue_push (priv->task_queue, task);
g_main_context_wakeup (priv->thread_context);
}
gboolean
meta_thread_impl_is_realtime (MetaThreadImpl *thread_impl)
{
MetaThreadImplPrivate *priv =
meta_thread_impl_get_instance_private (thread_impl);
return priv->is_realtime;
}

View File

@ -27,6 +27,12 @@
typedef struct _MetaThread MetaThread;
typedef enum _MetaThreadImplRunFlags
{
META_THREAD_IMPL_RUN_FLAG_NONE = 0,
META_THREAD_IMPL_RUN_FLAG_REALTIME = 1 << 0,
} MetaThreadImplRunFlags;
#define META_TYPE_THREAD_IMPL (meta_thread_impl_get_type ())
META_EXPORT_TEST
G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl,
@ -67,12 +73,16 @@ void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
void meta_thread_impl_terminate (MetaThreadImpl *thread_impl);
void meta_thread_impl_run (MetaThreadImpl *thread_impl);
void meta_thread_impl_run (MetaThreadImpl *thread_impl,
MetaThreadImplRunFlags flags);
int meta_thread_impl_dispatch (MetaThreadImpl *thread_impl);
gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl);
META_EXPORT_TEST
gboolean meta_thread_impl_is_realtime (MetaThreadImpl *thread_impl);
MetaThreadTask * meta_thread_task_new (MetaThreadTaskFunc func,
gpointer user_data,
GDestroyNotify user_data_destroy,

View File

@ -296,6 +296,7 @@ thread_impl_func (gpointer user_data)
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
MetaContext *context = meta_backend_get_context (priv->backend);
MetaThreadImpl *impl = priv->impl;
MetaThreadImplRunFlags run_flags = META_THREAD_IMPL_RUN_FLAG_NONE;
#ifdef HAVE_PROFILER
GMainContext *thread_context = meta_thread_impl_get_main_context (impl);
MetaProfiler *profiler = meta_context_get_profiler (context);
@ -320,10 +321,11 @@ thread_impl_func (gpointer user_data)
else
{
g_message ("Made thread '%s' realtime scheduled", priv->name);
run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME;
}
}
meta_thread_impl_run (impl);
meta_thread_impl_run (impl, run_flags);
#ifdef HAVE_PROFILER
meta_profiler_unregister_thread (profiler, thread_context);

View File

@ -1152,6 +1152,8 @@ assert_realtime (MetaThreadImpl *thread_impl,
g_autoptr (GVariant) priority_variant = NULL;
uint32_t priority = 0;
g_assert_true (meta_thread_impl_is_realtime (thread_impl));
ret = call_rtkit_mock_method ("GetThreadPriority",
g_variant_new ("(t)", gettid ()));
@ -1199,6 +1201,8 @@ assert_no_realtime (MetaThreadImpl *thread_impl,
g_autoptr (GVariant) priority_variant = NULL;
uint32_t priority = UINT32_MAX;
g_assert_false (meta_thread_impl_is_realtime (thread_impl));
ret = call_rtkit_mock_method ("GetThreadPriority",
g_variant_new ("(t)", gettid ()));