iyi

Standard library, 0.18.0

std/system

System: what the machine this program runs on is called, how many CPUs the program may run on, and how large a memory page is.

import std/system to use it. Source: src/std/system.iyi at v0.18.0.

System.hostname and System.cpu_count are the two calls the other library's System module carries (src/system.cr), and System.page_size is the one its runtime asks getpagesize for and keeps to itself; a program sizing a buffer or an mmap to the page wants the same number, so it is public here. Nothing else that module has is missing, and nothing it does not have is added.

Each answer comes from the platform the way the rest of std reaches it: raw syscalls on Linux, where no libc is linked (prelude.iyi says why), libSystem on darwin, kernel32 on Windows.

hostname is the kernel's node name. On Linux that is uname(2)'s nodename, which is what glibc's gethostname and so Python's socket.gethostname() read, and the same string as /proc/sys/kernel/hostname; on darwin it is libSystem's gethostname; on Windows GetComputerNameExW(ComputerNameDnsHostname), the name DNS knows the machine by, as the other library asks for, converted from UTF-16. It is read every time, because sethostname may change it while the program runs.

cpu_count is the number of CPUs this process may run on, not the number the machine has: a program sizing a pool of workers by the machine's count and held to one core by taskset -c 0, a cgroup cpuset or start /affinity 1 starts eleven threads to fight over one, which is what the runtime's marker did on Windows before it counted the mask (core_count in src/iyi/thread.iyi measured 3,077 ms against 178). So on Linux it is the bits of sched_getaffinity(2) - Python's len(os.sched_getaffinity(0)) - and only when the kernel refuses that call the online count in /sys/devices/system/cpu/online, which is what glibc's get_nprocs and so os.cpu_count() read. darwin has no affinity a process can be held to, and answers hw.activecpu, the processors the scheduler is using now, then hw.logicalcpu. Windows counts the process affinity mask, and a process spread across processor groups has no single mask (the call answers 0), so there it is GetActiveProcessorCount over every group. It is read every time, because the mask can be changed under a running program (taskset -p).

page_size is the kernel's: on Linux AT_PAGESZ out of the auxiliary vector the kernel handed the program, read from /proc/self/auxv, which is the number glibc's sysconf(_SC_PAGESIZE) answers. It is not 4096 by assumption: aarch64 kernels are built with 16 KiB and 64 KiB pages too, and Apple silicon's are 16 KiB. darwin asks getpagesize, Windows GetSystemInfo's dwPageSize (not dwAllocationGranularity, which is 64 KiB and the granularity of VirtualAlloc, not of a page). It cannot change while a process lives, so it is read once.

None of the three has an error to hand back: uname, gethostname, getpagesize and GetSystemInfo do not fail for a valid buffer, and a process with no CPU to run on is not running. What remains is a kernel that refuses calls every program makes - a sandbox hiding sched_getaffinity and /sys, or a Linux without /proc, which the collector already cannot run on (it reads /proc/self/maps for the stack's base) - and that is a panic naming what was refused, never a made-up count.

Systemstruct

std/systemiyi doc src/std/system.iyi
pub struct System
  # How many CPUs this process may run on: never more than the machine
  # has, fewer when the process is held to some of them.
  def self.cpu_count : Int32
  # The name of the machine, as the kernel holds it: `"build-07"`, or
  # `"host.example.org"` where it was set to a fully qualified name.
  def self.hostname : String
  def initialize
  # The size of a memory page in bytes: 4096 on most machines, 16384 on
  # Apple silicon and on some aarch64 Linux kernels, 65536 on others.
  def self.page_size : Int32
end