class Duffy::System

Depending on your hardware, you may want to make decisions in your code. I use this to figure out how many processes I can launch in parallel.

Public Class Methods

battery_percent() click to toggle source

The battery percentage 0.0 .. 100.0 nil if no battery or error reading value. Darwin: pmset -g batt Linux:

# File lib/duffy/system.rb, line 99
def battery_percent
  case RUBY_PLATFORM
    when /darwin/ then `pmset -g batt`.scan(/^.*\t(.*%);/)[0][0].to_f
    when /linux/  then File.read("/sys/class/power_supply/BAT0/charge_now").to_i * 100 / File.read("/sys/class/power_supply/BAT0/charge_full").to_i
    else nil
  end
rescue
  nil
end
cores() click to toggle source

How many actual CPU cores do we have not including Hyperthreading Linux: “cpu cores” in cpuinfo is on a per physical processor basis, so we multiply by the number of CPUs Mac: hw.physicalcpu

# File lib/duffy/system.rb, line 22
def cores
  case RUBY_PLATFORM
    when /linux/  then File.read('/proc/cpuinfo').scan(/(cpu cores)(\D)*(\d+)/)[0][2].to_i * cpus
    when /darwin/ then `sysctl -n hw.physicalcpu`.to_i
    else 1
  end
rescue
  1
end
cpu_percent() click to toggle source

The system's current CPU utilization. Darwin: Get a list of all processes' CPU percentage and add them up. Linux: Read /proc/stat twice and take the difference to give cpu time used in that interval.

# File lib/duffy/system.rb, line 62
def cpu_percent
  case RUBY_PLATFORM
    when /darwin/ then `ps -A -o %cpu`.lines.map(&:to_f).inject(:+) / threads
    when /linux/  then proc_diff
    else 0
  end
rescue
  0
end
cpus() click to toggle source

How many Physical CPUs do you have. Linux: Detected by counting unique physical IDs Mac: hw.packages

# File lib/duffy/system.rb, line 9
def cpus
  case RUBY_PLATFORM
    when /linux/  then File.read('/proc/cpuinfo').scan(/^physical id.*/).uniq.count
    when /darwin/ then `sysctl -n hw.packages`.to_i
    else 1
  end
rescue
  1
end
freespace() click to toggle source

Disk Freespace Looks at current working directory

# File lib/duffy/system.rb, line 74
def freespace
  case RUBY_PLATFORM
    when /darwin/ then `df -m #{Shellwords.shellescape(Dir.pwd)}`.lines[1].split[3].to_i
    when /linux/  then `df -m #{Shellwords.shellescape(Dir.pwd)}`.lines[1].split[3].to_i
    else 0
  end
end
mem_available() click to toggle source

Memory available for use in Megabytes Darwin: vm_stat (Pages Free + Pages Inactive) Linux: Read /proc/meminfo

# File lib/duffy/system.rb, line 112
def mem_available
  case RUBY_PLATFORM
    when /darwin/ then `vm_stat`.lines.grep(/(free:|inactive:)\s*(\d+)/){$2}.map(&:to_i).inject(:+) * 4 / 1024
    when /linux/  then File.read("/proc/meminfo").lines.grep(/MemAvail|MemFree/).sort.first.split[1].to_i / 1024
    else 0
  end
rescue
  0
end
mem_percent() click to toggle source

Percentage of Memory used, 0.0 .. 100.0

# File lib/duffy/system.rb, line 130
def mem_percent
  (100.0 * mem_used / mem_total).round(1)
rescue
  0
end
mem_total() click to toggle source

Total system memory in Megabytes Darwin: hw.memsize (bytes) Linux: Read /proc/meminfo

# File lib/duffy/system.rb, line 85
def mem_total
  case RUBY_PLATFORM
    when /darwin/ then `sysctl -n hw.memsize`.to_i / 1024 / 1024
    when /linux/  then File.read("/proc/meminfo").scan(/MemTotal:\s*(\d+)/)[0][0].to_i / 1024
    else 0
  end
rescue
  0
end
mem_used() click to toggle source

Memory used Subtract mem_available from mem_total. This ignores file cache etc that is not actually used by programs.

# File lib/duffy/system.rb, line 125
def mem_used
  mem_total - mem_available
end
sane_load() click to toggle source

What is a sane number of threads to use for data processing. You want to leave some headroom for your database etc running in other processes.

# File lib/duffy/system.rb, line 55
def sane_load
  threads * 3 / 4
end
threads() click to toggle source

How many threads does the system have.

# File lib/duffy/system.rb, line 33
def threads
  case RUBY_PLATFORM
    when /linux/  then File.read('/proc/cpuinfo').scan(/^processor\s*:/).size
    when /darwin/ then `sysctl -n hw.ncpu`.to_i
    else 1
  end
rescue
  1
end
virtual?() click to toggle source
# File lib/duffy/system.rb, line 43
def virtual?
  case RUBY_PLATFORM
    when /linux/  then !!File.read('/proc/cpuinfo').scan(/^flags.*(hypervisor)/)[0]
    when /darwin/ then false # PENDING
    else false
  end
rescue
  false
end

Private Class Methods

proc_diff() click to toggle source

Poll proc_stat twice and find the usage in that time. Higher Sleep is more accurate, but obviously slower. LINUX

# File lib/duffy/system.rb, line 149
def proc_diff
  s = proc_stat
  sleep 0.2
  f = proc_stat
  (f[0] - s[0]) * 100.0 / (f[1] - s[1])
end
proc_stat() click to toggle source
CPU USE, CPU IDLE

LINUX

# File lib/duffy/system.rb, line 141
def proc_stat
  cpu = File.open("/proc/stat", "r").read.lines.first
  [cpu.split[1..3].map(&:to_i).inject(:+), cpu.split[1..4].map(&:to_i).inject(:+)]
end