cpuinfo.nim 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements procs to determine the number of CPUs / cores.
  10. include "system/inclrtl"
  11. import strutils, os
  12. when not defined(windows):
  13. import posix
  14. when defined(linux):
  15. import linux
  16. when defined(freebsd) or defined(macosx):
  17. {.emit:"#include <sys/types.h>".}
  18. when defined(openbsd) or defined(netbsd):
  19. {.emit:"#include <sys/param.h>".}
  20. when defined(macosx) or defined(bsd):
  21. # we HAVE to emit param.h before sysctl.h so we cannot use .header here
  22. # either. The amount of archaic bullshit in Poonix based OSes is just insane.
  23. {.emit:"#include <sys/sysctl.h>".}
  24. const
  25. CTL_HW = 6
  26. HW_AVAILCPU = 25
  27. HW_NCPU = 3
  28. proc sysctl(x: ptr array[0..3, cint], y: cint, z: pointer,
  29. a: var csize, b: pointer, c: int): cint {.
  30. importc: "sysctl", nodecl.}
  31. when defined(genode):
  32. include genode/env
  33. proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
  34. importcpp: "@->cpu().affinity_space().total()".}
  35. when defined(haiku):
  36. type
  37. SystemInfo {.importc: "system_info", header: "<OS.h>".} = object
  38. cpuCount {.importc: "cpu_count".}: uint32
  39. proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info",
  40. header: "<OS.h>".}
  41. proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
  42. ## returns the numer of the processors/cores the machine has.
  43. ## Returns 0 if it cannot be detected.
  44. when defined(windows):
  45. type
  46. SYSTEM_INFO {.final, pure.} = object
  47. u1: int32
  48. dwPageSize: int32
  49. lpMinimumApplicationAddress: pointer
  50. lpMaximumApplicationAddress: pointer
  51. dwActiveProcessorMask: ptr int32
  52. dwNumberOfProcessors: int32
  53. dwProcessorType: int32
  54. dwAllocationGranularity: int32
  55. wProcessorLevel: int16
  56. wProcessorRevision: int16
  57. proc GetSystemInfo(lpSystemInfo: var SYSTEM_INFO) {.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".}
  58. var
  59. si: SYSTEM_INFO
  60. GetSystemInfo(si)
  61. result = si.dwNumberOfProcessors
  62. elif defined(macosx) or defined(bsd):
  63. var
  64. mib: array[0..3, cint]
  65. numCPU: int
  66. len: csize
  67. mib[0] = CTL_HW
  68. mib[1] = HW_AVAILCPU
  69. len = sizeof(numCPU)
  70. discard sysctl(addr(mib), 2, addr(numCPU), len, nil, 0)
  71. if numCPU < 1:
  72. mib[1] = HW_NCPU
  73. discard sysctl(addr(mib), 2, addr(numCPU), len, nil, 0)
  74. result = numCPU
  75. elif defined(hpux):
  76. result = mpctl(MPC_GETNUMSPUS, nil, nil)
  77. elif defined(irix):
  78. var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
  79. result = sysconf(SC_NPROC_ONLN)
  80. elif defined(genode):
  81. result = runtimeEnv.affinitySpaceTotal().int
  82. elif defined(haiku):
  83. var sysinfo: SystemInfo
  84. if getSystemInfo(addr sysinfo) == 0:
  85. result = sysinfo.cpuCount.int
  86. else:
  87. result = sysconf(SC_NPROCESSORS_ONLN)
  88. if result <= 0: result = 0