This project is mirrored from Pull mirroring failed .
Repository mirroring has been paused due to too many failed attempts, and can be resumed by a project maintainer.
Last successful update .
  1. 19 Oct, 2019 6 commits
  2. 18 Oct, 2019 3 commits
    • Ben Gamari's avatar
      Don't cleanup until we've stopped the collector · 47d6b1a2
      Ben Gamari authored
      This requires that we break nonmovingExit into two pieces since we need
      to first stop the collector to relinquish any capabilities, then we need
      to shutdown the scheduler, then we need to free the nonmoving
    • Ben Gamari's avatar
      rts: Implement concurrent collection in the nonmoving collector · d7017446
      Ben Gamari authored
      This extends the non-moving collector to allow concurrent collection.
      The full design of the collector implemented here is described in detail
      in a technical note
          B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell
          Compiler" (2018)
      This extension involves the introduction of a capability-local
      remembered set, known as the /update remembered set/, which tracks
      objects which may no longer be visible to the collector due to mutation.
      To maintain this remembered set we introduce a write barrier on
      mutations which is enabled while a concurrent mark is underway.
      The update remembered set representation is similar to that of the
      nonmoving mark queue, being a chunked array of `MarkEntry`s. Each
      `Capability` maintains a single accumulator chunk, which it flushed
      when it (a) is filled, or (b) when the nonmoving collector enters its
      post-mark synchronization phase.
      While the write barrier touches a significant amount of code it is
      conceptually straightforward: the mutator must ensure that the referee
      of any pointer it overwrites is added to the update remembered set.
      However, there are a few details:
       * In the case of objects with a dirty flag (e.g. `MVar`s) we can
         exploit the fact that only the *first* mutation requires a write
       * Weak references, as usual, complicate things. In particular, we must
         ensure that the referee of a weak object is marked if dereferenced by
         the mutator. For this we (unfortunately) must introduce a read
         barrier, as described in Note [Concurrent read barrier on deRefWeak#]
         (in `NonMovingMark.c`).
       * Stable names are also a bit tricky as described in Note [Sweeping
         stable names in the concurrent collector] (`NonMovingSweep.c`).
      We take quite some pains to ensure that the high thread count often seen
      in parallel Haskell applications doesn't affect pause times. To this end
      we allow thread stacks to be marked either by the thread itself (when it
      is executed or stack-underflows) or the concurrent mark thread (if the
      thread owning the stack is never scheduled). There is a non-trivial
      handshake to ensure that this happens without racing which is described
      in Note [StgStack dirtiness flags and concurrent marking].
      Co-Authored-by: Ömer Sinan Ağacan's avatarÖmer Sinan Ağacan <>
    • Ben Gamari's avatar
      rts/Schedule: Allow synchronization without holding a capability · bfcafd39
      Ben Gamari authored
      The concurrent mark-and-sweep will be performed by a GHC task which will
      not hold a capability. This is necessary to avoid a concurrent mark from
      interfering with minor generation collections.
      However, the major collector must synchronize with the mutators at the
      end of marking to flush their update remembered sets. This patch extends
      the `requestSync` mechanism used to synchronize garbage collectors to
      allow synchronization without holding a capability.
      This change is fairly straightforward as the capability was previously
      only required for two reasons:
       1. to ensure that we don't try to re-acquire a capability that we
          the sync requestor already holds.
       2. to provide a way to suspend and later resume the sync request if
          there is already a sync pending.
      When synchronizing without holding a capability we needn't worry about
      consideration (1) at all.
      (2) is slightly trickier and may happen, for instance, when a capability
      requests a minor collection and shortly thereafter the non-moving mark
      thread requests a post-mark synchronization. In this case we need to
      ensure that the non-moving mark thread suspends his request until after
      the minor GC has concluded to avoid dead-locking. For this we introduce
      a condition variable, `sync_finished_cond`, which a
      non-capability-bearing requestor will wait on and which is signalled
      after a synchronization or GC has finished.
  3. 15 Mar, 2019 1 commit
  4. 12 Jan, 2019 1 commit
    • Ömer Sinan Ağacan's avatar
      Fix negative mutator time in GC stats in prof builds · 19670bc3
      Ömer Sinan Ağacan authored
      Because garbage collector calls `retainerProfile()` and `heapCensus()`,
      GC times normally include some of PROF times too. To fix this we have
      these lines:
          // heapCensus() is called by the GC, so RP and HC time are
          // included in the GC stats.  We therefore subtract them to
          // obtain the actual GC cpu time.
          stats.gc_cpu_ns      -=  prof_cpu;
          stats.gc_elapsed_ns  -=  prof_elapsed;
      These variables are later used for calculating GC time excluding the
      final GC (which should be attributed to EXIT).
          exit_gc_elapsed      = stats.gc_elapsed_ns - start_exit_gc_elapsed;
      The problem is if we subtract PROF times from `gc_elapsed_ns` and then
      subtract `start_exit_gc_elapsed` from the result, we end up subtracting
      PROF times twice, because `start_exit_gc_elapsed` also includes PROF
      We now subtract PROF times from GC after the calculations for EXIT and
      MUT times. The existing assertion that checks
          INIT + MUT + GC + EXIT = TOTAL
      now holds. When we subtract PROF numbers from GC, and a new assertion
          INIT + MUT + GC + PROF + EXIT = TOTAL
      also holds.
      Fixes #15897. New assertions added in this commit also revealed #16102,
      which is also fixed by this commit.
  5. 19 Nov, 2018 2 commits
  6. 17 Nov, 2018 1 commit
  7. 29 Aug, 2018 1 commit
    • David Feuer's avatar
      Finish stable split · f48e276a
      David Feuer authored
      Long ago, the stable name table and stable pointer tables were one.
      Now, they are separate, and have significantly different
      implementations. I believe the time has come to finish the split
      that began in #7674.
      * Divide `rts/Stable` into `rts/StableName` and `rts/StablePtr`.
      * Give each table its own mutex.
      * Add FFI functions `hs_lock_stable_ptr_table` and
      `hs_unlock_stable_ptr_table` and document them.
        These are intended to replace the previously undocumented
      `hs_lock_stable_tables` and `hs_lock_stable_tables`,
        which are now documented as deprecated synonyms.
      * Make `eqStableName#` use pointer equality instead of unnecessarily
      comparing stable name table indices.
      Reviewers: simonmar, bgamari, erikd
      Reviewed By: bgamari
      Subscribers: rwbarton, carter
      GHC Trac Issues: #15555
      Differential Revision:
  8. 12 Jun, 2018 1 commit
  9. 11 Apr, 2018 2 commits
  10. 10 Apr, 2018 1 commit
  11. 25 Mar, 2018 1 commit
    • Simon Marlow's avatar
      Run C finalizers incrementally during mutation · f7bbc343
      Simon Marlow authored
      With a large heap it's possible to build up a lot of finalizers
      between GCs.  We've observed GC spending up to 50% of its time running
      finalizers.  But there's no reason we have to run finalizers during
      GC, and especially no reason we have to block *all* the mutator
      threads while *one* GC thread runs finalizers one by one.
      I thought about a bunch of alternative ways to handle this, which are
      documented along with runSomeFinalizers() in Weak.c.  The approach I
      settled on is to have a capability run finalizers if it is idle.  So
      running finalizers is like a low-priority background thread. This
      requires some minor scheduler changes, but not much.  In the future we
      might be able to move more GC work into here (I have my eye on freeing
      large blocks, for example).
      Test Plan:
      * validate
      * tested on our system and saw reductions in GC pauses of 40-50%.
      Reviewers: bgamari, niteria, osa1, erikd
      Reviewed By: bgamari, osa1
      Subscribers: rwbarton, thomie, carter
      Differential Revision:
  12. 07 Mar, 2018 1 commit
  13. 06 Mar, 2018 1 commit
  14. 02 Mar, 2018 2 commits
  15. 06 Feb, 2018 2 commits
  16. 18 Jul, 2017 1 commit
    • Simon Marlow's avatar
      Fix a missing getNewNursery(), and related cleanup · 12ae1fa5
      Simon Marlow authored
      When we use nursery chunks with +RTS -n<size>, when the current nursery
      runs out we have to check whether there's another chunk available with
      getNewNursery().  There was one place we weren't doing this: the ad-hoc
      heap check in scheduleProcessInbox().
      The impact of the bug was that we would GC too early when using nursery
      chunks, especially in programs that used messages (throwTo between
      capabilities could do this, also hs_try_putmvar()).
      Test Plan: validate, also local testing in our application
      Reviewers: bgamari, niteria, austin, erikd
      Subscribers: rwbarton, thomie
      Differential Revision:
  17. 18 Jun, 2017 1 commit
  18. 08 Jun, 2017 1 commit
    • Simon Marlow's avatar
      Fix a lost-wakeup bug in BLACKHOLE handling (#13751) · 59847290
      Simon Marlow authored
      The problem occurred when
      * Threads A & B evaluate the same thunk
      * Thread A context-switches, so the thunk gets blackholed
      * Thread C enters the blackhole, creates a BLOCKING_QUEUE attached to
        the blackhole and thread A's `tso->bq` queue
      * Thread B updates the blackhole with a value, overwriting the BLOCKING_QUEUE
      * We GC, replacing A's update frame with stg_enter_checkbh
      * Throw an exception in A, which ignores the stg_enter_checkbh frame
      Now we have C blocked on A's tso->bq queue, but we forgot to check the
      queue because the stg_enter_checkbh frame has been thrown away by the
      The solution and alternative designs are discussed in Note [upd-black-hole].
      This also exposed a bug in the interpreter, whereby we were sometimes
      context-switching without calling `threadPaused()`.  I've fixed this
      and added some Notes.
      Test Plan:
      * `cd testsuite/tests/concurrent && make slow`
      * validate
      Reviewers: niteria, bgamari, austin, erikd
      Reviewed By: erikd
      Subscribers: rwbarton, thomie
      GHC Trac Issues: #13751
      Differential Revision:
  19. 10 May, 2017 1 commit
  20. 29 Apr, 2017 2 commits
  21. 05 Apr, 2017 1 commit
  22. 04 Apr, 2017 1 commit
  23. 01 Apr, 2017 1 commit
  24. 04 Feb, 2017 1 commit
    • Takenobu Tani's avatar
      Fix comment (old file names) in rts/ · 31bb85ff
      Takenobu Tani authored
      [skip ci]
      There ware some old file names (.lhs, ...) at comments.
      * rts/win32/ThrIOManager.c
        - Conc.lhs -> Conc.hs
      * rts/PrimOps.cmm
        - ByteCodeLink.lhs -> ByteCodeLink.hs
        - StgMiscClosures.hc -> StgMiscClosures.cmm
      * rts/AutoApply.h
        - AutoApply.hc -> AutoApply.cmm
      * rts/HeapStackCheck.cmm
        - PrimOps.hc -> PrimOps.cmm
      * rts/LdvProfile.h
        - Updates.hc -> Updates.cmm
      * rts/Schedule.c
        - StgStartup.hc -> StgStartup.cmm
      * rts/Weak.c
        - StgMiscClosures.hc -> StgMiscClosures.cmm
      Reviewers: bgamari, austin, erikd, simonmar
      Subscribers: thomie
      Differential Revision:
  25. 10 Jan, 2017 1 commit
  26. 02 Dec, 2016 1 commit
    • Alexander Vershilov's avatar
      Install toplevel handler inside fork. · 895a131f
      Alexander Vershilov authored
      When rts is forked it doesn't update toplevel handler, so UserInterrupt
      exception is sent to Thread1 that doesn't exist in forked process.
      We install toplevel handler when fork so signal will be delivered to the
      new main thread.
      Fixes #12903
      Reviewers: simonmar, austin, erikd, bgamari
      Reviewed By: bgamari
      Subscribers: thomie
      Differential Revision:
      GHC Trac Issues: #12903
  27. 29 Nov, 2016 1 commit
  28. 18 Nov, 2016 1 commit