Commit 4624e887 authored by refold's avatar refold
Browse files

Initialise the 'jobs' config file setting with the current number of CPU cores.

Fixes #982. Additionally, running 'install -j' without the numerical argument
will have the same effect at runtime.

Side effect: 'install -jNUM' doesn't work when there's a space between -j and
NUM.
parent 38a79ab9
...@@ -36,6 +36,8 @@ import Distribution.Client.Setup ...@@ -36,6 +36,8 @@ import Distribution.Client.Setup
, UploadFlags(..), uploadCommand , UploadFlags(..), uploadCommand
, ReportFlags(..), reportCommand , ReportFlags(..), reportCommand
, showRepo, parseRepo ) , showRepo, parseRepo )
import Distribution.Client.Utils
( numberOfProcessors )
import Distribution.Simple.Compiler import Distribution.Simple.Compiler
( OptimisationLevel(..) ) ( OptimisationLevel(..) )
...@@ -200,7 +202,8 @@ initialSavedConfig = do ...@@ -200,7 +202,8 @@ initialSavedConfig = do
}, },
savedInstallFlags = mempty { savedInstallFlags = mempty {
installSummaryFile = [toPathTemplate (logsDir </> "build.log")], installSummaryFile = [toPathTemplate (logsDir </> "build.log")],
installBuildReports= toFlag AnonymousReports installBuildReports= toFlag AnonymousReports,
installNumJobs = toFlag (Just numberOfProcessors)
} }
} }
......
...@@ -93,7 +93,7 @@ import Distribution.Simple.Setup ...@@ -93,7 +93,7 @@ import Distribution.Simple.Setup
, toFlag, fromFlag, fromFlagOrDefault, flagToMaybe ) , toFlag, fromFlag, fromFlagOrDefault, flagToMaybe )
import qualified Distribution.Simple.Setup as Cabal import qualified Distribution.Simple.Setup as Cabal
( installCommand, InstallFlags(..), emptyInstallFlags ( installCommand, InstallFlags(..), emptyInstallFlags
, emptyTestFlags, testCommand ) , emptyTestFlags, testCommand, Flag(..) )
import Distribution.Simple.Utils import Distribution.Simple.Utils
( rawSystemExit, comparing ) ( rawSystemExit, comparing )
import Distribution.Simple.InstallDirs as InstallDirs import Distribution.Simple.InstallDirs as InstallDirs
...@@ -114,7 +114,7 @@ import Distribution.Version ...@@ -114,7 +114,7 @@ import Distribution.Version
import Distribution.Simple.Utils as Utils import Distribution.Simple.Utils as Utils
( notice, info, warn, die, intercalate, withTempDirectory ) ( notice, info, warn, die, intercalate, withTempDirectory )
import Distribution.Client.Utils import Distribution.Client.Utils
( inDir, mergeBy, MergeResult(..) ) ( numberOfProcessors, inDir, mergeBy, MergeResult(..) )
import Distribution.System import Distribution.System
( Platform, buildPlatform, OS(Windows), buildOS ) ( Platform, buildPlatform, OS(Windows), buildOS )
import Distribution.Text import Distribution.Text
...@@ -767,7 +767,10 @@ performInstallations verbosity ...@@ -767,7 +767,10 @@ performInstallations verbosity
platform = InstallPlan.planPlatform installPlan platform = InstallPlan.planPlatform installPlan
compid = InstallPlan.planCompiler installPlan compid = InstallPlan.planCompiler installPlan
numJobs = fromFlag (installNumJobs installFlags) numJobs = case installNumJobs installFlags of
Cabal.NoFlag -> 1
Cabal.Flag Nothing -> numberOfProcessors
Cabal.Flag (Just n) -> n
numFetchJobs = 2 numFetchJobs = 2
parallelBuild = numJobs >= 2 parallelBuild = numJobs >= 2
...@@ -825,14 +828,14 @@ performInstallations verbosity ...@@ -825,14 +828,14 @@ performInstallations verbosity
useDefaultTemplate useDefaultTemplate
| reportingLevel == DetailedReports = True | reportingLevel == DetailedReports = True
| isJust installLogFile' = False | isJust installLogFile' = False
| numJobs > 1 = True | parallelBuild = True
| otherwise = False | otherwise = False
overrideVerbosity :: Bool overrideVerbosity :: Bool
overrideVerbosity overrideVerbosity
| reportingLevel == DetailedReports = True | reportingLevel == DetailedReports = True
| isJust installLogFile' = True | isJust installLogFile' = True
| numJobs > 1 = False | parallelBuild = False
| otherwise = False | otherwise = False
substLogFileName :: PathTemplate -> PackageIdentifier -> FilePath substLogFileName :: PathTemplate -> PackageIdentifier -> FilePath
......
...@@ -616,7 +616,7 @@ data InstallFlags = InstallFlags { ...@@ -616,7 +616,7 @@ data InstallFlags = InstallFlags {
installBuildReports :: Flag ReportLevel, installBuildReports :: Flag ReportLevel,
installSymlinkBinDir :: Flag FilePath, installSymlinkBinDir :: Flag FilePath,
installOneShot :: Flag Bool, installOneShot :: Flag Bool,
installNumJobs :: Flag Int installNumJobs :: Flag (Maybe Int)
} }
defaultInstallFlags :: InstallFlags defaultInstallFlags :: InstallFlags
...@@ -640,7 +640,7 @@ defaultInstallFlags = InstallFlags { ...@@ -640,7 +640,7 @@ defaultInstallFlags = InstallFlags {
installBuildReports = Flag NoReports, installBuildReports = Flag NoReports,
installSymlinkBinDir = mempty, installSymlinkBinDir = mempty,
installOneShot = Flag False, installOneShot = Flag False,
installNumJobs = Flag 1 installNumJobs = mempty
} }
where where
docIndexFile = toPathTemplate ("$datadir" </> "doc" </> "index.html") docIndexFile = toPathTemplate ("$datadir" </> "doc" </> "index.html")
...@@ -792,9 +792,11 @@ installOptions showOrParseArgs = ...@@ -792,9 +792,11 @@ installOptions showOrParseArgs =
, option "j" ["jobs"] , option "j" ["jobs"]
"Run NUM jobs simultaneously." "Run NUM jobs simultaneously."
installNumJobs (\v flags -> flags { installNumJobs = v }) installNumJobs (\v flags -> flags { installNumJobs = v })
(reqArg "NUM" (readP_to_E (\_ -> "jobs should be a number") (optArg "NUM" (readP_to_E (\_ -> "jobs should be a number")
(fmap toFlag (Parse.readS_to_P reads))) (fmap (toFlag . Just)
(map show . flagToList)) (Parse.readS_to_P reads)))
(Flag Nothing)
(map (fmap show) . flagToList))
] ++ case showOrParseArgs of -- TODO: remove when "cabal install" avoids ] ++ case showOrParseArgs of -- TODO: remove when "cabal install" avoids
ParseArgs -> ParseArgs ->
option [] ["only"] option [] ["only"]
......
module Distribution.Client.Utils where {-# LANGUAGE ForeignFunctionInterface #-}
module Distribution.Client.Utils ( MergeResult(..)
, mergeBy, duplicates, duplicatesBy
, moreRecentFile, inDir, numberOfProcessors )
where
import Data.List import Data.List
( sortBy, groupBy ) ( sortBy, groupBy )
import Foreign.C.Types ( CInt(..) )
import System.Directory import System.Directory
( doesFileExist, getModificationTime ( doesFileExist, getModificationTime
, getCurrentDirectory, setCurrentDirectory ) , getCurrentDirectory, setCurrentDirectory )
import System.IO.Unsafe ( unsafePerformIO )
import qualified Control.Exception as Exception import qualified Control.Exception as Exception
( finally ) ( finally )
...@@ -58,3 +65,10 @@ inDir (Just d) m = do ...@@ -58,3 +65,10 @@ inDir (Just d) m = do
old <- getCurrentDirectory old <- getCurrentDirectory
setCurrentDirectory d setCurrentDirectory d
m `Exception.finally` setCurrentDirectory old m `Exception.finally` setCurrentDirectory old
foreign import ccall "getNumberOfProcessors" c_getNumberOfProcessors :: IO CInt
-- The number of processors is not going to change during the duration of the
-- program, so unsafePerformIO is safe here.
numberOfProcessors :: Int
numberOfProcessors = fromEnum $ unsafePerformIO c_getNumberOfProcessors
...@@ -136,4 +136,5 @@ Executable cabal ...@@ -136,4 +136,5 @@ Executable cabal
cpp-options: -DWIN32 cpp-options: -DWIN32
else else
build-depends: unix >= 1.0 && < 2.6 build-depends: unix >= 1.0 && < 2.6
extensions: CPP extensions: CPP, ForeignFunctionInterface
c-sources: cbits/getnumcores.c
#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 612)
/* Since version 6.12, GHC's threaded RTS includes a getNumberOfProcessors
function, so we try to use that if available. cabal-install is always built
with -threaded nowadays. */
#define HAS_GET_NUMBER_OF_PROCESSORS
#endif
#ifndef HAS_GET_NUMBER_OF_PROCESSORS
#ifdef _WIN32
#include <windows.h>
#elif MACOS
#include <sys/param.h>
#include <sys/sysctl.h>
#elif __linux__
#include <unistd.h>
#endif
int getNumberOfProcessors() {
#ifdef WIN32
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
#elif MACOS
int nm[2];
size_t len = 4;
uint32_t count;
nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) {
nm[1] = HW_NCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) { count = 1; }
}
return count;
#elif __linux__
return sysconf(_SC_NPROCESSORS_ONLN);
#else
return 1;
#endif
}
#endif /* HAS_GET_NUMBER_OF_PROCESSORS */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment