Skip to content

Commit 11e76e4

Browse files
Wesley MoxamMartin Verzilli
Wesley Moxam
authored and
Martin Verzilli
committedJun 15, 2017
Fix BSD cpu count (#4466)
* Use sysctl to return the number of CPUs on BSD systems See: http://man.openbsd.org/sysctl.3 https://www.freebsd.org/cgi/man.cgi?query=sysctl&sektion=3
1 parent 74b1bb4 commit 11e76e4

File tree

10 files changed

+91
-29
lines changed

10 files changed

+91
-29
lines changed
 

‎src/crystal/system.cr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module Crystal
2+
# :nodoc
3+
module System
4+
# Returns the hostname
5+
# def self.hostname
6+
7+
# Returns the number of logical processors available to the system.
8+
#
9+
# def self.cpu_count
10+
end
11+
end
12+
13+
require "./system/unix/hostname"
14+
15+
{% if flag?(:freebsd) || flag?(:openbsd) %}
16+
require "./system/unix/sysctl_cpucount"
17+
{% else %}
18+
# TODO: restrict on flag?(:unix) after crystal > 0.22.0 is released
19+
require "./system/unix/sysconf_cpucount"
20+
{% end %}

‎src/crystal/system/unix/hostname.cr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
require "c/unistd"
2+
3+
module Crystal::System
4+
def self.hostname
5+
String.new(255) do |buffer|
6+
unless LibC.gethostname(buffer, LibC::SizeT.new(255)) == 0
7+
raise Errno.new("Could not get hostname")
8+
end
9+
len = LibC.strlen(buffer)
10+
{len, len}
11+
end
12+
end
13+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% skip_file if flag?(:openbsd) || flag?(:freebsd) %}
2+
3+
require "c/unistd"
4+
5+
module Crystal::System
6+
def self.cpu_count
7+
LibC.sysconf(LibC::SC_NPROCESSORS_ONLN)
8+
end
9+
end
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{% skip_file unless flag?(:openbsd) || flag?(:freebsd) %}
2+
3+
require "c/sysctl"
4+
5+
module Crystal::System
6+
def self.cpu_count
7+
mib = Int32[LibC::CTL_HW, LibC::HW_NCPU]
8+
ncpus = 0
9+
size = sizeof(Int32).to_u64
10+
11+
if LibC.sysctl(mib, 2, pointerof(ncpus), pointerof(size), nil, 0) == 0
12+
ncpus
13+
else
14+
-1
15+
end
16+
end
17+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
lib LibC
2+
CTL_HW = 6
3+
HW_NCPU = 3
4+
5+
fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int
6+
end

‎src/lib_c/amd64-unknown-openbsd/c/unistd.cr

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ require "./sys/types"
22
require "./stdint"
33

44
lib LibC
5-
F_OK = 0
6-
R_OK = 0x04
7-
W_OK = 0x02
8-
X_OK = 0x01
9-
SC_CLK_TCK = 3
10-
SC_NPROCESSORS_ONLN = 58
5+
F_OK = 0
6+
R_OK = 0x04
7+
W_OK = 0x02
8+
X_OK = 0x01
9+
SC_CLK_TCK = 3
1110

1211
fun access(x0 : Char*, x1 : Int) : Int
1312
fun chdir(x0 : Char*) : Int
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
lib LibC
2+
CTL_HW = 6
3+
CTL_KERN = 1
4+
HW_NCPU = 3
5+
KERN_PROC = 14
6+
KERN_PROC_PATHNAME = 12
7+
PATH_MAX = 1024
8+
9+
fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int
10+
end

‎src/lib_c/x86_64-portbld-freebsd/c/unistd.cr

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ require "./sys/types"
22
require "./stdint"
33

44
lib LibC
5-
F_OK = 0
6-
R_OK = 0x04
7-
W_OK = 0x02
8-
X_OK = 0x01
9-
SC_CLK_TCK = 3
10-
SC_NPROCESSORS_ONLN = 58
5+
F_OK = 0
6+
R_OK = 0x04
7+
W_OK = 0x02
8+
X_OK = 0x01
9+
SC_CLK_TCK = 3
1110

1211
fun access(x0 : Char*, x1 : Int) : Int
1312
fun chdir(x0 : Char*) : Int

‎src/process/executable_path.cr

+1-7
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,7 @@ end
7272
end
7373

7474
{% elsif flag?(:freebsd) %}
75-
lib LibC
76-
PATH_MAX = 1024
77-
CTL_KERN = 1
78-
KERN_PROC = 14
79-
KERN_PROC_PATHNAME = 12
80-
fun sysctl(name : Int*, namelen : UInt, oldp : Void*, oldlenp : SizeT*, newp : Void*, newlen : SizeT) : Int
81-
end
75+
require "c/sysctl"
8276

8377
class Process
8478
private def self.executable_path_impl

‎src/system.cr

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
1-
require "c/unistd"
1+
require "crystal/system"
22

33
module System
44
# Returns the hostname.
55
#
6-
# NOTE: Maximum of 253 characters are allowed, with 2 bytes reserved for storage.
6+
# NOTE: Maximum of 253 characters are allowed, with 2 bytes reserved for
7+
# storage.
78
# In practice, many platforms will disallow anything longer than 63 characters.
89
#
910
# ```
1011
# System.hostname # => "host.example.org"
1112
# ```
1213
def self.hostname
13-
String.new(255) do |buffer|
14-
unless LibC.gethostname(buffer, LibC::SizeT.new(255)) == 0
15-
raise Errno.new("Could not get hostname")
16-
end
17-
len = LibC.strlen(buffer)
18-
{len, len}
19-
end
14+
Crystal::System.hostname
2015
end
2116

2217
# Returns the number of logical processors available to the system.
@@ -25,6 +20,6 @@ module System
2520
# System.cpu_count # => 4
2621
# ```
2722
def self.cpu_count
28-
LibC.sysconf(LibC::SC_NPROCESSORS_ONLN)
23+
Crystal::System.cpu_count
2924
end
3025
end

0 commit comments

Comments
 (0)
Please sign in to comment.