[libc-commits] [libc] [libc] Implement getrusage and corresponding unit tests. (PR #217684)

Vadim Kotov via libc-commits libc-commits at lists.llvm.org
Tue Aug 25 13:51:04 PDT 2026


https://github.com/vadimkotov updated https://github.com/llvm/llvm-project/pull/217684

>From 5b3102880cc9c3cbf8d918452542b45aa76892da Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Thu, 13 Aug 2026 16:09:50 -0700
Subject: [PATCH 01/10] Implement boilerplate for getrusage and its unit tests.

---
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/include/sys/resource.yaml                |  7 +++++
 libc/src/sys/resource/CMakeLists.txt          |  7 +++++
 libc/src/sys/resource/getrusage.h             | 26 +++++++++++++++++++
 libc/src/sys/resource/linux/CMakeLists.txt    | 11 ++++++++
 libc/src/sys/resource/linux/getrusage.cpp     | 26 +++++++++++++++++++
 libc/test/src/sys/resource/CMakeLists.txt     | 11 ++++++++
 libc/test/src/sys/resource/getrusage_test.cpp | 22 ++++++++++++++++
 8 files changed, 111 insertions(+)
 create mode 100644 libc/src/sys/resource/getrusage.h
 create mode 100644 libc/src/sys/resource/linux/getrusage.cpp
 create mode 100644 libc/test/src/sys/resource/getrusage_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 7ffb4f8d706f0..e5a332118a7f9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -330,6 +330,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # sys/resource.h entrypoints
     libc.src.sys.resource.getrlimit
+    libc.src.sys.resource.getrusage
     libc.src.sys.resource.setrlimit
 
     # sys/sem.h entrypoints
diff --git a/libc/include/sys/resource.yaml b/libc/include/sys/resource.yaml
index faf263d3d58e9..98fd8dae58236 100644
--- a/libc/include/sys/resource.yaml
+++ b/libc/include/sys/resource.yaml
@@ -17,6 +17,13 @@ functions:
     arguments:
       - type: int
       - type: struct rlimit *
+  - name: getrusage
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: int
+      - type: struct rusage *
   - name: setrlimit
     standards:
       - posix
diff --git a/libc/src/sys/resource/CMakeLists.txt b/libc/src/sys/resource/CMakeLists.txt
index 8319b6399650c..ac5f676588994 100644
--- a/libc/src/sys/resource/CMakeLists.txt
+++ b/libc/src/sys/resource/CMakeLists.txt
@@ -9,6 +9,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.getrlimit
 )
 
+add_entrypoint_object(
+  getrusage
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.getrusage
+)
+
 add_entrypoint_object(
   setrlimit
   ALIAS
diff --git a/libc/src/sys/resource/getrusage.h b/libc/src/sys/resource/getrusage.h
new file mode 100644
index 0000000000000..6cc246ba7f42b
--- /dev/null
+++ b/libc/src/sys/resource/getrusage.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header of getrusage.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
+#define LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
+
+#include "hdr/types/struct_rusage.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int getrusage(int who, struct rusage *usage);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif  // LLVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
diff --git a/libc/src/sys/resource/linux/CMakeLists.txt b/libc/src/sys/resource/linux/CMakeLists.txt
index 3d2aa3888887c..b292323beedfd 100644
--- a/libc/src/sys/resource/linux/CMakeLists.txt
+++ b/libc/src/sys/resource/linux/CMakeLists.txt
@@ -10,6 +10,17 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  getrusage
+  SRCS
+    getrusage.cpp
+  HDRS
+    ../getrusage.h
+  DEPENDS
+    libc.hdr.types.struct_rusage
+    libc.src.__support.common
+)
+
 add_entrypoint_object(
   setrlimit
   SRCS
diff --git a/libc/src/sys/resource/linux/getrusage.cpp b/libc/src/sys/resource/linux/getrusage.cpp
new file mode 100644
index 0000000000000..8772cf34c6673
--- /dev/null
+++ b/libc/src/sys/resource/linux/getrusage.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of getrusage.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/resource/getrusage.h"
+
+#include "hdr/types/struct_rusage.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getrusage, (int, struct rusage *)) {
+  return -1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/sys/resource/CMakeLists.txt b/libc/test/src/sys/resource/CMakeLists.txt
index 876d93703e794..df26db4d78798 100644
--- a/libc/test/src/sys/resource/CMakeLists.txt
+++ b/libc/test/src/sys/resource/CMakeLists.txt
@@ -20,3 +20,14 @@ add_libc_test(
     libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
+
+add_libc_test(
+  getrusage_test
+  SUITE
+    libc_sys_resource_unittests
+  SRCS
+    getrusage_test.cpp
+  DEPENDS
+    libc.hdr.types.struct_rusage
+    libc.src.sys.resource.getrusage
+)
diff --git a/libc/test/src/sys/resource/getrusage_test.cpp b/libc/test/src/sys/resource/getrusage_test.cpp
new file mode 100644
index 0000000000000..e4fa712f5712f
--- /dev/null
+++ b/libc/test/src/sys/resource/getrusage_test.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for getrusage.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/struct_rusage.h"
+#include "src/sys/resource/getrusage.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcGetrusageTest, DummyTest) {
+  struct rusage usage = {};
+  int res = LIBC_NAMESPACE::getrusage(0, &usage);
+  EXPECT_NE(res, -1);
+}

>From 372143d8ca3333b974ca0240c145bd79e87fd039 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 18 Aug 2026 10:33:01 -0700
Subject: [PATCH 02/10] Implement getrusage Linux syscall wrapper and complete
 getrusage libc function.

---
 .../linux/syscall_wrappers/CMakeLists.txt     | 14 ++++++++
 .../OSUtil/linux/syscall_wrappers/getrusage.h | 34 +++++++++++++++++++
 libc/src/sys/resource/getrusage.h             |  6 ++--
 libc/src/sys/resource/linux/CMakeLists.txt    |  3 ++
 libc/src/sys/resource/linux/getrusage.cpp     | 11 ++++--
 5 files changed, 63 insertions(+), 5 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 2b22bb8e733de..2756d9cf76943 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -940,3 +940,17 @@ add_header_library(
     libc.src.__support.macros.config
     libc.include.sys_syscall
 )
+
+add_header_library(
+  getrusage
+  HDRS
+    getrusage.h
+  DEPENDS
+    libc.hdr.types.struct_timespec
+    libc.hdr.time_macros
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.include.sys_syscall
+)
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
new file mode 100644
index 0000000000000..e52261288ddc4
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for getrusage
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
+
+#include "hdr/types/struct_rusage.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<long> getrusage(int who, struct rusage *ru) {
+  return syscall_checked<long>(SYS_getrusage, who, ru);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif  // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
diff --git a/libc/src/sys/resource/getrusage.h b/libc/src/sys/resource/getrusage.h
index 6cc246ba7f42b..899ebefc5acab 100644
--- a/libc/src/sys/resource/getrusage.h
+++ b/libc/src/sys/resource/getrusage.h
@@ -11,8 +11,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
-#define LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
+#ifndef LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H
+#define LVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H
 
 #include "hdr/types/struct_rusage.h"
 #include "src/__support/macros/config.h"
@@ -23,4 +23,4 @@ int getrusage(int who, struct rusage *usage);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif  // LLVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H_
+#endif  // LLVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H
diff --git a/libc/src/sys/resource/linux/CMakeLists.txt b/libc/src/sys/resource/linux/CMakeLists.txt
index b292323beedfd..2a7d96c2eb365 100644
--- a/libc/src/sys/resource/linux/CMakeLists.txt
+++ b/libc/src/sys/resource/linux/CMakeLists.txt
@@ -18,7 +18,10 @@ add_entrypoint_object(
     ../getrusage.h
   DEPENDS
     libc.hdr.types.struct_rusage
+    libc.src.__support.OSUtil.linux.syscall_wrappers.getrusage
     libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/resource/linux/getrusage.cpp b/libc/src/sys/resource/linux/getrusage.cpp
index 8772cf34c6673..4851cd7a522f6 100644
--- a/libc/src/sys/resource/linux/getrusage.cpp
+++ b/libc/src/sys/resource/linux/getrusage.cpp
@@ -14,13 +14,20 @@
 #include "src/sys/resource/getrusage.h"
 
 #include "hdr/types/struct_rusage.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getrusage.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, getrusage, (int, struct rusage *)) {
-  return -1;
+LLVM_LIBC_FUNCTION(int, getrusage, (int who, struct rusage *usage)) {
+  auto result = linux_syscalls::getrusage(who, usage);
+  if (!result) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From b3e48c6f1d4926df160d997151d469dbafb4be04 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 18 Aug 2026 12:06:11 -0700
Subject: [PATCH 03/10] Change getrusage syscall wrapper return value to
 `ErrorOr<int>` and leave the comment providing the rationale

---
 .../__support/OSUtil/linux/syscall_wrappers/getrusage.h    | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
index e52261288ddc4..128b178fc54f7 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
@@ -24,8 +24,11 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace linux_syscalls {
 
-LIBC_INLINE ErrorOr<long> getrusage(int who, struct rusage *ru) {
-  return syscall_checked<long>(SYS_getrusage, who, ru);
+// The wrapper returns an int (casting from `long` returned by the syscall)
+// because its libc counterpart returns an int and the set of possible return
+// values fits: 0, -EFAULT (-14) or -EINVAL (-22).
+LIBC_INLINE ErrorOr<int> getrusage(int who, struct rusage *ru) {
+  return syscall_checked<int>(SYS_getrusage, who, ru);
 }
 
 } // namespace linux_syscalls

>From d4455034fcbf081090fa3699871cd75a119ae559 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Wed, 19 Aug 2026 17:22:21 -0700
Subject: [PATCH 04/10] Implement basic tests for getrusage

---
 .../linux/sys-resource-macros.h               |  4 ++++
 libc/include/sys/resource.yaml                |  3 ++-
 libc/test/src/sys/resource/CMakeLists.txt     |  2 ++
 libc/test/src/sys/resource/getrusage_test.cpp | 24 ++++++++++++++++---
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/libc/include/llvm-libc-macros/linux/sys-resource-macros.h b/libc/include/llvm-libc-macros/linux/sys-resource-macros.h
index 419761e01c453..9f1e04a339c73 100644
--- a/libc/include/llvm-libc-macros/linux/sys-resource-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-resource-macros.h
@@ -30,4 +30,8 @@
 
 #define RLIM_INFINITY ((rlim_t) - 1)
 
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_THREAD 1
+
 #endif // LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
diff --git a/libc/include/sys/resource.yaml b/libc/include/sys/resource.yaml
index 98fd8dae58236..53e9a9dc27478 100644
--- a/libc/include/sys/resource.yaml
+++ b/libc/include/sys/resource.yaml
@@ -19,7 +19,8 @@ functions:
       - type: struct rlimit *
   - name: getrusage
     standards:
-      - posix
+      # GNU because we support RUSAGE_THREAD, which is not in POSIX.
+      - gnu
     return_type: int
     arguments:
       - type: int
diff --git a/libc/test/src/sys/resource/CMakeLists.txt b/libc/test/src/sys/resource/CMakeLists.txt
index df26db4d78798..18196eaf1865c 100644
--- a/libc/test/src/sys/resource/CMakeLists.txt
+++ b/libc/test/src/sys/resource/CMakeLists.txt
@@ -28,6 +28,8 @@ add_libc_test(
   SRCS
     getrusage_test.cpp
   DEPENDS
+    libc.hdr.sys_resource_macros
     libc.hdr.types.struct_rusage
     libc.src.sys.resource.getrusage
+    libc.test.UnitTest.ErrnoCheckingTest
 )
diff --git a/libc/test/src/sys/resource/getrusage_test.cpp b/libc/test/src/sys/resource/getrusage_test.cpp
index e4fa712f5712f..b908eb5a89be9 100644
--- a/libc/test/src/sys/resource/getrusage_test.cpp
+++ b/libc/test/src/sys/resource/getrusage_test.cpp
@@ -11,12 +11,30 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "hdr/sys_resource_macros.h"
 #include "hdr/types/struct_rusage.h"
 #include "src/sys/resource/getrusage.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/Test.h"
 
-TEST(LlvmLibcGetrusageTest, DummyTest) {
+
+TEST(LlvmLibcGetrusageTest, BasicTest) {
+  struct rusage usage = {};
+  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, &usage);
+  EXPECT_EQ(res, 0);
+  ASSERT_ERRNO_SUCCESS();
+}
+
+TEST(LlvmLibcGetrusageTest, TestWhoInvalid) {
   struct rusage usage = {};
-  int res = LIBC_NAMESPACE::getrusage(0, &usage);
-  EXPECT_NE(res, -1);
+  int res = LIBC_NAMESPACE::getrusage(99, &usage);
+  EXPECT_EQ(res, -1);
+  ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcGetrusageTest, TestUsageBadPointer) {
+  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage*)-1L);
+  EXPECT_EQ(res, -1);
+  ASSERT_ERRNO_EQ(EFAULT);
+
 }

>From e65205b39e45af816cb48272372e228da6ed107c Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Thu, 20 Aug 2026 09:23:27 -0700
Subject: [PATCH 05/10] Format files with git-clang-format

---
 libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h | 2 +-
 libc/src/sys/resource/getrusage.h                            | 2 +-
 libc/test/src/sys/resource/getrusage_test.cpp                | 4 +---
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
index 128b178fc54f7..2a4b1b0887969 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
@@ -34,4 +34,4 @@ LIBC_INLINE ErrorOr<int> getrusage(int who, struct rusage *ru) {
 } // namespace linux_syscalls
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif  // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
diff --git a/libc/src/sys/resource/getrusage.h b/libc/src/sys/resource/getrusage.h
index 899ebefc5acab..40c13948e32a0 100644
--- a/libc/src/sys/resource/getrusage.h
+++ b/libc/src/sys/resource/getrusage.h
@@ -23,4 +23,4 @@ int getrusage(int who, struct rusage *usage);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif  // LLVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H
+#endif // LLVM_LIBC_SRC_SYS_RESOURCE_GETRUSAGE_H
diff --git a/libc/test/src/sys/resource/getrusage_test.cpp b/libc/test/src/sys/resource/getrusage_test.cpp
index b908eb5a89be9..1a3a52c90c238 100644
--- a/libc/test/src/sys/resource/getrusage_test.cpp
+++ b/libc/test/src/sys/resource/getrusage_test.cpp
@@ -17,7 +17,6 @@
 #include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/Test.h"
 
-
 TEST(LlvmLibcGetrusageTest, BasicTest) {
   struct rusage usage = {};
   int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, &usage);
@@ -33,8 +32,7 @@ TEST(LlvmLibcGetrusageTest, TestWhoInvalid) {
 }
 
 TEST(LlvmLibcGetrusageTest, TestUsageBadPointer) {
-  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage*)-1L);
+  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage *)-1L);
   EXPECT_EQ(res, -1);
   ASSERT_ERRNO_EQ(EFAULT);
