After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 653140 - gmain: use Linux eventfd() for main context wake up
gmain: use Linux eventfd() for main context wake up
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2011-06-21 23:06 UTC by Colin Walters
Modified: 2011-06-22 03:28 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gmain: use Linux eventfd() for main context wake up (5.13 KB, patch)
2011-06-21 23:06 UTC, Colin Walters
reviewed Details | Review
gmain: use Linux eventfd() for main context wake up (5.08 KB, patch)
2011-06-22 01:55 UTC, Colin Walters
committed Details | Review
GCancellable: Use Linux eventfd() instead of pipe (3.80 KB, patch)
2011-06-22 01:55 UTC, Colin Walters
committed Details | Review

Description Colin Walters 2011-06-21 23:06:03 UTC
The Linux eventfd() call is basically tailor made for the main loop
wake up pipe - all we want is a threadsafe way to write to a file
descriptor, and wake up the context on the other end; we don't care
about the content at all.

The eventfd manual page basically explains the benefits:

       Applications can use an eventfd file descriptor instead of a
       pipe (see pipe(2)) in all cases where a pipe is used simply to
       signal events.  The kernel overhead of an eventfd file
       descriptor is much lower than that of a pipe, and only one file
       descriptor is required (versus the two required for a pipe).

When writing my multithreaded spawn test case I actually hit the 1024
file descriptor limit quickly, because we used 2 fds per main context.
This brings that down to 1.
Comment 1 Colin Walters 2011-06-21 23:06:06 UTC
Created attachment 190400 [details] [review]
gmain: use Linux eventfd() for main context wake up
Comment 2 Matthias Clasen 2011-06-22 00:20:00 UTC
Can we use this for GCancellable ? They currently use pipes too, iirc; and that is a place where you are much more likely to hit the fd limit...
Comment 3 Matthias Clasen 2011-06-22 00:33:59 UTC
Review of attachment 190400 [details] [review]:

::: glib/gmain.c
@@ +579,3 @@
+      efd = eventfd (0, EFD_CLOEXEC);
+      if (efd == -1 && errno == ENOSYS)
+	{

Any reason to special-case ENOSYS here ?
Also, ENOSYS is not documented as a possible error in eventfd(2)...

@@ +2995,1 @@
     }

Looks like we lost a #ifndef G_OS_WIN32 here ?
Comment 4 Colin Walters 2011-06-22 01:55:05 UTC
Created attachment 190406 [details] [review]
gmain: use Linux eventfd() for main context wake up

Fix accidentally removed #ifndef G_OS_WIN32
Comment 5 Colin Walters 2011-06-22 01:55:15 UTC
Created attachment 190407 [details] [review]
GCancellable: Use Linux eventfd() instead of pipe

See commit f626dd2b4311bd82137c5b208ab2de288c3e6fae for rationale;
basically it's cheaper than a pipe.
Comment 6 Colin Walters 2011-06-22 01:55:40 UTC
(In reply to comment #3)
> 
> Any reason to special-case ENOSYS here ?
> Also, ENOSYS is not documented as a possible error in eventfd(2)...

Yeah, the idea is to handle the case of old kernels.

> @@ +2995,1 @@
>      }
> 
> Looks like we lost a #ifndef G_OS_WIN32 here ?

Fixed.
Comment 7 Matthias Clasen 2011-06-22 02:46:15 UTC
Review of attachment 190406 [details] [review]:

Looks good, apart from the cross-compilation question.

One thing I'm curious about, though: You say this is more performant ? Is this measurable ? If yes, I'd very much like to see a performance test to demonstrate this go in along with the change.

::: configure.ac
@@ +2606,3 @@
 
+AC_MSG_CHECKING([for eventfd(2) system call])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([

We should probably have an AC_CACHE_CHECK around this to help cross compilers, like we do for other instances of AC_COMPILE_IFELSE ?
Comment 8 Matthias Clasen 2011-06-22 02:49:36 UTC
Review of attachment 190407 [details] [review]:

Looks good. Out of interest: do we have cancellation of GCancellable under unit test ?
Comment 9 Dan Winship 2011-06-22 02:53:13 UTC
yes, the unix-streams test tests multi-threaded cancellation
Comment 10 Colin Walters 2011-06-22 03:18:48 UTC
(In reply to comment #7)
>
> One thing I'm curious about, though: You say this is more performant ? Is this
> measurable ? If yes, I'd very much like to see a performance test to
> demonstrate this go in along with the change.

I'm not even going to try looking at the difference in terms of CPU/memory overhead, I don't expect it to be noticeable relative to all the other crap we're doing.  The main benefit is really just having 1 fd instead of two.

The current Linux default of 1024 fds is really pretty silly in 2011 where phones have 512MB+ of RAM, and is likely to change, but we can't rely hard on that for a while yet.

If you're into small scale optimization though, just compare linux/fs/pipe.c and linux/fs/eventfd.c.  Pipes have to deal with allocating pages, etc., whereas eventfd boils down to a mutex around a simple struct with a uint64_t.

> We should probably have an AC_CACHE_CHECK around this to help cross compilers,
> like we do for other instances of AC_COMPILE_IFELSE ?

To be honest I copied it from the futex() check.  I'll do a patch.
Comment 11 Colin Walters 2011-06-22 03:28:43 UTC
Attachment 190406 [details] pushed as 3904c87 - gmain: use Linux eventfd() for main context wake up
Attachment 190407 [details] pushed as fa87399 - GCancellable: Use Linux eventfd() instead of pipe