From c84b8e597a76b5b81f612182e97f645aee0b2ee2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 12 Apr 2020 20:23:18 +0200 Subject: [PATCH] LibC: Cache the result of gettid() to avoid syscalls We now use minherit(MAP_INHERIT_ZERO) to create a gettid() cache that is automatically invalidated on fork(). This is needed since the TID will be different in a forked child, and so we can't have a stale cached TID lying around. This is a gigantic speedup for LibJS (and everyone else too) :^) --- Libraries/LibC/unistd.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 10fffdd1a1..679817a937 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -547,9 +548,27 @@ int ftruncate(int fd, off_t length) __RETURN_WITH_ERRNO(rc, rc, -1); } +struct ThreadInfoCache { + int tid { 0 }; +}; + +__thread ThreadInfoCache* thread_info_cache; + int gettid() { - return syscall(SC_gettid); + if (!thread_info_cache) { + thread_info_cache = (ThreadInfoCache*)mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + ASSERT(thread_info_cache != MAP_FAILED); + if (minherit(thread_info_cache, PAGE_SIZE, MAP_INHERIT_ZERO) < 0) { + perror("minherit(MAP_INHERIT_ZERO)"); + ASSERT_NOT_REACHED(); + } + } + + if (thread_info_cache->tid == 0) + thread_info_cache->tid = syscall(SC_gettid); + + return thread_info_cache->tid; } int donate(int tid)