Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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.
  • Loading branch information...
commit c247ec758d9dd4dad1147b48e113bdb9e6da56c2 1 parent e7e7ce1
Mikhail Glushenkov 23Skidoo authored tibbe committed
5 cabal-install/Distribution/Client/Config.hs
@@ -36,6 +36,8 @@ import Distribution.Client.Setup
36 36 , UploadFlags(..), uploadCommand
37 37 , ReportFlags(..), reportCommand
38 38 , showRepo, parseRepo )
  39 +import Distribution.Client.Utils
  40 + ( numberOfProcessors )
39 41
40 42 import Distribution.Simple.Compiler
41 43 ( OptimisationLevel(..) )
@@ -200,7 +202,8 @@ initialSavedConfig = do
200 202 },
201 203 savedInstallFlags = mempty {
202 204 installSummaryFile = [toPathTemplate (logsDir </> "build.log")],
203   - installBuildReports= toFlag AnonymousReports
  205 + installBuildReports= toFlag AnonymousReports,
  206 + installNumJobs = toFlag (Just numberOfProcessors)
204 207 }
205 208 }
206 209
13 cabal-install/Distribution/Client/Install.hs
@@ -93,7 +93,7 @@ import Distribution.Simple.Setup
93 93 , toFlag, fromFlag, fromFlagOrDefault, flagToMaybe )
94 94 import qualified Distribution.Simple.Setup as Cabal
95 95 ( installCommand, InstallFlags(..), emptyInstallFlags
96   - , emptyTestFlags, testCommand )
  96 + , emptyTestFlags, testCommand, Flag(..) )
97 97 import Distribution.Simple.Utils
98 98 ( rawSystemExit, comparing )
99 99 import Distribution.Simple.InstallDirs as InstallDirs
@@ -114,7 +114,7 @@ import Distribution.Version
114 114 import Distribution.Simple.Utils as Utils
115 115 ( notice, info, warn, die, intercalate, withTempDirectory )
116 116 import Distribution.Client.Utils
117   - ( inDir, mergeBy, MergeResult(..) )
  117 + ( numberOfProcessors, inDir, mergeBy, MergeResult(..) )
118 118 import Distribution.System
119 119 ( Platform, buildPlatform, OS(Windows), buildOS )
120 120 import Distribution.Text
@@ -767,7 +767,10 @@ performInstallations verbosity
767 767 platform = InstallPlan.planPlatform installPlan
768 768 compid = InstallPlan.planCompiler installPlan
769 769
770   - numJobs = fromFlag (installNumJobs installFlags)
  770 + numJobs = case installNumJobs installFlags of
  771 + Cabal.NoFlag -> 1
  772 + Cabal.Flag Nothing -> numberOfProcessors
  773 + Cabal.Flag (Just n) -> n
771 774 numFetchJobs = 2
772 775 parallelBuild = numJobs >= 2
773 776
@@ -825,14 +828,14 @@ performInstallations verbosity
825 828 useDefaultTemplate
826 829 | reportingLevel == DetailedReports = True
827 830 | isJust installLogFile' = False
828   - | numJobs > 1 = True
  831 + | parallelBuild = True
829 832 | otherwise = False
830 833
831 834 overrideVerbosity :: Bool
832 835 overrideVerbosity
833 836 | reportingLevel == DetailedReports = True
834 837 | isJust installLogFile' = True
835   - | numJobs > 1 = False
  838 + | parallelBuild = False
836 839 | otherwise = False
837 840
838 841 substLogFileName :: PathTemplate -> PackageIdentifier -> FilePath
12 cabal-install/Distribution/Client/Setup.hs
@@ -616,7 +616,7 @@ data InstallFlags = InstallFlags {
616 616 installBuildReports :: Flag ReportLevel,
617 617 installSymlinkBinDir :: Flag FilePath,
618 618 installOneShot :: Flag Bool,
619   - installNumJobs :: Flag Int
  619 + installNumJobs :: Flag (Maybe Int)
620 620 }
621 621
622 622 defaultInstallFlags :: InstallFlags
@@ -640,7 +640,7 @@ defaultInstallFlags = InstallFlags {
640 640 installBuildReports = Flag NoReports,
641 641 installSymlinkBinDir = mempty,
642 642 installOneShot = Flag False,
643   - installNumJobs = Flag 1
  643 + installNumJobs = mempty
644 644 }
645 645 where
646 646 docIndexFile = toPathTemplate ("$datadir" </> "doc" </> "index.html")
@@ -792,9 +792,11 @@ installOptions showOrParseArgs =
792 792 , option "j" ["jobs"]
793 793 "Run NUM jobs simultaneously."
794 794 installNumJobs (\v flags -> flags { installNumJobs = v })
795   - (reqArg "NUM" (readP_to_E (\_ -> "jobs should be a number")
796   - (fmap toFlag (Parse.readS_to_P reads)))
797   - (map show . flagToList))
  795 + (optArg "NUM" (readP_to_E (\_ -> "jobs should be a number")
  796 + (fmap (toFlag . Just)
  797 + (Parse.readS_to_P reads)))
  798 + (Flag Nothing)
  799 + (map (fmap show) . flagToList))
