I once had the same question. That's what I eventually came with (I didn't want C bindings):
let cpu_count () =
try match Sys.os_type with
| "Win32" -> int_of_string (Sys.getenv "NUMBER_OF_PROCESSORS")
| _ ->
let i = Unix.open_process_in "getconf _NPROCESSORS_ONLN" in
let close () = ignore (Unix.close_process_in i) in
try Scanf.fscanf i "%d" (fun n -> close (); n) with e -> close (); raise e
with
| Not_found | Sys_error _ | Failure _ | Scanf.Scan_failure _
| End_of_file | Unix.Unix_error (_, _, _) -> 1
If you don't want Unix
you could replace open_process_in
by a Sys.command
writing to a temporary file. Tested on linux and osx, reported to work on mingw but not on cygwin at the time.
Update. Note that this doesn't work on freebsd where as mentioned here you need to use
sysctl -n hw.ncpu
. However since Sys.os_type
doesn't have the right granularity you'd need to conditionalize on the result of uname -s
whenever Sys.os_type
is different from Win32
.