@@ -12,6 +12,7 @@ def initialize
12
12
@processor_count = Delay . new { compute_processor_count }
13
13
@physical_processor_count = Delay . new { compute_physical_processor_count }
14
14
@cpu_quota = Delay . new { compute_cpu_quota }
15
+ @cpu_shares = Delay . new { compute_cpu_shares }
15
16
end
16
17
17
18
def processor_count
@@ -41,6 +42,10 @@ def cpu_quota
41
42
@cpu_quota . value
42
43
end
43
44
45
+ def cpu_shares
46
+ @cpu_shares . value
47
+ end
48
+
44
49
private
45
50
46
51
def compute_processor_count
@@ -98,13 +103,13 @@ def run(command)
98
103
99
104
def compute_cpu_quota
100
105
if RbConfig ::CONFIG [ "target_os" ] . include? ( "linux" )
101
- if File . exist? ( "/sys/fs/cgroup/cpu.max" )
106
+ if cgroups_v2?
102
107
# cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files
103
108
cpu_max = File . read ( "/sys/fs/cgroup/cpu.max" )
104
109
return nil if cpu_max . start_with? ( "max " ) # no limit
105
110
max , period = cpu_max . split . map ( &:to_f )
106
111
max / period
107
- elsif File . exist? ( "/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us" )
112
+ elsif cgroups_v1?
108
113
# cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt
109
114
max = File . read ( "/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us" ) . to_i
110
115
return nil if max == 0
@@ -113,6 +118,26 @@ def compute_cpu_quota
113
118
end
114
119
end
115
120
end
121
+
122
+ def compute_cpu_shares
123
+ if RbConfig ::CONFIG [ "target_os" ] . include? ( "linux" )
124
+ if cgroups_v2?
125
+ # Ref: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2
126
+ weight = File . read ( '/sys/fs/cgroup/cpu.weight' ) . to_f
127
+ ( ( ( ( weight - 1 ) * 262142 ) / 9999 ) + 2 ) / 1024
128
+ elsif cgroups_v1?
129
+ File . read ( '/sys/fs/cgroup/cpu/cpu.shares' ) . to_f / 1024
130
+ end
131
+ end
132
+ end
133
+
134
+ def cgroups_v1?
135
+ File . exist? ( "/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us" )
136
+ end
137
+
138
+ def cgroups_v2?
139
+ File . exist? ( "/sys/fs/cgroup/cpu.max" )
140
+ end
116
141
end
117
142
end
118
143
@@ -187,4 +212,12 @@ def self.available_processor_count
187
212
def self . cpu_quota
188
213
processor_counter . cpu_quota
189
214
end
215
+
216
+ # The CPU shares requested by the process. For performance reasons the calculated
217
+ # value will be memoized on the first call.
218
+ #
219
+ # @return [Float, nil] CPU shares requested by the process, or nil if not set
220
+ def self . cpu_shares
221
+ processor_counter . cpu_shares
222
+ end
190
223
end
0 commit comments