From dab870854a1edcf0fd1492c81f581b44035d2be0 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 12 May 2017 13:50:45 -0400 Subject: [PATCH] add Rscons.n_threads --- lib/rscons.rb | 42 +++++++++++++++++++++++++++++ spec/rscons_spec.rb | 66 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/lib/rscons.rb b/lib/rscons.rb index c760982..2ef06d0 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -41,6 +41,10 @@ module Rscons class << self + # @return [Integer] + # The number of threads to use when scheduling subprocesses. + attr_accessor :n_threads + # Remove all generated files. # # @return [void] @@ -147,7 +151,45 @@ module Rscons @command_executer = val end + private + + # Determine the number of threads to use by default. + # + # @return [Integer] + # The number of threads to use by default. + def determine_n_threads + # If the user specifies the number of threads in the environment, then + # respect that. + if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/ + return $1.to_i + end + + # Otherwise try to figure out how many threads are available on the + # host hardware. + begin + case RbConfig::CONFIG["host_os"] + when /linux/ + return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size + when /mswin|mingw/ + if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/ + return $1.to_i + end + when /darwin/ + if `sysctl -n hw.ncpu` =~ /(\d+)/ + return $1.to_i + end + end + rescue + end + + # If we can't figure it out, default to 1. + 1 + end + end + + @n_threads = determine_n_threads + end # Unbuffer $stdout diff --git a/spec/rscons_spec.rb b/spec/rscons_spec.rb index 6c6660b..6468f9e 100644 --- a/spec/rscons_spec.rb +++ b/spec/rscons_spec.rb @@ -122,4 +122,70 @@ describe Rscons do end end end + + describe ".determine_n_threads" do + context "when specified by environment variable" do + before(:each) do + expect(ENV).to receive(:[]).with("RSCONS_NTHREADS").and_return("3") + end + it "returns the user-specified number of threads to use" do + expect(Rscons.__send__(:determine_n_threads)).to eq(3) + end + end + + context "when not specified by environment variable" do + before(:each) do + expect(ENV).to receive(:[]).with("RSCONS_NTHREADS").and_return(nil) + end + + context "on Linux" do + before(:each) do + expect(RbConfig::CONFIG).to receive(:[]).with("host_os").and_return("linux") + end + it "returns the number of processors from /proc/cpuinfo" do + expect(File).to receive(:read).with("/proc/cpuinfo").and_return(<