os/platform
Identifying the system the program is running on: the operating system, the processor, the core count and the memory.
import os.platform
The os.platform package says at run time what system the program is on: the operating system, the processor family, the number of cores and the amount of memory. Use it for reports and logs, for automatic settings such as a worker count or a cache size, and for small per-system differences such as a file extension. For code that only compiles on one system, use the constants such as SALAM_OS_WINDOWS and conditional compilation instead. For the user and their home folder see os.user; for environment variables, env.
The Is... functions, OS and Arch are fixed when the program is compiled, so they cost nothing to call. The hardware questions are asked of the running system, and how they are answered differs:
| Function | Linux | macOS and BSD | Windows |
|---|---|---|---|
CpuCount | sysconf, instant | runs sysctl | the NUMBER_OF_PROCESSORS variable |
TotalMemory | /proc/meminfo | runs sysctl | runs PowerShell, often a second or more |
AvailableMemory | /proc/meminfo | not known, -1 | runs PowerShell |
What people get wrong: calling the memory functions in a loop (on Windows each call starts PowerShell, so ask once and keep the number), forgetting that every hardware function returns -1 when it cannot find out, and treating CpuCount as physical cores. It counts the logical processors online, hyper-threads included, and inside a container it counts the whole machine.
The programs below print whether a rule held rather than the raw numbers, so their output is the same on any machine.
Choose how many workers to run
Work that splits into independent pieces, such as resizing images, goes faster with one thread or process per core. CpuCount gives the number of cores; keep the result between one and a limit of your own, because a machine with 128 cores does not mean your job wants 128 threads.
import os.platform
func worker_count(limit: int): int:
cores := platform.CpuCount()
if cores < 1:
ret 1
end
if cores > limit:
ret limit
end
ret cores
end
func main:
workers := worker_count(8)
println "workers between 1 and 8:", workers >= 1 and workers <= 8
println "never more than the cores:", workers <= platform.CpuCount()
one := worker_count(1)
println "with a limit of one:", one
endInside a container the count is the whole machine's, not the share the container may use. If the program runs under Docker or Kubernetes, let a flag or an environment variable override it.
Size a cache from the system memory
TotalMemory and AvailableMemory return bytes as an i64. A cache can take a fraction of the total memory, kept between a floor and a ceiling, and never more than half of what is free right now. AvailableMemory returns minus one on systems where it is not known, so check for that before using it.
import os.platform
const MB := 1048576 as i64
func cache_bytes(): i64:
mut size := platform.TotalMemory() / 16
if size < 64 * MB:
size = 64 * MB
end
if size > 1024 * MB:
size = 1024 * MB
end
free := platform.AvailableMemory()
if free > 0 and size > free / 2:
size = free / 2
end
ret size
end
func main:
size := cache_bytes()
println "cache is at most 1 GB:", size <= 1024 * MB
println "cache is positive:", size > 0
free := platform.AvailableMemory()
println "cache fits in free memory:", free < 0 or size <= free
endSmall differences between systems
Most differences between systems are small: Windows programs end in .exe, and each desktop opens a file with a different command. A function that asks IsWindows or IsMac and returns the right piece keeps the rest of the program free of such checks.
import os.platform
func executable(name: str): str:
if platform.IsWindows():
ret name + ".exe"
end
ret name
end
func open_command(): str:
if platform.IsWindows(): ret "start" end
if platform.IsMac(): ret "open" end
ret "xdg-open"
end
func main:
mut matched := 0
if platform.IsLinux(): matched += 1 end
if platform.IsWindows(): matched += 1 end
if platform.IsMac(): matched += 1 end
if platform.IsFreeBSD(): matched += 1 end
if platform.IsWasm(): matched += 1 end
println "at most one system matched:", matched <= 1
println "binary name built:", executable("salam").starts_with("salam")
println "open command chosen:", open_command().len() > 0
endRun time or compile time
The functions of this package are answered when the program runs, so both branches of an if are compiled on every system. That fails when one branch calls a function that only exists on one system, such as a Windows API. Then use the constant itself: a plain if SALAM_OS_WINDOWS: is decided while compiling and the other branch is left out. See compile-time code for the full list of constants.
import os.platform
func linux_when_compiled(): bool:
if SALAM_OS_LINUX:
ret true
else:
ret false
end
end
func main:
println "compile time and run time agree:", linux_when_compiled() == platform.IsLinux()
if SALAM_OS_WINDOWS:
println "this line is only compiled on Windows"
else:
println "this line is compiled everywhere else"
end
end| Need | Use |
|---|---|
| Show the system in a report or a log | OS, Arch |
| Pick a value that differs by system | IsWindows, IsMac, IsLinux |
| Call code that only compiles on one system | if SALAM_OS_WINDOWS: and the other constants |
| Decide how much work to do at once | CpuCount |
| Decide how much memory to use | TotalMemory, AvailableMemory |
Functions
IsLinux
func IsLinux(): boolimport os.platform
func main:
known := platform.IsLinux() or platform.IsWindows() or platform.IsMac() or platform.IsFreeBSD() or platform.IsBSD() or platform.IsAndroid() or platform.IsWasm()
println known, platform.OS().len() > 0
arch := platform.IsX64() or platform.IsArm64() or platform.IsX86() or platform.IsArm()
println arch, platform.Arch().len() > 0
println platform.CpuCount() >= 1
println platform.TotalMemory() > 0, platform.AvailableMemory() <= platform.TotalMemory()
endIsWindows
func IsWindows(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsMac
func IsMac(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsBSD
func IsBSD(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsFreeBSD
func IsFreeBSD(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsAndroid
func IsAndroid(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsWasm
func IsWasm(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
OS
func OS(): strlinux, mac, windows, freebsd, android, wasm or unknown. Fixed at compile time.The example for this item is shown with the ones above: os-platform-OS.salam
IsX64
func IsX64(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsArm64
func IsArm64(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsX86
func IsX86(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
IsArm
func IsArm(): boolThe example for this item is shown with the ones above: os-platform-OS.salam
Arch
func Arch(): strx64, arm64, x86, arm, wasm or unknown.The example for this item is shown with the ones above: os-platform-OS.salam
CpuCount
func CpuCount(): intThe example for this item is shown with the ones above: os-platform-OS.salam
TotalMemory
func TotalMemory(): i64The example for this item is shown with the ones above: os-platform-OS.salam
AvailableMemory
func AvailableMemory(): i64MemAvailable on Linux). Supported on Linux and Windows only; elsewhere it returns minus one. On Windows each call runs PowerShell.The example for this item is shown with the ones above: os-platform-OS.salam