Module: LinuxStat::CPU

Defined in:
lib/linux_stat/cpu.rb

Class Method Summary collapse

Class Method Details

.countObject

Returns the total number of CPU threads. If the information isn’t available, it will return 0.



71
72
73
74
# File 'lib/linux_stat/cpu.rb', line 71

def count
	# CPU count can change during the program runtime
	cpuinfo.count { |x| x.start_with?('processor') }
end

.cur_freqObject

Returns an array with current core frequencies corresponding to the usages. If the information isn’t available, it will return an empty array.



86
87
88
89
90
91
92
93
94
95
# File 'lib/linux_stat/cpu.rb', line 86

def cur_freq
	@@cpu_freqs ||= Dir["/sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_cur_freq"]
	@@cur_freqs_readable ||= @@cpu_freqs.all?(&File.method(:readable?))

	if @@cur_freqs_readable
		@@cpu_freqs.map { |x| IO.read(x).to_i }
	else
		[]
	end
end

.max_freqObject

Returns an array with max core frequencies corresponding to the usages. If the information isn’t available, it will return an empty array.



99
100
101
102
103
104
105
106
107
108
# File 'lib/linux_stat/cpu.rb', line 99

def max_freq
	@@max_freqs ||= Dir["/sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_max_freq"]
	@@max_freqs_readable ||= @@max_freqs.all?(&File.method(:readable?))

	if @@max_freqs_readable
		@@max_freqs.map { |x| IO.read(x).to_i }
	else
		[]
	end
end

.modelObject

Returns the model of processor. If the information isn’t available, it will return en empty string.

The output is also cached (memoized) ; as changing the value in runtime is unexpected.



80
81
82
# File 'lib/linux_stat/cpu.rb', line 80

def model
	@@name ||= cpuinfo.find { |x| x.start_with?('model name') }.to_s.split(?:)[-1].to_s.strip
end

.stat(sleep = ticks_to_ms) ⇒ Object Also known as: usages

stat(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck) Where sleep is the delay to gather the data. The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck This method returns the cpu usage of all threads.

The first one is aggregated CPU usage reported by the Linux kernel. And the consecutive ones are the real core usages.

On a system with 4 threads, the output will be like

1=>100.0, 2=>50.0, 3=>87.5, 4=>87.5

If the information is not available, it will return an empty Hash



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/linux_stat/cpu.rb', line 16

def stat(sleep = ticks_to_ms)
	return {} unless stat?

	data = IO.readlines('/proc/stat').select! { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) }
	sleep(sleep)
	data2 = IO.readlines('/proc/stat').select! { |x| x[/^cpu\d*/] }.map! { |x| x.split.map!(&:to_f) }

	# On devices like android, the core count can change anytime.
	# I had crashes on Termux.
	# So better just count the min number of CPU and iterate over that
	# If data.length is smaller than data2.length, we don't have enough data to compare.
	dl, d2l = data.length, data2.length
	min = dl > d2l ? d2l : dl

	min.times.reduce({}) do |h, x|
		user, nice, sys, idle, iowait, irq, softirq, steal = *data[x].drop(1)
		user2, nice2, sys2, idle2, iowait2, irq2, softirq2, steal2 = *data2[x].drop(1)

		idle_then, idle_now  = idle + iowait, idle2 + iowait2
		totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal)

		res = totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
		res = 0.0 if res.nan?

		h.merge!(
			x => res
		)
	end
end

.total_usage(sleep = ticks_to_ms) ⇒ Object Also known as: usage

total_usage(sleep = 1.0 / LinuxStat::Sysconf.sc_clk_tck) Where sleep is the delay to gather the data. The minimum possible value at anytime is 1.0 / LinuxStat::Sysconf.sc_clk_tck This method returns the cpu usage of all threads.

It’s like running LinuxStat::CPU.stat but it’s much more efficient and calculates just the aggregated usage which is available at the top of the /proc/stat file.

If the information is not available, it will return nil.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/linux_stat/cpu.rb', line 54

def total_usage(sleep = ticks_to_ms)
	return nil unless stat?

	data = IO.foreach('/proc/stat').first.split.tap(&:shift).map!(&:to_f)
	sleep(sleep)
	data2 = IO.foreach('/proc/stat').first.split.tap(&:shift).map!(&:to_f)

	user, nice, sys, idle, iowait, irq, softirq, steal = *data
	user2, nice2, sys2, idle2, iowait2, irq2, softirq2, steal2 = *data2

	idle_then, idle_now  = idle + iowait, idle2 + iowait2
	totald = idle_now.+(user2 + nice2 + sys2 + irq2 + softirq2 + steal2) - idle_then.+(user + nice + sys + irq + softirq + steal)
	totald.-(idle_now - idle_then).fdiv(totald).*(100).round(2).abs
end