[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: Handle heap allocation failure in I/O primops
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1ae08ce7 by Duncan Coutts at 2025-09-12T00:11:34-04:00 Handle heap allocation failure in I/O primops The current I/O managers do not use allocateMightFail, but future ones will. To support this properly we need to be able to return to the primop with a failure. We simply use a bool return value. Currently however, we will just throw an exception rather than calling the GC because that's what all the other primops do too. For the general issue of primops invoking GC and retrying, see https://gitlab.haskell.org/ghc/ghc/-/issues/24105 - - - - - c3b7a003 by Duncan Coutts at 2025-09-12T00:11:34-04:00 Move (and rename) scheduleStartSignalHandlers into RtsSignals.h Previously it was a local helper (static) function in Schedule.c. Rename it to startPendingSignalHandlers and deifine it as an inline header function in RtsSignals.h. So it should still be fast. Each (new style) I/O manager is going to need to do the same, so eliminating the duplication now makes sense. - - - - - d1764f11 by Duncan Coutts at 2025-09-12T00:11:34-04:00 Reduce detail in printThreadBlockage I/O blocking cases The printThreadBlockage is used in debug tracing output. For the cases BlockedOn{Read,Write,Delay} the output previously included the fd that was being waited on, and the delay target wake time. Superficially this sounds useful, but it's clearly not that useful because it was already wrong for the Win32 non-threaded I/O manager. In that situation it will print garbage (the async_result pointer, cast to a fd or a time). So given that it apparently never mattered that the information was accurate, then it's hardly a big jump to say it doesn't matter if it is present at all. A good reason to remove it is that otherwise we have to make a new API and a per-I/O manager implementation to fetch the information. And for some I/O manager implementations, this information is not available. It is not available in the win32 non-threaded I/O manager. And for some future Linux ones, there is no need for the fd to be stored, so storing it would be just extra space used for very little gain. So the simplest thing is to just remove the detail. - - - - - 03774c0a by Duncan Coutts at 2025-09-12T00:11:35-04:00 Add TimeoutQueue.{c,h} and corresponding tests A data structure used to efficiently manage a collection of timeouts. It is a priority queue based on absolute expiry time. It uses 64bit high-precision Time for the keys. The values are normal closures which allows for example using MVars for unblocking. It is common in many applications for timeouts to be created and then deleted or altered before they expire. Thus the choice of data structure for timeouts should support this efficiently. The implementation choice here is a leftist heap with the extra feature that it supports deleting arbitrary elements, provided the caller retain a pointer to the element. While the deleteMin operation takes O(log n) time, as in all heap structures, the delete operation for arbitrary elements /typically/ takes O(1), and only O(log n) in the worst case. In practice, when managing thousands of timeouts it can be a factor of 10 faster to delete a random timeout queue element than to remove the minimum element. This supports the common use case. The plan is to use it in some of the RTS-side I/O managers to support their timer functionality. In this use case the heap value will be an MVar used for each timeout to unblock waiting threads. - - - - - d4258a8a by Duncan Coutts at 2025-09-12T00:11:35-04:00 Add ClosureTable.{c,h} and corresponding tests A table of pointers to closures on the GC heap with stable indexes. It provides O(1) alloc, free and lookup. The table can be expanded using a simple doubling strategy: in which case allocation is typically O(1) and occasionally O(n) for overall amortised O(1). No shrinking is used. The table itself is heap allocated, and points to other heap objects. As such it's necessary to use markClosureTable to ensure the table is used as a GC root to keep the table entries alive, and maintain proper pointers to them as the GC moves heap objects about. It is designed to be allocated and accesses exclusively from a single capability, enabling it to work without any locking. It is thus similar to the StablePtr table, but per-capability which removes the need for locking. It _should_ also provide lower GC pause times with the non-moving GC by spending only O(1) time in markClosureTable, vs O(n) for markStablePtrTable. The plan is to use it in some of the I/O managers to keep track of in-flight I/O operations (but not timers). This allows the tracking info to be kept on the (unpinned) GC heap, and shared with Haskell code, and by putting a pointer to the tracking information in a table, the index remains stable and can be passed via foreign code (like the kernel). - - - - - 21069694 by Duncan Coutts at 2025-09-12T00:11:35-04:00 Add the StgAsyncIOOp closure type This is intended to be used by multiple I/O managers to help with tracking in-flight I/O operations. It is called asynchronous because from the point of view of the RTS we have many such operations in progress at once. From the point of view of a Haskell thread of course it can look synchronous. - - - - - dbb9bd9f by Duncan Coutts at 2025-09-12T00:11:35-04:00 Add StgAsyncIOOp and StgTimeoutQueue to tso->block_info These will be used by new I/O managers, for threads blocked on I/O or timeouts. - - - - - 0a1fccc0 by Duncan Coutts at 2025-09-12T00:11:35-04:00 Add a new I/O manager based on poll() This is a proof of concept I/O manager, to show how to add new ones neatly, using the ClosureTable and TimeoutQueue infrastructure. It uses the old unix poll() API, so it is of course limited in performance by that, but it should have the benefit of wide compatibility. Also we neatly avoid a name clash with the existing select() I/O manager. Compared to the select() I/O manager: 1. beause it uses poll() it is not limited to 1024 file descriptors (but it's still O(n) so don't expect great performance); 2. it should have much faster threadDelay (when using it in lots of threads at once) because it's based on the new TimeoutQueue which is O(log n) rather than O(n). Some of the code related to timers/timouts is put into a shared module rts/posix/Timeout.{h,c} since it is intended to be shared with other similar I/O managers. - - - - - 8acc1c76 by Duncan Coutts at 2025-09-12T00:11:35-04:00 Document the I/O managers in the user guide and note the new poll I/O manager in the release notes. - - - - - b702ea57 by Duncan Coutts at 2025-09-12T00:11:35-04:00 Use the poll() I/O manager by default That is, for the non-threaded RTS, prefer the poll I/O manager over the legacy select() one, if both can be enabled. This patch is primarily for CI testing, so we should probably remove this patch before merging. We can change defaults later after wider testing and feedback. - - - - - 7f3be388 by Simon Peyton Jones at 2025-09-12T00:11:39-04:00 Solve forall-constraints via an implication, again In this earlier commit: commit 953fd8f1dc080f1c56e3a60b4b7157456949be29 Author: Simon Peyton Jones <simon.peytonjones@gmail.com> Date: Mon Jul 21 10:06:43 2025 +0100 Solve forall-constraints immediately, or not at all I used a all-or-nothing strategy for quantified constraints (aka forall-constraints). But alas that fell foul of #26315, and #26376. So this MR goes back to solving a quantified constraint by turning it into an implication; UNLESS we are simplifying constraints from a SPECIALISE pragma, in which case the all-or-nothing strategy is great. See: Note [Solving a Wanted forall-constraint] Other stuff in this MR: * TcSMode becomes a record of flags, rather than an enumeration type; much nicer. * Some fancy footwork to avoid error messages worsening again (The above MR made them better; we want to retain that.) See `GHC.Tc.Errors.Ppr.pprQCOriginExtra`. - - - - - 073b8379 by Simon Peyton Jones at 2025-09-12T00:11:39-04:00 Add a test case for #26396 ...same bug ast #26315 - - - - - 80 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Deriv/Utils.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Solver/Solve.hs-boot - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Zonk/TcType.hs - compiler/GHC/Tc/Zonk/Type.hs - docs/users_guide/9.16.1-notes.rst - docs/users_guide/runtime_control.rst - libraries/base/src/GHC/RTS/Flags.hs - libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc - + rts/ClosureTable.c - + rts/ClosureTable.h - rts/IOManager.c - rts/IOManager.h - rts/IOManagerInternals.h - rts/PrimOps.cmm - rts/RtsSignals.h - rts/Schedule.c - rts/StgMiscClosures.cmm - rts/Threads.c - + rts/TimeoutQueue.c - + rts/TimeoutQueue.h - rts/configure.ac - rts/include/rts/Constants.h - rts/include/rts/Flags.h - rts/include/rts/storage/Closures.h - rts/include/rts/storage/TSO.h - rts/include/stg/MiscClosures.h - + rts/posix/Poll.c - + rts/posix/Poll.h - + rts/posix/Timeout.c - + rts/posix/Timeout.h - rts/rts.cabal - testsuite/tests/backpack/should_fail/bkpfail11.stderr - testsuite/tests/backpack/should_fail/bkpfail43.stderr - + testsuite/tests/deriving/should_compile/T26396.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/deriving/should_fail/T12768.stderr - testsuite/tests/deriving/should_fail/T1496.stderr - testsuite/tests/deriving/should_fail/T21302.stderr - testsuite/tests/deriving/should_fail/T22696b.stderr - testsuite/tests/deriving/should_fail/T5498.stderr - testsuite/tests/deriving/should_fail/T7148.stderr - testsuite/tests/deriving/should_fail/T7148a.stderr - testsuite/tests/impredicative/T17332.stderr - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/quantified-constraints/T19690.stderr - testsuite/tests/quantified-constraints/T19921.stderr - testsuite/tests/quantified-constraints/T21006.stderr - testsuite/tests/roles/should_fail/RolesIArray.stderr - + testsuite/tests/rts/ClosureTable.hs - + testsuite/tests/rts/ClosureTable_c.c - + testsuite/tests/rts/TimeoutQueue.c - + testsuite/tests/rts/TimeoutQueue.stdout - testsuite/tests/rts/all.T - testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/DsSpecPragmas.stderr - testsuite/tests/typecheck/should_compile/T14434.hs - + testsuite/tests/typecheck/should_compile/T26376.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/T15801.stderr - testsuite/tests/typecheck/should_fail/T19627.stderr - testsuite/tests/typecheck/should_fail/T20666.stderr - testsuite/tests/typecheck/should_fail/T20666a.stderr - testsuite/tests/typecheck/should_fail/T20666b.stderr - testsuite/tests/typecheck/should_fail/T22912.stderr - testsuite/tests/typecheck/should_fail/T23427.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c99345fc40dce87c59c6532458740c... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c99345fc40dce87c59c6532458740c... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Marge Bot (@marge-bot)