Zubin pushed to branch wip/semaphore-v2 at Glasgow Haskell Compiler / GHC
Commits:
-
d7e90c63
by Zubin Duggal at 2026-03-17T16:20:53+05:30
15 changed files:
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- hadrian/cabal.project
- hadrian/hadrian.cabal
- hadrian/src/Flavour.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings/Packages.hs
- libraries/semaphore-compat
Changes:
| ... | ... | @@ -282,6 +282,15 @@ instance Diagnostic DriverMessage where |
| 282 | 282 | -> mkSimpleDecorated $
|
| 283 | 283 | vcat [ text "The following modules are missing a linkable which is needed for creating a library:"
|
| 284 | 284 | , nest 2 $ hcat (map ppr mods) ]
|
| 285 | + DriverSemaphoreVersionMismatch received supported
|
|
| 286 | + -> mkSimpleDecorated $
|
|
| 287 | + text "Semaphore version mismatch (received v" <> int received <>
|
|
| 288 | + text ", this GHC supports v" <> int supported <>
|
|
| 289 | + text "); ignoring -jsem and compiling sequentially."
|
|
| 290 | + DriverSemaphoreOpenFailure reason
|
|
| 291 | + -> mkSimpleDecorated $
|
|
| 292 | + text "Failed to open -jsem semaphore:" <+> text reason <>
|
|
| 293 | + text "; ignoring -jsem and compiling sequentially."
|
|
| 285 | 294 | |
| 286 | 295 | diagnosticReason = \case
|
| 287 | 296 | DriverUnknownMessage m
|
| ... | ... | @@ -355,6 +364,10 @@ instance Diagnostic DriverMessage where |
| 355 | 364 | -> WarningWithoutFlag
|
| 356 | 365 | DriverMissingLinkableForModule {}
|
| 357 | 366 | -> ErrorWithoutFlag
|
| 367 | + DriverSemaphoreVersionMismatch {}
|
|
| 368 | + -> WarningWithFlag Opt_WarnSemaphoreVersionMismatch
|
|
| 369 | + DriverSemaphoreOpenFailure {}
|
|
| 370 | + -> WarningWithFlag Opt_WarnSemaphoreOpenFailure
|
|
| 358 | 371 | |
| 359 | 372 | diagnosticHints = \case
|
| 360 | 373 | DriverUnknownMessage m
|
| ... | ... | @@ -430,5 +443,14 @@ instance Diagnostic DriverMessage where |
| 430 | 443 | -> noHints
|
| 431 | 444 | DriverMissingLinkableForModule {}
|
| 432 | 445 | -> noHints
|
| 446 | + DriverSemaphoreVersionMismatch received _supported
|
|
| 447 | + | received < _supported
|
|
| 448 | + -> [UnknownHint (text "The parent process (e.g. cabal-install) uses an older semaphore protocol."
|
|
| 449 | + $$ text "Upgrading cabal-install may resolve this." :: SDoc)]
|
|
| 450 | + | otherwise
|
|
| 451 | + -> [UnknownHint (text "The parent process (e.g. cabal-install) uses a newer semaphore protocol."
|
|
| 452 | + $$ text "Upgrading GHC may resolve this." :: SDoc)]
|
|
| 453 | + DriverSemaphoreOpenFailure {}
|
|
| 454 | + -> noHints
|
|
| 433 | 455 | |
| 434 | 456 | diagnosticCode = constructorCode @GHC |
| ... | ... | @@ -419,6 +419,23 @@ data DriverMessage where |
| 419 | 419 | |
| 420 | 420 | DriverMissingLinkableForModule :: ![Module] -> DriverMessage
|
| 421 | 421 | |
| 422 | + {-| DriverSemaphoreVersionMismatch is a warning that occurs when GHC
|
|
| 423 | + receives a @-jsem@ semaphore name whose protocol version is incompatible
|
|
| 424 | + with the version this GHC supports. GHC ignores @-jsem@ and compiles
|
|
| 425 | + sequentially.
|
|
| 426 | + |
|
| 427 | + The first field is the received version (or 1 for unversioned names),
|
|
| 428 | + the second is the version this GHC supports.
|
|
| 429 | + -}
|
|
| 430 | + DriverSemaphoreVersionMismatch :: !Int -> !Int -> DriverMessage
|
|
| 431 | + |
|
| 432 | + {-| DriverSemaphoreOpenFailure is a warning that occurs when GHC fails to
|
|
| 433 | + open the semaphore specified by @-jsem@ (e.g. the socket does not exist
|
|
| 434 | + or a system error occurred). GHC ignores @-jsem@ and compiles
|
|
| 435 | + sequentially.
|
|
| 436 | + -}
|
|
| 437 | + DriverSemaphoreOpenFailure :: !String -> DriverMessage
|
|
| 438 | + |
|
| 422 | 439 | deriving instance Generic DriverMessage
|
| 423 | 440 | |
| 424 | 441 | data DriverMessageOpts =
|
| ... | ... | @@ -1110,6 +1110,8 @@ data WarningFlag = |
| 1110 | 1110 | -- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
|
| 1111 | 1111 | | Opt_WarnUnusableUnpackPragmas -- Since 9.14
|
| 1112 | 1112 | | Opt_WarnPatternNamespaceSpecifier -- Since 9.14
|
| 1113 | + | Opt_WarnSemaphoreVersionMismatch -- Since 10.0.1
|
|
| 1114 | + | Opt_WarnSemaphoreOpenFailure -- Since 10.0.1
|
|
| 1113 | 1115 | deriving (Eq, Ord, Show, Enum, Bounded)
|
| 1114 | 1116 | |
| 1115 | 1117 | -- | Return the names of a WarningFlag
|
| ... | ... | @@ -1231,6 +1233,8 @@ warnFlagNames wflag = case wflag of |
| 1231 | 1233 | Opt_WarnRuleLhsEqualities -> "rule-lhs-equalities" :| []
|
| 1232 | 1234 | Opt_WarnUnusableUnpackPragmas -> "unusable-unpack-pragmas" :| []
|
| 1233 | 1235 | Opt_WarnPatternNamespaceSpecifier -> "pattern-namespace-specifier" :| []
|
| 1236 | + Opt_WarnSemaphoreVersionMismatch -> "semaphore-version-mismatch" :| []
|
|
| 1237 | + Opt_WarnSemaphoreOpenFailure -> "semaphore-open-failure" :| []
|
|
| 1234 | 1238 | |
| 1235 | 1239 | -- -----------------------------------------------------------------------------
|
| 1236 | 1240 | -- Standard sets of warning options
|
| ... | ... | @@ -1376,7 +1380,9 @@ standardWarnings -- see Note [Documenting warning flags] |
| 1376 | 1380 | Opt_WarnUselessSpecialisations,
|
| 1377 | 1381 | Opt_WarnDeprecatedPragmas,
|
| 1378 | 1382 | Opt_WarnRuleLhsEqualities,
|
| 1379 | - Opt_WarnUnusableUnpackPragmas
|
|
| 1383 | + Opt_WarnUnusableUnpackPragmas,
|
|
| 1384 | + Opt_WarnSemaphoreVersionMismatch,
|
|
| 1385 | + Opt_WarnSemaphoreOpenFailure
|
|
| 1380 | 1386 | ]
|
| 1381 | 1387 | |
| 1382 | 1388 | -- | Things you get with @-W@.
|
| ... | ... | @@ -28,6 +28,16 @@ import GHC.Driver.Errors.Types |
| 28 | 28 | import GHC.Driver.Messager
|
| 29 | 29 | import GHC.Driver.MakeSem
|
| 30 | 30 | |
| 31 | +import System.Semaphore
|
|
| 32 | + ( SemaphoreError(..)
|
|
| 33 | + , semaphoreVersion, versionsAreCompatible, parseSemaphoreName )
|
|
| 34 | + |
|
| 35 | +import GHC.Driver.Config.Diagnostic ( initDiagOpts, initPrintConfig )
|
|
| 36 | +import GHC.Driver.Errors ( printOrThrowDiagnostics )
|
|
| 37 | +import GHC.Driver.Errors.Types ( DriverMessage(..), GhcMessage(..) )
|
|
| 38 | +import GHC.Types.Error ( singleMessage )
|
|
| 39 | +import GHC.Types.SrcLoc ( noSrcSpan )
|
|
| 40 | +import GHC.Utils.Error ( mkPlainMsgEnvelope )
|
|
| 31 | 41 | import GHC.Utils.Logger
|
| 32 | 42 | import GHC.Utils.TmpFs
|
| 33 | 43 | |
| ... | ... | @@ -122,17 +132,34 @@ runNjobsAbstractSem n_jobs action = do |
| 122 | 132 | resetNumCapabilities = set_num_caps n_capabilities
|
| 123 | 133 | MC.bracket_ updNumCapabilities resetNumCapabilities $ action asem
|
| 124 | 134 | |
| 125 | -runWorkerLimit :: WorkerLimit -> (AbstractSem -> IO a) -> IO a
|
|
| 135 | +runWorkerLimit :: Logger -> DynFlags -> WorkerLimit -> (AbstractSem -> IO a) -> IO a
|
|
| 126 | 136 | #if defined(wasm32_HOST_ARCH)
|
| 127 | -runWorkerLimit _ action = do
|
|
| 137 | +runWorkerLimit _logger _dflags _ action = do
|
|
| 128 | 138 | lock <- newMVar ()
|
| 129 | 139 | action $ AbstractSem (takeMVar lock) (putMVar lock ())
|
| 130 | 140 | #else
|
| 131 | -runWorkerLimit worker_limit action = case worker_limit of
|
|
| 141 | +runWorkerLimit logger dflags worker_limit action = case worker_limit of
|
|
| 132 | 142 | NumProcessorsLimit n_jobs ->
|
| 133 | 143 | runNjobsAbstractSem n_jobs action
|
| 134 | 144 | JSemLimit sem ->
|
| 135 | - runJSemAbstractSem sem action
|
|
| 145 | + let received_ver = case parseSemaphoreName (getSemaphoreName sem) of
|
|
| 146 | + Just (ver, _) -> ver
|
|
| 147 | + Nothing -> 1
|
|
| 148 | + in if versionsAreCompatible received_ver semaphoreVersion
|
|
| 149 | + then do
|
|
| 150 | + result <- MC.try $ runJSemAbstractSem sem action
|
|
| 151 | + case result of
|
|
| 152 | + Right a -> return a
|
|
| 153 | + Left (err :: SemaphoreError) -> do
|
|
| 154 | + let diag = DriverSemaphoreOpenFailure (show err)
|
|
| 155 | + msg = singleMessage $ mkPlainMsgEnvelope (initDiagOpts dflags) noSrcSpan diag
|
|
| 156 | + printOrThrowDiagnostics logger (initPrintConfig dflags) (initDiagOpts dflags) (GhcDriverMessage <$> msg)
|
|
| 157 | + runNjobsAbstractSem 1 action
|
|
| 158 | + else do
|
|
| 159 | + let diag = DriverSemaphoreVersionMismatch received_ver semaphoreVersion
|
|
| 160 | + msg = singleMessage $ mkPlainMsgEnvelope (initDiagOpts dflags) noSrcSpan diag
|
|
| 161 | + printOrThrowDiagnostics logger (initPrintConfig dflags) (initDiagOpts dflags) (GhcDriverMessage <$> msg)
|
|
| 162 | + runNjobsAbstractSem 1 action
|
|
| 136 | 163 | #endif
|
| 137 | 164 | |
| 138 | 165 | -- | Build and run a pipeline
|
| ... | ... | @@ -159,7 +186,7 @@ runParPipelines worker_limit plugin_hsc_env diag_wrapper mHscMessager all_pipeli |
| 159 | 186 | thread_safe_logger <- liftIO $ makeThreadSafe (hsc_logger plugin_hsc_env)
|
| 160 | 187 | let thread_safe_hsc_env = plugin_hsc_env { hsc_logger = thread_safe_logger }
|
| 161 | 188 | |
| 162 | - runWorkerLimit worker_limit $ \abstract_sem -> do
|
|
| 189 | + runWorkerLimit (hsc_logger plugin_hsc_env) (hsc_dflags plugin_hsc_env) worker_limit $ \abstract_sem -> do
|
|
| 163 | 190 | let env = MakeEnv { hsc_env = thread_safe_hsc_env
|
| 164 | 191 | , withLogger = withParLog log_queue_queue_var
|
| 165 | 192 | , compile_sem = abstract_sem
|
| ... | ... | @@ -439,7 +439,7 @@ jobserverLoop opts sjs@(Jobserver { jobs = jobs_tvar }) |
| 439 | 439 | -- | Create a new jobserver using the given semaphore handle.
|
| 440 | 440 | makeJobserver :: SemaphoreName -> IO (AbstractSem, IO ())
|
| 441 | 441 | makeJobserver sem_name = do
|
| 442 | - semaphore <- openSemaphore sem_name
|
|
| 442 | + semaphore <- openSemaphore sem_name >>= either MC.throwM pure
|
|
| 443 | 443 | let
|
| 444 | 444 | init_jobs =
|
| 445 | 445 | Jobs { tokensOwned = 1
|
| ... | ... | @@ -2444,6 +2444,8 @@ wWarningFlagsDeps = [minBound..maxBound] >>= \x -> case x of |
| 2444 | 2444 | Opt_WarnRuleLhsEqualities -> warnSpec x
|
| 2445 | 2445 | Opt_WarnUnusableUnpackPragmas -> warnSpec x
|
| 2446 | 2446 | Opt_WarnPatternNamespaceSpecifier -> warnSpec x
|
| 2447 | + Opt_WarnSemaphoreVersionMismatch -> warnSpec x
|
|
| 2448 | + Opt_WarnSemaphoreOpenFailure -> warnSpec x
|
|
| 2447 | 2449 | |
| 2448 | 2450 | warningGroupsDeps :: [(Deprecation, FlagSpec WarningGroup)]
|
| 2449 | 2451 | warningGroupsDeps = map mk warningGroups
|
| ... | ... | @@ -402,6 +402,8 @@ type family GhcDiagnosticCode c = n | n -> c where |
| 402 | 402 | GhcDiagnosticCode "DriverInstantiationNodeInDependencyGeneration" = 74284
|
| 403 | 403 | GhcDiagnosticCode "DriverNoConfiguredLLVMToolchain" = 66599
|
| 404 | 404 | GhcDiagnosticCode "DriverMissingLinkableForModule" = 47338
|
| 405 | + GhcDiagnosticCode "DriverSemaphoreVersionMismatch" = 56206
|
|
| 406 | + GhcDiagnosticCode "DriverSemaphoreOpenFailure" = 19877
|
|
| 405 | 407 | |
| 406 | 408 | -- Constraint solver diagnostic codes
|
| 407 | 409 | GhcDiagnosticCode "BadTelescope" = 97739
|
| ... | ... | @@ -2706,6 +2706,37 @@ of ``-W(no-)*``. |
| 2706 | 2706 | |
| 2707 | 2707 | import Data.List.NonEmpty (data (:|))
|
| 2708 | 2708 | |
| 2709 | +.. ghc-flag:: -Wsemaphore-version-mismatch
|
|
| 2710 | + :shortdesc: warn when GHC receives a ``-jsem`` semaphore whose protocol
|
|
| 2711 | + version is incompatible with the version this GHC supports.
|
|
| 2712 | + :type: dynamic
|
|
| 2713 | + :reverse: -Wno-semaphore-version-mismatch
|
|
| 2714 | + :category:
|
|
| 2715 | + |
|
| 2716 | + :since: 10.0.1
|
|
| 2717 | + |
|
| 2718 | + Warn when GHC is invoked with :ghc-flag:`-jsem` but the semaphore
|
|
| 2719 | + name indicates a protocol version that is incompatible with this GHC
|
|
| 2720 | + (e.g. an unversioned v1 name passed to a v2 GHC, or vice versa).
|
|
| 2721 | + When this occurs, GHC ignores ``-jsem`` and compiles modules sequentially.
|
|
| 2722 | + |
|
| 2723 | + This situation typically arises when ``cabal-install`` and GHC are built
|
|
| 2724 | + against different versions of the ``semaphore-compat`` library. Upgrading
|
|
| 2725 | + both to versions that use the same protocol resolves the mismatch.
|
|
| 2726 | + |
|
| 2727 | +.. ghc-flag:: -Wsemaphore-open-failure
|
|
| 2728 | + :shortdesc: warn when GHC cannot open the ``-jsem`` semaphore.
|
|
| 2729 | + :type: dynamic
|
|
| 2730 | + :reverse: -Wno-semaphore-open-failure
|
|
| 2731 | + :category:
|
|
| 2732 | + |
|
| 2733 | + :since: 10.0.1
|
|
| 2734 | + |
|
| 2735 | + Warn when GHC is invoked with :ghc-flag:`-jsem` but the semaphore
|
|
| 2736 | + cannot be opened (e.g. the socket does not exist or a system error
|
|
| 2737 | + occurred). When this occurs, GHC ignores ``-jsem`` and compiles
|
|
| 2738 | + modules sequentially.
|
|
| 2739 | + |
|
| 2709 | 2740 | ----
|
| 2710 | 2741 | |
| 2711 | 2742 | If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
|
| ... | ... | @@ -797,7 +797,14 @@ There are two kinds of participants in the GHC Jobserver protocol: |
| 797 | 797 | |
| 798 | 798 | Perform compilation in parallel when possible, coordinating with other
|
| 799 | 799 | processes through the semaphore ⟨sem⟩ (specified as a string).
|
| 800 | - Error if the semaphore doesn't exist.
|
|
| 800 | + |
|
| 801 | + If the semaphore's protocol version is incompatible, GHC emits a
|
|
| 802 | + :ghc-flag:`-Wsemaphore-version-mismatch` warning and compiles
|
|
| 803 | + sequentially. If the semaphore cannot be opened for other reasons
|
|
| 804 | + (e.g. the socket does not exist), GHC emits a
|
|
| 805 | + :ghc-flag:`-Wsemaphore-open-failure` warning and compiles
|
|
| 806 | + sequentially. In both cases GHC uses only the implicit token
|
|
| 807 | + inherited from the parent process.
|
|
| 801 | 808 | |
| 802 | 809 | Use of ``-jsem`` will override use of :ghc-flag:`-j[⟨n⟩]`,
|
| 803 | 810 | and vice-versa.
|
| 1 | 1 | packages: ./
|
| 2 | 2 | ../utils/ghc-toolchain/
|
| 3 | 3 | ../libraries/ghc-platform/
|
| 4 | + ../libraries/semaphore-compat/
|
|
| 4 | 5 | |
| 5 | 6 | -- This essentially freezes the build plan for hadrian
|
| 6 | 7 | -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh.
|
| ... | ... | @@ -170,6 +170,7 @@ executable hadrian |
| 170 | 170 | , base16-bytestring >= 0.1.1 && < 1.1.0.0
|
| 171 | 171 | , ghc-platform
|
| 172 | 172 | , ghc-toolchain
|
| 173 | + , semaphore-compat
|
|
| 173 | 174 | ghc-options: -Wall
|
| 174 | 175 | -Wincomplete-record-updates
|
| 175 | 176 | -Wredundant-constraints
|
| ... | ... | @@ -149,10 +149,6 @@ werror = |
| 149 | 149 | -- unix has many unused imports
|
| 150 | 150 | , package unix
|
| 151 | 151 | ? mconcat [arg "-Wwarn=unused-imports", arg "-Wwarn=unused-top-binds"]
|
| 152 | - -- semaphore-compat relies on sem_getvalue as provided by unix, which is
|
|
| 153 | - -- not implemented on Darwin and therefore throws a deprecation warning
|
|
| 154 | - , package semaphoreCompat
|
|
| 155 | - ? mconcat [arg "-Wwarn=deprecations"]
|
|
| 156 | 152 | ]
|
| 157 | 153 | , builder Ghc
|
| 158 | 154 | ? package rts
|
| ... | ... | @@ -25,6 +25,7 @@ import Utilities |
| 25 | 25 | import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp))
|
| 26 | 26 | import GHC.Platform.ArchOS
|
| 27 | 27 | import Settings.Program (ghcWithInterpreter)
|
| 28 | +import System.Semaphore (semaphoreVersion)
|
|
| 28 | 29 | |
| 29 | 30 | -- | Track this file to rebuild generated files whenever it changes.
|
| 30 | 31 | trackGenerateHs :: Expr ()
|
| ... | ... | @@ -483,6 +484,7 @@ generateSettings settingsFile = do |
| 483 | 484 | , ("RTS ways", escapeArgs . map show . Set.toList <$> getRtsWays)
|
| 484 | 485 | , ("Relative Global Package DB", pure rel_pkg_db)
|
| 485 | 486 | , ("base unit-id", pure base_unit_id)
|
| 487 | + , ("Semaphore version", pure (show semaphoreVersion))
|
|
| 486 | 488 | ]
|
| 487 | 489 | let showTuple (k, v) = "(" ++ show k ++ ", " ++ show v ++ ")"
|
| 488 | 490 | pure $ case settings of
|
| ... | ... | @@ -230,6 +230,10 @@ packageArgs = do |
| 230 | 230 | , package hpcBin
|
| 231 | 231 | ? builder (Cabal Flags) ? arg "-build-tool-depends"
|
| 232 | 232 | |
| 233 | + ------------------------------ semaphore-compat ----------------------------
|
|
| 234 | + , package semaphoreCompat
|
|
| 235 | + ? builder (Cabal Flags) ? arg "-build-testing"
|
|
| 236 | + |
|
| 233 | 237 | ]
|
| 234 | 238 | |
| 235 | 239 | ghcInternalArgs :: Args
|
| 1 | -Subproject commit ba87d1bb0209bd9f29bda1c878ddf345f8a2b199 |
|
| 1 | +Subproject commit e67d577b50b6630c589be188fcaf86b58629d782 |