mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 10:42:11 +01:00
gmain: Optimize insertion of matching or higher priority sources
Calling g_source_attach() does an O(n) iteration over all current sources until it found the insertion point, while holding the context mutex. This is a serious performance hit for heavy asynchronous I/O, because GIOScheduler sends results back to the source context via g_source_attach(). A more correct fix for this would be a priority queue, but this patch is quite simple - we just walk the source list in reverse instead of forwards. For applications where most sources are the same priority (or they have just a few lower-priority sources), this patch is a large speedup. However, this patch will degrade performance in the case of inserting a high-priority source for applications which have many lower-priority sources. https://bugzilla.gnome.org/show_bug.cgi?id=619329
This commit is contained in:
parent
211d50ac74
commit
11ba8eb445
16
glib/gmain.c
16
glib/gmain.c
@ -233,6 +233,7 @@ struct _GMainContext
|
||||
|
||||
guint next_id;
|
||||
GSource *source_list;
|
||||
GSource *source_list_last;
|
||||
gint in_check_or_prepare;
|
||||
|
||||
GPollRec *poll_records, *poll_records_tail;
|
||||
@ -820,12 +821,12 @@ g_source_list_add (GSource *source,
|
||||
}
|
||||
else
|
||||
{
|
||||
last_source = NULL;
|
||||
tmp_source = context->source_list;
|
||||
while (tmp_source && tmp_source->priority <= source->priority)
|
||||
tmp_source = NULL;
|
||||
last_source = context->source_list_last;
|
||||
while (last_source && last_source->priority > source->priority)
|
||||
{
|
||||
last_source = tmp_source;
|
||||
tmp_source = tmp_source->next;
|
||||
tmp_source = last_source;
|
||||
last_source = last_source->prev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,6 +839,9 @@ g_source_list_add (GSource *source,
|
||||
last_source->next = source;
|
||||
else
|
||||
context->source_list = source;
|
||||
|
||||
if (source->next == NULL)
|
||||
context->source_list_last = source;
|
||||
}
|
||||
|
||||
/* Holds context's lock
|
||||
@ -853,6 +857,8 @@ g_source_list_remove (GSource *source,
|
||||
|
||||
if (source->next)
|
||||
source->next->prev = source->prev;
|
||||
else
|
||||
context->source_list_last = context->source_list_last->prev;
|
||||
|
||||
source->prev = NULL;
|
||||
source->next = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user