thread: Make thread priority preference more generic
Either prefer "normal" or "realtime", via an enum, instead of a boolean. Also make it configurable with an env var `MUTTER_DEBUG_KMS_SCHEDULING_PRIORITY`, which can be set to either `normal` or `realtime`. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4124>
This commit is contained in:
parent
52aa84b3c3
commit
1a6c0ea3d0
@ -1696,7 +1696,15 @@ is_using_deadline_timer (MetaKmsImplDevice *impl_device)
|
|||||||
MetaKmsImpl *impl = meta_kms_impl_device_get_impl (impl_device);
|
MetaKmsImpl *impl = meta_kms_impl_device_get_impl (impl_device);
|
||||||
MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl);
|
MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl);
|
||||||
|
|
||||||
return meta_thread_impl_is_realtime (thread_impl);
|
switch (meta_thread_impl_get_scheduling_priority (thread_impl))
|
||||||
|
{
|
||||||
|
case META_SCHEDULING_PRIORITY_NORMAL:
|
||||||
|
return FALSE;
|
||||||
|
case META_SCHEDULING_PRIORITY_REALTIME:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,8 +382,9 @@ meta_kms_new (MetaBackend *backend,
|
|||||||
MetaUdev *udev = meta_backend_native_get_udev (backend_native);
|
MetaUdev *udev = meta_backend_native_get_udev (backend_native);
|
||||||
MetaKms *kms;
|
MetaKms *kms;
|
||||||
const char *thread_type_string;
|
const char *thread_type_string;
|
||||||
|
const char *preferred_scheduling_priority_string;
|
||||||
MetaThreadType thread_type = META_THREAD_TYPE_KERNEL;
|
MetaThreadType thread_type = META_THREAD_TYPE_KERNEL;
|
||||||
gboolean wants_realtime_scheduling;
|
MetaSchedulingPriority preferred_scheduling_priority;
|
||||||
|
|
||||||
thread_type_string = g_getenv ("MUTTER_DEBUG_KMS_THREAD_TYPE");
|
thread_type_string = g_getenv ("MUTTER_DEBUG_KMS_THREAD_TYPE");
|
||||||
if (thread_type_string)
|
if (thread_type_string)
|
||||||
@ -395,17 +396,36 @@ meta_kms_new (MetaBackend *backend,
|
|||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
wants_realtime_scheduling = !(flags & META_KMS_FLAG_NO_MODE_SETTING);
|
|
||||||
if (flags & META_KMS_FLAG_NO_MODE_SETTING)
|
if (flags & META_KMS_FLAG_NO_MODE_SETTING)
|
||||||
thread_type = META_THREAD_TYPE_USER;
|
thread_type = META_THREAD_TYPE_USER;
|
||||||
|
|
||||||
|
preferred_scheduling_priority_string =
|
||||||
|
g_getenv ("MUTTER_DEBUG_KMS_SCHEDULING_PRIORITY");
|
||||||
|
if (preferred_scheduling_priority_string)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (preferred_scheduling_priority_string,
|
||||||
|
"normal") == 0)
|
||||||
|
preferred_scheduling_priority = META_SCHEDULING_PRIORITY_NORMAL;
|
||||||
|
else if (g_strcmp0 (preferred_scheduling_priority_string,
|
||||||
|
"realtime") == 0)
|
||||||
|
preferred_scheduling_priority = META_SCHEDULING_PRIORITY_REALTIME;
|
||||||
|
else
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flags & META_KMS_FLAG_NO_MODE_SETTING)
|
||||||
|
preferred_scheduling_priority = META_SCHEDULING_PRIORITY_NORMAL;
|
||||||
|
else
|
||||||
|
preferred_scheduling_priority = META_SCHEDULING_PRIORITY_REALTIME;
|
||||||
|
}
|
||||||
|
|
||||||
kms = g_initable_new (META_TYPE_KMS,
|
kms = g_initable_new (META_TYPE_KMS,
|
||||||
NULL, error,
|
NULL, error,
|
||||||
"backend", backend,
|
"backend", backend,
|
||||||
"name", "KMS thread",
|
"name", "KMS thread",
|
||||||
"thread-type", thread_type,
|
"thread-type", thread_type,
|
||||||
"wants-realtime", wants_realtime_scheduling,
|
"preferred-scheduling-priority", preferred_scheduling_priority,
|
||||||
NULL);
|
NULL);
|
||||||
kms->flags = flags;
|
kms->flags = flags;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ typedef struct _MetaThreadImplPrivate
|
|||||||
GSource *impl_source;
|
GSource *impl_source;
|
||||||
GAsyncQueue *task_queue;
|
GAsyncQueue *task_queue;
|
||||||
|
|
||||||
gboolean is_realtime;
|
MetaSchedulingPriority scheduling_priority;
|
||||||
} MetaThreadImplPrivate;
|
} MetaThreadImplPrivate;
|
||||||
|
|
||||||
struct _MetaThreadTask
|
struct _MetaThreadTask
|
||||||
@ -579,7 +579,7 @@ meta_thread_impl_setup (MetaThreadImpl *thread_impl)
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||||
MetaThreadImplRunFlags flags)
|
MetaSchedulingPriority scheduling_priority)
|
||||||
{
|
{
|
||||||
MetaThreadImplPrivate *priv =
|
MetaThreadImplPrivate *priv =
|
||||||
meta_thread_impl_get_instance_private (thread_impl);
|
meta_thread_impl_get_instance_private (thread_impl);
|
||||||
@ -587,9 +587,8 @@ meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
|||||||
meta_assert_in_thread_impl (priv->thread);
|
meta_assert_in_thread_impl (priv->thread);
|
||||||
|
|
||||||
priv->loop = g_main_loop_new (priv->thread_context, FALSE);
|
priv->loop = g_main_loop_new (priv->thread_context, FALSE);
|
||||||
priv->is_realtime = !!(flags & META_THREAD_IMPL_RUN_FLAG_REALTIME);
|
priv->scheduling_priority = scheduling_priority;
|
||||||
g_main_loop_run (priv->loop);
|
g_main_loop_run (priv->loop);
|
||||||
priv->is_realtime = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -606,11 +605,11 @@ meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
|||||||
g_async_queue_unlock (priv->task_queue);
|
g_async_queue_unlock (priv->task_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
MetaSchedulingPriority
|
||||||
meta_thread_impl_is_realtime (MetaThreadImpl *thread_impl)
|
meta_thread_impl_get_scheduling_priority (MetaThreadImpl *thread_impl)
|
||||||
{
|
{
|
||||||
MetaThreadImplPrivate *priv =
|
MetaThreadImplPrivate *priv =
|
||||||
meta_thread_impl_get_instance_private (thread_impl);
|
meta_thread_impl_get_instance_private (thread_impl);
|
||||||
|
|
||||||
return priv->is_realtime;
|
return priv->scheduling_priority;
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,6 @@
|
|||||||
|
|
||||||
typedef struct _MetaThread MetaThread;
|
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 ())
|
#define META_TYPE_THREAD_IMPL (meta_thread_impl_get_type ())
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl,
|
G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl,
|
||||||
@ -75,14 +69,14 @@ void meta_thread_impl_terminate (MetaThreadImpl *thread_impl);
|
|||||||
void meta_thread_impl_setup (MetaThreadImpl *thread_impl);
|
void meta_thread_impl_setup (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
void meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
void meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||||
MetaThreadImplRunFlags flags);
|
MetaSchedulingPriority scheduling_priority);
|
||||||
|
|
||||||
int meta_thread_impl_dispatch (MetaThreadImpl *thread_impl);
|
int meta_thread_impl_dispatch (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl);
|
gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
gboolean meta_thread_impl_is_realtime (MetaThreadImpl *thread_impl);
|
MetaSchedulingPriority meta_thread_impl_get_scheduling_priority (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
MetaThreadTask * meta_thread_task_new (MetaThreadTaskFunc func,
|
MetaThreadTask * meta_thread_task_new (MetaThreadTaskFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
|
@ -36,7 +36,7 @@ enum
|
|||||||
PROP_BACKEND,
|
PROP_BACKEND,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
PROP_THREAD_TYPE,
|
PROP_THREAD_TYPE,
|
||||||
PROP_WANTS_REALTIME,
|
PROP_PREFERED_SCHEDULING_PRIORITY,
|
||||||
|
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
@ -71,7 +71,7 @@ typedef struct _MetaThreadPrivate
|
|||||||
GMainContext *main_context;
|
GMainContext *main_context;
|
||||||
|
|
||||||
MetaThreadImpl *impl;
|
MetaThreadImpl *impl;
|
||||||
gboolean wants_realtime;
|
MetaSchedulingPriority preferred_scheduling_priority;
|
||||||
gboolean waiting_for_impl_task;
|
gboolean waiting_for_impl_task;
|
||||||
GSource *wrapper_source;
|
GSource *wrapper_source;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ typedef struct _MetaThreadPrivate
|
|||||||
pid_t thread_id;
|
pid_t thread_id;
|
||||||
GMutex init_mutex;
|
GMutex init_mutex;
|
||||||
int realtime_inhibit_count;
|
int realtime_inhibit_count;
|
||||||
gboolean is_realtime;
|
MetaSchedulingPriority scheduling_priority;
|
||||||
} kernel;
|
} kernel;
|
||||||
} MetaThreadPrivate;
|
} MetaThreadPrivate;
|
||||||
|
|
||||||
@ -106,6 +106,20 @@ G_DEFINE_TYPE_WITH_CODE (MetaThread, meta_thread, G_TYPE_OBJECT,
|
|||||||
g_type_add_class_private (g_define_type_id,
|
g_type_add_class_private (g_define_type_id,
|
||||||
sizeof (MetaThreadClassPrivate)))
|
sizeof (MetaThreadClassPrivate)))
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
meta_scheduling_priority_to_string (MetaSchedulingPriority priority)
|
||||||
|
{
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case META_SCHEDULING_PRIORITY_NORMAL:
|
||||||
|
return "normal";
|
||||||
|
case META_SCHEDULING_PRIORITY_REALTIME:
|
||||||
|
return "realtime";
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_thread_callback_data_free (MetaThreadCallbackData *callback_data)
|
meta_thread_callback_data_free (MetaThreadCallbackData *callback_data)
|
||||||
{
|
{
|
||||||
@ -134,8 +148,8 @@ meta_thread_get_property (GObject *object,
|
|||||||
case PROP_THREAD_TYPE:
|
case PROP_THREAD_TYPE:
|
||||||
g_value_set_enum (value, priv->thread_type);
|
g_value_set_enum (value, priv->thread_type);
|
||||||
break;
|
break;
|
||||||
case PROP_WANTS_REALTIME:
|
case PROP_PREFERED_SCHEDULING_PRIORITY:
|
||||||
g_value_set_boolean (value, priv->wants_realtime);
|
g_value_set_enum (value, priv->preferred_scheduling_priority);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -163,8 +177,8 @@ meta_thread_set_property (GObject *object,
|
|||||||
case PROP_THREAD_TYPE:
|
case PROP_THREAD_TYPE:
|
||||||
priv->thread_type = g_value_get_enum (value);
|
priv->thread_type = g_value_get_enum (value);
|
||||||
break;
|
break;
|
||||||
case PROP_WANTS_REALTIME:
|
case PROP_PREFERED_SCHEDULING_PRIORITY:
|
||||||
priv->wants_realtime = g_value_get_boolean (value);
|
priv->preferred_scheduling_priority = g_value_get_enum (value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -342,7 +356,8 @@ can_use_realtime_scheduling_in_impl (MetaThread *thread)
|
|||||||
case META_THREAD_TYPE_USER:
|
case META_THREAD_TYPE_USER:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case META_THREAD_TYPE_KERNEL:
|
case META_THREAD_TYPE_KERNEL:
|
||||||
return priv->wants_realtime;
|
return (priv->preferred_scheduling_priority ==
|
||||||
|
META_SCHEDULING_PRIORITY_REALTIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@ -358,19 +373,23 @@ should_use_realtime_scheduling_in_impl (MetaThread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sync_realtime_scheduling_in_impl (MetaThread *thread)
|
sync_scheduling_priority_in_impl (MetaThread *thread)
|
||||||
{
|
{
|
||||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||||
g_autoptr (GError) error = NULL;
|
g_autoptr (GError) error = NULL;
|
||||||
gboolean should_be_realtime;
|
MetaSchedulingPriority scheduling_priority;
|
||||||
|
|
||||||
should_be_realtime = should_use_realtime_scheduling_in_impl (thread);
|
if (should_use_realtime_scheduling_in_impl (thread))
|
||||||
|
scheduling_priority = META_SCHEDULING_PRIORITY_REALTIME;
|
||||||
|
else
|
||||||
|
scheduling_priority = META_SCHEDULING_PRIORITY_NORMAL;
|
||||||
|
|
||||||
if (should_be_realtime == priv->kernel.is_realtime)
|
if (scheduling_priority == priv->kernel.scheduling_priority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (should_be_realtime)
|
switch (scheduling_priority)
|
||||||
{
|
{
|
||||||
|
case META_SCHEDULING_PRIORITY_REALTIME:
|
||||||
if (!request_realtime_scheduling (thread, &error))
|
if (!request_realtime_scheduling (thread, &error))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to make thread '%s' realtime scheduled: %s",
|
g_warning ("Failed to make thread '%s' realtime scheduled: %s",
|
||||||
@ -378,12 +397,12 @@ sync_realtime_scheduling_in_impl (MetaThread *thread)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_BACKEND, "Made thread '%s' real-time scheduled", priv->name);
|
meta_topic (META_DEBUG_BACKEND,
|
||||||
priv->kernel.is_realtime = TRUE;
|
"Made thread '%s' real-time scheduled", priv->name);
|
||||||
|
priv->kernel.scheduling_priority = scheduling_priority;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else
|
case META_SCHEDULING_PRIORITY_NORMAL:
|
||||||
{
|
|
||||||
if (!request_normal_scheduling (thread, &error))
|
if (!request_normal_scheduling (thread, &error))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to make thread '%s' normally scheduled: %s",
|
g_warning ("Failed to make thread '%s' normally scheduled: %s",
|
||||||
@ -392,18 +411,34 @@ sync_realtime_scheduling_in_impl (MetaThread *thread)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_BACKEND, "Made thread '%s' normally scheduled", priv->name);
|
meta_topic (META_DEBUG_BACKEND, "Made thread '%s' normally scheduled", priv->name);
|
||||||
priv->kernel.is_realtime = FALSE;
|
priv->kernel.scheduling_priority = scheduling_priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaSchedulingPriority
|
||||||
|
determine_effective_thread_priority (MetaThread *thread)
|
||||||
|
{
|
||||||
|
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||||
|
|
||||||
|
switch (priv->thread_type)
|
||||||
|
{
|
||||||
|
case META_THREAD_TYPE_USER:
|
||||||
|
return META_SCHEDULING_PRIORITY_NORMAL;
|
||||||
|
case META_THREAD_TYPE_KERNEL:
|
||||||
|
return priv->preferred_scheduling_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
thread_impl_func (gpointer user_data)
|
thread_impl_func (gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaThread *thread = META_THREAD (user_data);
|
MetaThread *thread = META_THREAD (user_data);
|
||||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||||
MetaThreadImpl *impl = priv->impl;
|
MetaThreadImpl *impl = priv->impl;
|
||||||
MetaThreadImplRunFlags run_flags = META_THREAD_IMPL_RUN_FLAG_NONE;
|
MetaSchedulingPriority effective_scheduling_priority;
|
||||||
GMainContext *thread_context = meta_thread_impl_get_main_context (impl);
|
GMainContext *thread_context = meta_thread_impl_get_main_context (impl);
|
||||||
#ifdef HAVE_PROFILER
|
#ifdef HAVE_PROFILER
|
||||||
MetaContext *context = meta_backend_get_context (priv->backend);
|
MetaContext *context = meta_backend_get_context (priv->backend);
|
||||||
@ -421,19 +456,18 @@ thread_impl_func (gpointer user_data)
|
|||||||
|
|
||||||
priv->kernel.thread_id = gettid ();
|
priv->kernel.thread_id = gettid ();
|
||||||
priv->kernel.realtime_inhibit_count = 0;
|
priv->kernel.realtime_inhibit_count = 0;
|
||||||
priv->kernel.is_realtime = FALSE;
|
|
||||||
|
|
||||||
meta_thread_impl_setup (impl);
|
meta_thread_impl_setup (impl);
|
||||||
|
|
||||||
sync_realtime_scheduling_in_impl (thread);
|
sync_scheduling_priority_in_impl (thread);
|
||||||
|
|
||||||
if (can_use_realtime_scheduling_in_impl (thread))
|
effective_scheduling_priority = determine_effective_thread_priority (thread);
|
||||||
{
|
|
||||||
g_message ("Thread '%s' will be using real time scheduling", priv->name);
|
|
||||||
run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_thread_impl_run (impl, run_flags);
|
g_message ("Thread '%s' will be using %s scheduling",
|
||||||
|
priv->name,
|
||||||
|
meta_scheduling_priority_to_string (effective_scheduling_priority));
|
||||||
|
|
||||||
|
meta_thread_impl_run (impl, effective_scheduling_priority);
|
||||||
|
|
||||||
#ifdef HAVE_PROFILER
|
#ifdef HAVE_PROFILER
|
||||||
meta_profiler_unregister_thread (profiler, thread_context);
|
meta_profiler_unregister_thread (profiler, thread_context);
|
||||||
@ -737,12 +771,13 @@ meta_thread_class_init (MetaThreadClass *klass)
|
|||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
obj_props[PROP_WANTS_REALTIME] =
|
obj_props[PROP_PREFERED_SCHEDULING_PRIORITY] =
|
||||||
g_param_spec_boolean ("wants-realtime", NULL, NULL,
|
g_param_spec_enum ("preferred-scheduling-priority", NULL, NULL,
|
||||||
FALSE,
|
META_TYPE_SCHEDULING_PRIORITY,
|
||||||
G_PARAM_READWRITE |
|
META_SCHEDULING_PRIORITY_NORMAL,
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||||
}
|
}
|
||||||
@ -1285,7 +1320,7 @@ meta_thread_inhibit_realtime_in_impl (MetaThread *thread)
|
|||||||
priv->kernel.realtime_inhibit_count++;
|
priv->kernel.realtime_inhibit_count++;
|
||||||
|
|
||||||
if (priv->kernel.realtime_inhibit_count == 1)
|
if (priv->kernel.realtime_inhibit_count == 1)
|
||||||
sync_realtime_scheduling_in_impl (thread);
|
sync_scheduling_priority_in_impl (thread);
|
||||||
break;
|
break;
|
||||||
case META_THREAD_TYPE_USER:
|
case META_THREAD_TYPE_USER:
|
||||||
break;
|
break;
|
||||||
@ -1303,7 +1338,7 @@ meta_thread_uninhibit_realtime_in_impl (MetaThread *thread)
|
|||||||
priv->kernel.realtime_inhibit_count--;
|
priv->kernel.realtime_inhibit_count--;
|
||||||
|
|
||||||
if (priv->kernel.realtime_inhibit_count == 0)
|
if (priv->kernel.realtime_inhibit_count == 0)
|
||||||
sync_realtime_scheduling_in_impl (thread);
|
sync_scheduling_priority_in_impl (thread);
|
||||||
break;
|
break;
|
||||||
case META_THREAD_TYPE_USER:
|
case META_THREAD_TYPE_USER:
|
||||||
break;
|
break;
|
||||||
|
@ -30,6 +30,12 @@ typedef enum _MetaThreadType
|
|||||||
META_THREAD_TYPE_USER,
|
META_THREAD_TYPE_USER,
|
||||||
} MetaThreadType;
|
} MetaThreadType;
|
||||||
|
|
||||||
|
typedef enum _MetaSchedulingPriority
|
||||||
|
{
|
||||||
|
META_SCHEDULING_PRIORITY_NORMAL,
|
||||||
|
META_SCHEDULING_PRIORITY_REALTIME,
|
||||||
|
} MetaSchedulingPriority;
|
||||||
|
|
||||||
#define META_TYPE_THREAD (meta_thread_get_type ())
|
#define META_TYPE_THREAD (meta_thread_get_type ())
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaThread, meta_thread,
|
G_DECLARE_DERIVABLE_TYPE (MetaThread, meta_thread,
|
||||||
|
@ -1149,7 +1149,9 @@ assert_realtime (MetaThreadImpl *thread_impl,
|
|||||||
g_autoptr (GVariant) ret = NULL;
|
g_autoptr (GVariant) ret = NULL;
|
||||||
uint32_t priority = 0;
|
uint32_t priority = 0;
|
||||||
|
|
||||||
g_assert_true (meta_thread_impl_is_realtime (thread_impl));
|
g_assert_cmpint (meta_thread_impl_get_scheduling_priority (thread_impl),
|
||||||
|
==,
|
||||||
|
META_SCHEDULING_PRIORITY_REALTIME);
|
||||||
|
|
||||||
ret = call_rtkit_mock_method ("GetThreadPriority",
|
ret = call_rtkit_mock_method ("GetThreadPriority",
|
||||||
g_variant_new ("(t)", gettid ()));
|
g_variant_new ("(t)", gettid ()));
|
||||||
@ -1175,7 +1177,7 @@ meta_test_thread_realtime (void)
|
|||||||
"backend", backend,
|
"backend", backend,
|
||||||
"name", "test realtime",
|
"name", "test realtime",
|
||||||
"thread-type", META_THREAD_TYPE_KERNEL,
|
"thread-type", META_THREAD_TYPE_KERNEL,
|
||||||
"wants-realtime", TRUE,
|
"preferred-scheduling-priority", META_SCHEDULING_PRIORITY_REALTIME,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_add_weak_pointer (G_OBJECT (thread), (gpointer *) &thread);
|
g_object_add_weak_pointer (G_OBJECT (thread), (gpointer *) &thread);
|
||||||
g_assert_nonnull (thread);
|
g_assert_nonnull (thread);
|
||||||
@ -1197,7 +1199,9 @@ assert_no_realtime (MetaThreadImpl *thread_impl,
|
|||||||
g_autoptr (GVariant) ret = NULL;
|
g_autoptr (GVariant) ret = NULL;
|
||||||
uint32_t priority = UINT32_MAX;
|
uint32_t priority = UINT32_MAX;
|
||||||
|
|
||||||
g_assert_false (meta_thread_impl_is_realtime (thread_impl));
|
g_assert_cmpint (meta_thread_impl_get_scheduling_priority (thread_impl),
|
||||||
|
==,
|
||||||
|
META_SCHEDULING_PRIORITY_NORMAL);
|
||||||
|
|
||||||
ret = call_rtkit_mock_method ("GetThreadPriority",
|
ret = call_rtkit_mock_method ("GetThreadPriority",
|
||||||
g_variant_new ("(t)", gettid ()));
|
g_variant_new ("(t)", gettid ()));
|
||||||
@ -1223,7 +1227,7 @@ meta_test_thread_no_realtime (void)
|
|||||||
"backend", backend,
|
"backend", backend,
|
||||||
"name", "test realtime",
|
"name", "test realtime",
|
||||||
"thread-type", META_THREAD_TYPE_USER,
|
"thread-type", META_THREAD_TYPE_USER,
|
||||||
"wants-realtime", TRUE,
|
"preferred-scheduling-priority", META_SCHEDULING_PRIORITY_REALTIME,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_add_weak_pointer (G_OBJECT (thread), (gpointer *) &thread);
|
g_object_add_weak_pointer (G_OBJECT (thread), (gpointer *) &thread);
|
||||||
g_assert_nonnull (thread);
|
g_assert_nonnull (thread);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user