798 800 ] ++ case showOrParseArgs of -- TODO: remove when "cabal install" avoids
799 801 ParseArgs ->
800 802 option [] ["only"]
16 cabal-install/Distribution/Client/Utils.hs
... ... @@ -1,10 +1,17 @@
1   -module Distribution.Client.Utils where
  1 +{-# LANGUAGE ForeignFunctionInterface #-}
  2 +
  3 +module Distribution.Client.Utils ( MergeResult(..)
  4 + , mergeBy, duplicates, duplicatesBy
  5 + , moreRecentFile, inDir, numberOfProcessors )
  6 + where
2 7
3 8 import Data.List
4 9 ( sortBy, groupBy )
  10 +import Foreign.C.Types ( CInt(..) )
5 11 import System.Directory
6 12 ( doesFileExist, getModificationTime
7 13 , getCurrentDirectory, setCurrentDirectory )
  14 +import System.IO.Unsafe ( unsafePerformIO )
8 15 import qualified Control.Exception as Exception
9 16 ( finally )
10 17
@@ -58,3 +65,10 @@ inDir (Just d) m = do
58 65 old <- getCurrentDirectory
59 66 setCurrentDirectory d
60 67 m `Exception.finally` setCurrentDirectory old
  68 +
  69 +foreign import ccall "getNumberOfProcessors" c_getNumberOfProcessors :: IO CInt
  70 +
  71 +-- The number of processors is not going to change during the duration of the
  72 +-- program, so unsafePerformIO is safe here.
  73 +numberOfProcessors :: Int
  74 +numberOfProcessors = fromEnum $ unsafePerformIO c_getNumberOfProcessors
3  cabal-install/cabal-install.cabal
@@ -136,4 +136,5 @@ Executable cabal
136 136 cpp-options: -DWIN32
137 137 else
138 138 build-depends: unix >= 1.0 && < 2.6
139   - extensions: CPP
  139 + extensions: CPP, ForeignFunctionInterface
  140 + c-sources: cbits/getnumcores.c
46 cabal-install/cbits/getnumcores.c
... ... @@ -0,0 +1,46 @@
  1 +#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 612)
  2 +/* Since version 6.12, GHC's threaded RTS includes a getNumberOfProcessors
  3 + function, so we try to use that if available. cabal-install is always built
  4 + with -threaded nowadays. */
  5 +#define HAS_GET_NUMBER_OF_PROCESSORS
  6 +#endif
  7 +
  8 +
  9 +#ifndef HAS_GET_NUMBER_OF_PROCESSORS
  10 +
  11 +#ifdef _WIN32
  12 +#include <windows.h>
  13 +#elif MACOS
  14 +#include <sys/param.h>
  15 +#include <sys/sysctl.h>
  16 +#elif __linux__
  17 +#include <unistd.h>
  18 +#endif
  19 +
  20 +int getNumberOfProcessors() {
  21 +#ifdef WIN32
  22 + SYSTEM_INFO sysinfo;
  23 + GetSystemInfo(&sysinfo);
  24 + return sysinfo.dwNumberOfProcessors;
  25 +#elif MACOS
  26 + int nm[2];
  27 + size_t len = 4;
  28 + uint32_t count;
  29 +
  30 + nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
  31 + sysctl(nm, 2, &count, &len, NULL, 0);
  32 +
  33 + if(count < 1) {
  34 + nm[1] = HW_NCPU;
  35 + sysctl(nm, 2, &count, &len, NULL, 0);
  36 + if(count < 1) { count = 1; }
  37 + }
  38 + return count;
  39 +#elif __linux__
  40 + return sysconf(_SC_NPROCESSORS_ONLN);
  41 +#else
  42 + return 1;
  43 +#endif
  44 +}
  45 +
  46 +#endif /* HAS_GET_NUMBER_OF_PROCESSORS */

0 comments on commit c247ec7

Please sign in to comment.
Something went wrong with that request. Please try again.