[libc] Add implementation of getcpu syscall wrapper (#150871)

This patch adds the getcpu syscall wrapper. This has been supported in
glibc since v2.29.
This commit is contained in:
Aiden Grossman
2025-07-30 09:45:19 -07:00
committed by GitHub
parent 8e199f0f75
commit fc5976118d
8 changed files with 119 additions and 0 deletions

View File

@@ -36,6 +36,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.poll.poll
# sched.h entrypoints
libc.src.sched.getcpu
libc.src.sched.sched_get_priority_max
libc.src.sched.sched_get_priority_min
libc.src.sched.sched_getaffinity

View File

@@ -18,6 +18,13 @@ functions:
arguments:
- type: size_t
- type: const cpu_set_t *
- name: getcpu
standards:
- POSIX
return_type: int
arguments:
- type: unsigned int *
- type: unsigned int *
- name: sched_get_priority_max
standards:
- POSIX

View File

@@ -2,6 +2,13 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()
add_entrypoint_object(
getcpu
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.getcpu
)
add_entrypoint_object(
sched_getaffinity
ALIAS

20
libc/src/sched/getcpu.h Normal file
View File

@@ -0,0 +1,20 @@
//===-- Implementation header for getcpu ------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SCHED_GETCPU_H
#define LLVM_LIBC_SRC_SCHED_GETCPU_H
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
int getcpu(unsigned int *cpu, unsigned int *node);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_SCHED_GETCPU_H

View File

@@ -1,3 +1,15 @@
add_entrypoint_object(
getcpu
SRCS
getcpu.cpp
HDRS
../getcpu.h
DEPENDS
libc.include.sched
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
add_entrypoint_object(
sched_getaffinity
SRCS

View File

@@ -0,0 +1,29 @@
//===-- Implementation of getcpu ------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/sched/getcpu.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, getcpu, (unsigned int *cpu, unsigned int *node)) {
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_getcpu, cpu, node, nullptr);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
}
} // namespace LIBC_NAMESPACE_DECL

View File

@@ -40,6 +40,19 @@ add_libc_unittest(
libc.src.sched.sched_get_priority_max
)
add_libc_unittest(
getcpu_test
SUITE
libc_sched_unittests
SRCS
getcpu_test.cpp
DEPENDS
libc.include.sched
libc.src.errno.errno
libc.src.sched.getcpu
libc.test.UnitTest.ErrnoCheckingTest
)
add_libc_unittest(
scheduler_test
SUITE

View File

@@ -0,0 +1,30 @@
//===-- Unittests for getcpu ----------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/libc_errno.h"
#include "src/sched/getcpu.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
using LlvmLibcSchedGetCpuTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcSchedGetCpuTest, SmokeTest) {
unsigned int current_cpu;
unsigned int current_node;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
ASSERT_THAT(LIBC_NAMESPACE::getcpu(&current_cpu, &current_node), Succeeds(0));
}
TEST_F(LlvmLibcSchedGetCpuTest, BadPointer) {
unsigned int current_cpu;
unsigned int *current_node = reinterpret_cast<unsigned int *>(-1);
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
ASSERT_THAT(LIBC_NAMESPACE::getcpu(&current_cpu, current_node),
Fails(EFAULT));
}