summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-08-09 11:12:13 +0100
committerPhil Jones <philj56@gmail.com>2022-08-09 12:30:24 +0100
commit81025108db445ab31d7506a88e8919a5eebcadcb (patch)
tree19901e9897b7305fe553089cd05837295ce4bbfc /src
parent33ec439ca9d1f6a2467703333d8a6189e42bd446 (diff)
Add Transparent HugePage support on Linux.
Currently, this is unlikely to be enabled for shared memory mappings on any user's system, so will not make a difference. If `/sys/kernel/mm/transparent_hugepage/shmem_enabled` is set to `advise` or higher, however, this commit should enable the use of hugepages. This can greatly speed up startup for large windows - for a 2880x1800 fullscreen window on my laptop, enabling hugepages halves startup time. From the kernel mailing lists, it looks like there's some work towards allowing applications to opt-in to THP support regardless of whether they're enabled, via `madvise(MADV_COLLAPSE)`, so this may be more useful in future.
Diffstat (limited to 'src')
-rw-r--r--src/shm.c12
-rw-r--r--src/surface.c14
2 files changed, 26 insertions, 0 deletions
diff --git a/src/shm.c b/src/shm.c
index e145d4a..9e0833f 100644
--- a/src/shm.c
+++ b/src/shm.c
@@ -34,7 +34,19 @@ static int create_shm_file(void)
int shm_allocate_file(size_t size)
{
+#ifdef __linux__
+ /*
+ * On linux, we can just use memfd_create(). This is both simpler and
+ * potentially allows usage of Transparent HugePages, which speed up
+ * the first paint of a large screen buffer.
+ *
+ * This isn't available on *BSD, which we could conceivably be running
+ * on.
+ */
+ int fd = memfd_create("wl_shm", 0);
+#else
int fd = create_shm_file();
+#endif
if (fd < 0)
return -1;
int ret;
diff --git a/src/surface.c b/src/surface.c
index e640c40..b8ed88e 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -32,6 +32,20 @@ void surface_init(
MAP_SHARED,
surface->shm_pool_fd,
0);
+#ifdef __linux__
+ /*
+ * On linux, ask for Transparent HugePages if available and our
+ * buffer's at least 2MiB. This can greatly speed up the first
+ * cairo_paint() by reducing page faults, but unfortunately is disabled
+ * for shared memory at the time of writing.
+ *
+ * MADV_HUGEPAGE isn't available on *BSD, which we could conceivably be
+ * running on.
+ */
+ if (surface->shm_pool_size >= (2 << 20)) {
+ madvise(surface->shm_pool_data, surface->shm_pool_size, MADV_HUGEPAGE);
+ }
+#endif
surface->wl_shm_pool = wl_shm_create_pool(
wl_shm,
surface->shm_pool_fd,