-
 }

>From b50c6ca10f5a1eaa058c64fd3df2d7de510b32ae Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 25 Aug 2026 10:06:01 -0700
Subject: [PATCH 06/10] Add getrusage to aarch64 and riscv entrypoints.txt

---
 libc/config/linux/aarch64/entrypoints.txt | 1 +
 libc/config/linux/riscv/entrypoints.txt   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f1fc1fe67a268..486916d866e08 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -299,6 +299,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # sys/resource.h entrypoints
     libc.src.sys.resource.getrlimit
+    libc.src.sys.resource.getrusage
     libc.src.sys.resource.setrlimit
 
     # sys/sendfile.h entrypoints
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index b807410fbb12b..f027ccbaea3ef 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -330,6 +330,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # sys/resource.h entrypoints
     libc.src.sys.resource.getrlimit
+    libc.src.sys.resource.getrusage
     libc.src.sys.resource.setrlimit
 
     # sys/sendfile.h entrypoints

>From 5747cc60cd42907e73498e64914e169889f9aa5a Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 25 Aug 2026 11:26:08 -0700
Subject: [PATCH 07/10] Add rusage-related macros to resource.yaml and the
 corresponding CMakeLists.txt

---
 libc/include/CMakeLists.txt    |  1 +
 libc/include/sys/resource.yaml | 12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index a7c2978aae3e7..0785616279546 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -748,6 +748,7 @@ add_header_macro(
     .llvm-libc-macros.sys_resource_macros
     .llvm-libc-types.rlim_t
     .llvm-libc-types.struct_rlimit
+    .llvm-libc-types.struct_rusage
 )
 
 add_header_macro(
diff --git a/libc/include/sys/resource.yaml b/libc/include/sys/resource.yaml
index 53e9a9dc27478..a26dfb5f77beb 100644
--- a/libc/include/sys/resource.yaml
+++ b/libc/include/sys/resource.yaml
@@ -4,9 +4,18 @@ standards:
 macros:
   - macro_name: RLIMIT_CPU
     macro_header: sys-resource-macros.h
+  - macro_name: RUSAGE_SELF
+    macro_header: sys-resource-macros.h
+  - macro_name: RUSAGE_CHILDREN
+    macro_header: sys-resource-macros.h
+  - macro_name: RUSAGE_THREAD
+    macro_header: sys-resource-macros.h
+    standards:
+      - gnu
 types:
   - type_name: struct_rlimit
   - type_name: rlim_t
+  - type_name: struct_rusage
 enums: []
 objects: []
 functions:
@@ -19,8 +28,7 @@ functions:
       - type: struct rlimit *
   - name: getrusage
     standards:
-      # GNU because we support RUSAGE_THREAD, which is not in POSIX.
-      - gnu
+      - posix
     return_type: int
     arguments:
       - type: int

>From 609d33c69bf63324a8989e9fba2749f899254507 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 25 Aug 2026 11:40:29 -0700
Subject: [PATCH 08/10] Fix wrong description and Cmake deps in getrusage
 syscall wrapper.

---
 .../src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt | 3 +--
 libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h   | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 2756d9cf76943..c210b237d90ea 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -946,8 +946,7 @@ add_header_library(
   HDRS
     getrusage.h
   DEPENDS
-    libc.hdr.types.struct_timespec
-    libc.hdr.time_macros
+    libc.hdr.types.struct_rusage
     libc.src.__support.OSUtil.osutil
     libc.src.__support.common
     libc.src.__support.error_or
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
index 2a4b1b0887969..ed44014a9556d 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// Implementation header for getrusage
+/// Syscall wrapper for getrusage
 ///
 //===----------------------------------------------------------------------===//
 

>From 31a72fdb56a11eaaf4d508561328364875eadfb2 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 25 Aug 2026 13:44:17 -0700
Subject: [PATCH 09/10] Use Succeed and Failed in getrusage unit tests and add
 a soft faults assertion.

---
 libc/test/src/sys/resource/CMakeLists.txt     |  1 +
 libc/test/src/sys/resource/getrusage_test.cpp | 24 +++++++++----------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/libc/test/src/sys/resource/CMakeLists.txt b/libc/test/src/sys/resource/CMakeLists.txt
index 18196eaf1865c..5ff3ec8a62ea9 100644
--- a/libc/test/src/sys/resource/CMakeLists.txt
+++ b/libc/test/src/sys/resource/CMakeLists.txt
@@ -32,4 +32,5 @@ add_libc_test(
     libc.hdr.types.struct_rusage
     libc.src.sys.resource.getrusage
     libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
 )
diff --git a/libc/test/src/sys/resource/getrusage_test.cpp b/libc/test/src/sys/resource/getrusage_test.cpp
index 1a3a52c90c238..f47ee81d561af 100644
--- a/libc/test/src/sys/resource/getrusage_test.cpp
+++ b/libc/test/src/sys/resource/getrusage_test.cpp
@@ -15,24 +15,24 @@
 #include "hdr/types/struct_rusage.h"
 #include "src/sys/resource/getrusage.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
-TEST(LlvmLibcGetrusageTest, BasicTest) {
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcGetrusageTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcGetrusageTest, BasicTest) {
   struct rusage usage = {};
-  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, &usage);
-  EXPECT_EQ(res, 0);
-  ASSERT_ERRNO_SUCCESS();
+  ASSERT_THAT(LIBC_NAMESPACE::getrusage(RUSAGE_SELF, &usage), Succeeds());
+  // The number of soft page faults should be stably greater than 0.
+  ASSERT_TRUE(usage.ru_minflt > 0);
 }
 
-TEST(LlvmLibcGetrusageTest, TestWhoInvalid) {
+TEST_F(LlvmLibcGetrusageTest, TestWhoInvalid) {
   struct rusage usage = {};
-  int res = LIBC_NAMESPACE::getrusage(99, &usage);
-  EXPECT_EQ(res, -1);
-  ASSERT_ERRNO_EQ(EINVAL);
+  ASSERT_THAT(LIBC_NAMESPACE::getrusage(99, &usage), Fails(EINVAL, -1));
 }
 
-TEST(LlvmLibcGetrusageTest, TestUsageBadPointer) {
-  int res = LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage *)-1L);
-  EXPECT_EQ(res, -1);
-  ASSERT_ERRNO_EQ(EFAULT);
+TEST_F(LlvmLibcGetrusageTest, TestUsageBadPointer) {
+  ASSERT_THAT(LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage *)-1L), Fails(EFAULT, -1));
 }

>From 735ce4727613d046ce8adaa757b6c33f09b1d881 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Tue, 25 Aug 2026 13:50:44 -0700
Subject: [PATCH 10/10] Fix clang formatting

---
 libc/test/src/sys/resource/getrusage_test.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/test/src/sys/resource/getrusage_test.cpp b/libc/test/src/sys/resource/getrusage_test.cpp
index f47ee81d561af..589cef73e79e1 100644
--- a/libc/test/src/sys/resource/getrusage_test.cpp
+++ b/libc/test/src/sys/resource/getrusage_test.cpp
@@ -34,5 +34,6 @@ TEST_F(LlvmLibcGetrusageTest, TestWhoInvalid) {
 }
 
 TEST_F(LlvmLibcGetrusageTest, TestUsageBadPointer) {
-  ASSERT_THAT(LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage *)-1L), Fails(EFAULT, -1));
+  ASSERT_THAT(LIBC_NAMESPACE::getrusage(RUSAGE_SELF, (struct rusage *)-1L),
+              Fails(EFAULT, -1));
 }



More information about the libc-commits mailing list