[libc-commits] [libc] [libc] add proc number parser and sysconf wrapper (PR #194159)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Thu Apr 30 03:46:40 PDT 2026
================
@@ -0,0 +1,189 @@
+//===------------- Linux sysinfo support -------------------------------------//
+//
+// 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___SUPPORT_OSUTIL_LINUX_SYSINFO_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSINFO_H
+
+#include "hdr/errno_macros.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/read.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/sched_getaffinity.h"
+#include "src/__support/ctype_utils.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace sysinfo {
+
+LIBC_INLINE_VAR constexpr char POSSIBLE_NPROC_PATH[] =
+ "/sys/devices/system/cpu/possible";
+LIBC_INLINE_VAR constexpr char ONLINE_NPROC_PATH[] =
+ "/sys/devices/system/cpu/online";
+
+// Parses Linux CPU-list syntax:
+// list := item (',' item)*
+// item := number | number '-' number
+// number := [0-9]+
+class ProcParser {
+ enum class ProcParserState {
+ ParseUnstarted,
+ ParseNumber,
+ ParseRangeSeparator,
+ ParseRangeEnd
+ };
+
+ ProcParserState state;
+ cpp::array<char, 128> buffer;
+ int fd;
+ size_t cursor;
+ size_t buffer_end;
+ size_t cpu_count;
+ size_t current_number;
+ size_t range_start;
+ bool has_error;
+
+ LIBC_INLINE static int open_path(const char *path) {
+ ErrorOr<int> open_result =
+ linux_syscalls::open(path, O_RDONLY | O_CLOEXEC, 0);
+ return open_result ? *open_result : -1;
+ }
+
+ LIBC_INLINE cpp::optional<char> next_char() {
+ if (fd < 0)
+ return cpp::nullopt;
+
+ while (cursor == buffer_end) {
+ ErrorOr<ssize_t> bytes_read =
+ linux_syscalls::read(fd, buffer.data(), buffer.size());
+ if (!bytes_read) {
+ if (bytes_read.error() == EINTR)
+ continue;
+ has_error = true;
+ return cpp::nullopt;
+ }
+
+ if (*bytes_read == 0)
+ return cpp::nullopt;
+
+ cursor = 0;
+ buffer_end = static_cast<size_t>(*bytes_read);
+ }
+
+ return buffer[cursor++];
+ }
+
+ LIBC_INLINE bool finish_group() {
+ if (state == ProcParserState::ParseUnstarted)
+ return true;
+ if (state == ProcParserState::ParseRangeSeparator)
+ return false;
+
+ if (state == ProcParserState::ParseRangeEnd) {
+ if (current_number < range_start)
+ return false;
+ cpu_count += current_number - range_start + 1;
+ } else {
+ ++cpu_count;
+ }
+
+ current_number = 0;
+ range_start = 0;
+ state = ProcParserState::ParseUnstarted;
+ return true;
+ }
+
+ LIBC_INLINE bool consume(char ch) {
+ if (internal::isdigit(ch)) {
+ current_number = current_number * 10 + static_cast<size_t>(ch - '0');
+ if (state == ProcParserState::ParseUnstarted)
+ state = ProcParserState::ParseNumber;
+ else if (state == ProcParserState::ParseRangeSeparator)
+ state = ProcParserState::ParseRangeEnd;
+ return true;
+ }
+
+ if (ch == '-') {
+ if (state != ProcParserState::ParseNumber)
+ return false;
+ range_start = current_number;
+ current_number = 0;
+ state = ProcParserState::ParseRangeSeparator;
+ return true;
+ }
+
+ if (ch == ',' || ch == '\n')
+ return finish_group();
+
+ if (ch == ' ' || ch == '\t' || ch == '\r')
+ return state == ProcParserState::ParseUnstarted ? true : finish_group();
+
+ return false;
+ }
+
+public:
+ // Using string view isn't exactly correct because we demands null-terminated
----------------
kaladron wrote:
OK, this feels like the wrong thing and I think we should go back to the two consts being character arrays. I just don't love handing around pointers and hoping that they're correct.
Thanks for trying this.
https://github.com/llvm/llvm-project/pull/194159
More information about the libc-commits
mailing list