1. 26 Jun, 2002 1 commit
    • stolz's avatar
      [project @ 2002-06-26 08:18:38 by stolz] · fbbed914
      stolz authored
      - Make TSO "stable" again: The thread label was changing the size of the
         TSO if you were building a debugging-RTS, leading to binary
         incompatibility. Now we map TSOs to strings using Hash.c.
      - API change for labelThread: Label arbitrary threads.
  2. 19 Jun, 2002 1 commit
    • sof's avatar
      [project @ 2002-06-19 20:45:14 by sof] · 237ea701
      sof authored
      When handling external call-ins (via the RTS API) in
      the multi-threaded case, add the StgMainThread that
      the external thread is going to block waiting on
      to the main_threads list prior to scheduling the new
      worker thread.
      Do this by having the scheduler provide a new entry
      point, scheduleWaitThread().
      Fixes a bug/race condition spotted by Wolfgang Thaller
      (see scheduleWaitThread() comment) + enables a little
      tidier interface between RtsAPI and Schedule.
  3. 18 May, 2002 1 commit
  4. 11 May, 2002 2 commits
    • sof's avatar
      [project @ 2002-05-11 13:58:18 by sof] · 263ebdd8
      sof authored
      Have createThread() use a separate mutex to ensure unique
      allocation of ThreadIds. A less-than-light solution, but
      cleaner than trying to reuse sched_mutex for this purpose.
    • sof's avatar
      [project @ 2002-05-11 00:16:11 by sof] · 32a27624
      sof authored
      As a result of calling exitScheduler(), enter into a
      'shutting-down' state, so that the subsequent (sequential)
      execution of finalisers won't get stuck inside the
      Scheduler waiting for more work.
      Cleanest way I could think of solving this problem on a
      Friday afternoon.
  5. 26 Apr, 2002 1 commit
    • sof's avatar
      [project @ 2002-04-26 22:35:54 by sof] · 6a268d86
      sof authored
      When the OS thread is all out of work, shut down in a gentler
      manner by calling shutdownHaskell() rather than
      shutdownHaskellAndExit(). Give up the sched_mutex lock also.
  6. 23 Apr, 2002 3 commits
    • sof's avatar
      [project @ 2002-04-23 14:20:18 by sof] · 95c57852
      sof authored
      forkProcess() mingw unused arg tweak
    • stolz's avatar
      [project @ 2002-04-23 09:56:28 by stolz] · 85126d52
      stolz authored
      - set thread labels to NULL after free()
      - labelThread# didn't exit properly
      TODO: Labels are prematurely free()d when a thread terminates. Better let
              the GC worry?
    • sof's avatar
      [project @ 2002-04-23 06:34:26 by sof] · 30a97b4c
      sof authored
      More sched_mutex related cleanup & fixes; little bit
      too delicate for my liking, this.
      * Revert lock assumptions for raiseAsync(); now assumed
        to run with sched_mutex held (as it mucks about with a
      * stodgily release / acquire sched_mutex around calls
        to startSignalHandlers() (as is done in Signals.c)
      * in the presence of user-installed signal handlers, the
        MT-enabled RTS failed to shutdown -- all queues empty
        causes a lone RTS worker thread to pause() waiting for
        signals. This is not the right thing to do; I (temporarily?)
        disabled this signal-wait fallback in MT mode and shut
        down instead. We need to be clearer as to what is a shutdown
        condition in MT mode.
      * The use of sched_mutex to protect next_thread_id increments
        is causing headaches; disabled in non-SMP mode right now until
        I've figured out the pthreads-correct way of doing atomic
      * There's still a ^C-related problem which causes the Haskell
        handler to sometimes induce a SEGV when run. Feel free to debug :)
  7. 13 Apr, 2002 1 commit
    • sof's avatar
      [project @ 2002-04-13 05:33:02 by sof] · 6a00c0fd
      sof authored
      - clarified/fixed sched_mutex locking problems when
        calling raiseAsync() from withing the bowels of the Scheduler.
      - we now yieldToReturningWorker() as part of the main Scheduler
      - simplified grabCapability() and waitForWorkCapability() usage.
  8. 10 Apr, 2002 1 commit
    • stolz's avatar
      [project @ 2002-04-10 11:43:43 by stolz] · c1f3fad1
      stolz authored
      Two new scheduler-API primops:
      1) GHC.Conc.forkProcess/forkProcess# :: IO Int
         This is a low-level call to fork() to replace Posix.forkProcess().
         In a Concurrent Haskell setting, only the thread invoking forkProcess()
         is alive in the child process. Other threads will be GC'ed!
            This brings the RTS closer to pthreads, where a call to fork()
         doesn't clone any pthreads, either.
            The result is 0 for the child and the child's pid for the parent.
         The primop will barf() when used on mingw32, sorry.
      2) GHC.Conc.labelThread/forkProcess# :: String -> IO ()
         Useful for scheduler debugging: If the RTS is compiled with DEBUGging
         support, this primitive assigns a name to the current thread which
         will be used in debugging output (+RTS -D1). For larger applications,
         simply numbering threads is not sufficient.
           Notice: The Haskell side of this call is always available, but if
         you are not compiling with debugging support, the actual primop will
         turn into a no-op.
  9. 01 Apr, 2002 1 commit
  10. 12 Mar, 2002 2 commits
    • simonmar's avatar
      [project @ 2002-03-12 13:57:11 by simonmar] · 5eedab2c
      simonmar authored
      If we are in a deadlock situation but there are signal handlers
      installed, pause() instead of reporting deadlock.  One of the signal
      handlers may allow the process to continue after being triggered.
      Fixes bug #525772.
      I've made a half-hearted attempt to clean up the deadlock code in the
      scheduler, it now looks slightly better.
    • simonmar's avatar
      [project @ 2002-03-12 11:50:02 by simonmar] · f762be1b
      simonmar authored
      Main threads are now not kept alive artificially, so it is possible
      for a main thread to be sent the BlockedOnDeadMVar exception.  Main
      threads are no longer GC roots.
      This involved cleaning up the weak pointer processing somewhat, and
      separating the processing of real weak pointers from the processing of
      the all_threads list (which can be thought of as "weaker pointers": a
      finalizer can keep a blocked thread alive, but not vice-versa).  The
      new story is described in a detailed comment in GC.c.
      One interesting consequence is that it's much harder to get a Deadlock
      exception now - many deadlock situations involving main threads will
      turn into BlockedOnDeadMVar situations instead.  For example, if there
      are a group of threads in a circular deadlock, then they will all be
      sent BlockedOnDeadMVar simultaneously, whereas before if one of them
      was the main thread it would be sent Deadlock.  It's really hard to
      get Deadlock now - you have to somehow keep an MVar independently
      reachable, eg. by using a StablePtr.
  11. 18 Feb, 2002 2 commits
    • sof's avatar
      [project @ 2002-02-18 17:27:24 by sof] · 80f067ce
      sof authored
      unused arg wibble
    • sof's avatar
      [project @ 2002-02-18 13:26:12 by sof] · 6e2ea06c
      sof authored
      Be clear about the lock assumptions of GarbageCollect(); it
      is now required to hold sched_mutex.
      The real reason for adding this requirement is so that when
      prior to scheduling finalizers and doing thread resurrection,
      GarbageCollect() may set the lock status of sched_mutex to
      the state expected by scheduleFinalizers() and resurrectThreads()
      (i.e., unlocked).
      Note: this is only an issue with pthreads. In the Win32 threading
      model, it's a NOP for a thread to grab a mutex it already holds.
  12. 16 Feb, 2002 1 commit
  13. 15 Feb, 2002 6 commits
    • sof's avatar
      [project @ 2002-02-15 22:14:27 by sof] · 9d70000e
      sof authored
      Extra arg to suspendThread() and resumeThread(); controls whether an external call is concurrent or not
    • sof's avatar
      [project @ 2002-02-15 20:58:14 by sof] · b7709803
      sof authored
      suspendThread() comment
    • sof's avatar
      [project @ 2002-02-15 17:49:23 by sof] · 21001dc3
      sof authored
      unbreak prev. commit
    • simonmar's avatar
      [project @ 2002-02-15 14:53:32 by simonmar] · adfe39e8
      simonmar authored
      Ensure that async exceptions are blocked during the raising of an
      async exception - we're about to block them anyway on entry to the
      handler, but we don't want any further exceptions being raised in the
    • simonmar's avatar
      [project @ 2002-02-15 14:49:08 by simonmar] · 93d2b952
      simonmar authored
      Fix bugs in async exception raising: instead of trying to build an
      application of the exception handler to the exception directly, just
      leave a THUNK(raise,exception) on top of the CATCH_FRAME ready to
      trigger the next time this thread is run.
      This avoids two problems: the PAP we were using before wasn't really a
      PAP, which broke some assumptions elsewhere (c.f. PAP_ENTRY:
      CATCH_FRAME failure), and there was also some duplication between
      raiseAsync and raisezh_fast due to the fact that we were attempting to
      do the raising directly.
    • sof's avatar
      [project @ 2002-02-15 07:50:36 by sof] · 6d7576ef
      sof authored
      Tighten up the Scheduler synchronisation story some more:
      - moved thread_ready_cond + the counter rts_n_waiting_tasks
        to Capability.c, leaving only sched_mutex as a synchro
        variable in Scheduler (the less stuff that inhabit
        Schedule.c, the better, methinks.)
      - upon entry to the Scheduler, a worker thread will now call
        Capability.yieldToReturningWorker() to check whether it
        needs to give up its capability.
      - Worker threads that are either idle or lack a capability,
        will now call Capability.waitForWorkCapability() and block.
  14. 14 Feb, 2002 1 commit
    • sof's avatar
      [project @ 2002-02-14 07:52:05 by sof] · efa41d9d
      sof authored
      Restructured / tidied a bit:
      * Capability.grabReturnCapability() is now called by resumeThread().
        It takes care of waiting on the (Capability.c-local) condition
        variable, 'returning_worker_cond' (moved here from Schedule.c)
      * If a worker notices upon entry to the Scheduler that there are
        worker threads waiting to deposit results of external calls,
        it gives up its capability by calling Capability.yieldCapability().
      * Added Scheduler.waitForWork(), which takes care of blocking
        on 'thread_ready_cond' (+ 'rts_n_waiting_tasks' book-keeping).
      Note: changes haven't been fully tested, due to HEAD instability.
  15. 13 Feb, 2002 1 commit
    • sof's avatar
      [project @ 2002-02-13 08:48:06 by sof] · e289780e
      sof authored
      Revised implementation of multi-threaded callouts (and callins):
      - unified synchronisation story for threaded and SMP builds,
        following up on SimonM's suggestion. The following synchro
        variables are now used inside the Scheduler:
          + thread_ready_cond - condition variable that is signalled
            when a H. thread has become runnable (via the THREAD_RUNNABLE()
            macro) and there are available capabilities. Waited on:
               + upon schedule() entry (iff no caps. available).
      	 + when a thread inside of the Scheduler spots that there
      	   are no runnable threads to service, but one or more
      	   external call is in progress.
      	 + in resumeThread(), waiting for a capability to become
            Prior to waiting on thread_ready_cond, a counter rts_n_waiting_tasks
            is incremented, so that we can keep track of the number of
            readily available worker threads (need this in order to make
            an informed decision on whether or not to create a new thread
            when an external call is made).
          + returning_worker_cond - condition variable that is waited
            on by an OS thread that has finished executing and external
            call & now want to feed its result back to the H thread
            that made the call. Before doing so, the counter
            rts_n_returning_workers is incremented.
            Upon entry to the Scheduler, this counter is checked for &
            if it is non-zero, the thread gives up its capability and
            signals returning_worker_cond before trying to re-grab a
            capability. (releaseCapability() takes care of this).
          + sched_mutex - protect Scheduler data structures.
          + gc_pending_cond - SMP-only condition variable for signalling
            completion of GCs.
      - initial implementation of call-ins, i.e., multiple OS threads
        may concurrently call into the RTS without interfering with
        each other. Implementation uses cheesy locking protocol to
        ensure that only one OS thread at a time can construct a
        function application -- stop-gap measure until the RtsAPI
        is revised (as discussed last month) *and* a designated
        block is used for allocating these applications.
      - In the implementation of call-ins, the OS thread blocks
        waiting for an RTS worker thread to complete the evaluation
        of the function application. Since main() also uses the
        RtsAPI, provide a separate entry point for it (rts_mainEvalIO()),
        which avoids creating a separate thread to evaluate Main.main,
        that can be done by the thread exec'ing main() directly.
        [Maybe there's a tidier way of doing this, a bit ugly the
        way it is now..]
      There are a couple of dark corners that needs to be looked at,
      such as conditions for shutting down (and how) + consider what
      ought to happen when async I/O is thrown into the mix (I know
      what will happen, but that's maybe not what we want).
      Other than that, things are in a generally happy state & I hope
      to declare myself done before the week is up.
  16. 12 Feb, 2002 1 commit
    • sof's avatar
      [project @ 2002-02-12 15:38:08 by sof] · a62d5cd2
      sof authored
      Snapshot (before heading into work):
      - thread_ready_aux_mutex is no more; use sched_mutex instead.
      - gc_pending_cond only used in SMP mode.
      - document the condition that thread_ready_cond captures.
  17. 08 Feb, 2002 1 commit
  18. 07 Feb, 2002 1 commit
  19. 06 Feb, 2002 1 commit
    • sof's avatar
      [project @ 2002-02-06 01:29:27 by sof] · 91fd2101
      sof authored
      - use task manager API to keep track of the number
        of tasks that are blocked waiting on the RTS lock.
      - comment updates/additions.
  20. 05 Feb, 2002 1 commit
    • simonmar's avatar
      [project @ 2002-02-05 10:06:24 by simonmar] · 84a29fdd
      simonmar authored
      Fix bad bugs in deleteAllThreds: we were looping through the thread
      queues calling deleteThread() on each thread as we go, but calling
      deleteThread() has the side effect of removing the thread from the
      relevant queue, so we would end up breaking out of the loop after
      processing only a single thread.
      This may fix problems like "resurrectThreads: thread blocked in a
      strange way" seen after pressing ^C.
      Aside: we really shouldn't be using deleteThread() at all, since it
      doesn't give the thread a chance to clean up & release locks.  To be
      well-behaved a program has to catch ^C itself at the moment.
  21. 04 Feb, 2002 2 commits
    • sof's avatar
      [project @ 2002-02-04 20:56:53 by sof] · 632827e0
      sof authored
      resumeThread: ifdef threads-specific code
    • sof's avatar
      [project @ 2002-02-04 20:40:36 by sof] · be72dc05
      sof authored
      Snapshot of 'native thread'-friendly extension:
      - call-outs now work, i.e., a Concurrent Haskell thread which
        makes an external (C) call no longer stop other CH threads
        dead in their tracks. [More testing and tightening up of
        invariants reqd, this is just a snapshot].
      - separated task handling into sep. module.
  22. 31 Jan, 2002 1 commit
    • sof's avatar
      [project @ 2002-01-31 11:18:06 by sof] · 3b9c5eb2
      sof authored
      First steps towards implementing better interop between
      Concurrent Haskell and native threads.
      - factored out Capability handling into a separate source file
        (only the SMP build uses multiple capabilities tho).
      - factored out OS/native threads handling into a separate
        source file, OSThreads.{c,h}. Currently, just a pthreads-based
        implementation; Win32 version to follow.
      - scheduler code now distinguishes between multi-task threaded
        code (SMP) and single-task threaded code ('threaded RTS'),
        but sharing code between these two modes whenever poss.
      i.e., just a first snapshot; the bulk of the transitioning code
      remains to be implemented.
  23. 24 Jan, 2002 2 commits
  24. 22 Jan, 2002 1 commit
    • simonmar's avatar
      [project @ 2002-01-22 13:54:22 by simonmar] · 33a7aa8b
      simonmar authored
      Deadlock is now an exception instead of a return status from
      The current behaviour is as follows, and can be changed if necessary:
      in the event of a deadlock, the top main thread is taken from the main
      thread queue, and if it is blocked on an MVar or an Exception (for
      throwTo), then it receives a Deadlock exception.  If it is blocked on
      a BLACKHOLE, we instead send it the NonTermination exception.  Note
      that only the main thread gets the exception: it is the responsibility
      of the main thread to unblock other threads if necessary.
      There's a slight difference in the SMP build: *all* the main threads
      get an exception, because clearly none of them may make progress
      (compared to the non-SMP situation, where all but the top main thread
      are usually blocked).
  25. 18 Dec, 2001 1 commit
  26. 07 Dec, 2001 1 commit
    • sof's avatar
      [project @ 2001-12-07 20:57:53 by sof] · f9a21ddc
      sof authored
      - tidy up TICK_ALLOC_TSO() uses.
      - scheduleThread: remove special-case for END_TSO_QUEUE. If you want
        to call schedule(), do so directly. (Only one of the scheduleThread()
        call sites depended on this feature).
  27. 26 Nov, 2001 1 commit
    • simonmar's avatar
      [project @ 2001-11-26 16:54:21 by simonmar] · dbef766c
      simonmar authored
      Profiling cleanup.
      This commit eliminates some duplication in the various heap profiling
      subsystems, and generally centralises much of the machinery.  The key
      concept is the separation of a heap *census* (which is now done in one
      place only instead of three) from the calculation of retainer sets.
      Previously the retainer profiling code also did a heap census on the
      fly, and lag-drag-void profiling had its own census machinery.
         - you can now restrict a heap profile to certain retainer sets,
           but still display by cost centre (or type, or closure or
         - I've added an option to restrict the maximum retainer set size
           (+RTS -R<size>, defaulting to 8).
         - I've cleaned up the heap profiling options at the request of
           Simon PJ.  See the help text for details.  The new scheme
           is backwards compatible with the old.
         - I've removed some odd bits of LDV or retainer profiling-specific
           code from various parts of the system.
         - the time taken doing heap censuses (and retainer set calculation)
           is now accurately reported by the RTS when you say +RTS -Sstderr.
      Still to come:
         - restricting a profile to a particular biography
           (lag/drag/void/use).  This requires keeping old heap censuses
           around, but the infrastructure is now in place to do this.
  28. 22 Nov, 2001 1 commit
    • simonmar's avatar
      [project @ 2001-11-22 14:25:11 by simonmar] · db61851c
      simonmar authored
      Retainer Profiling / Lag-drag-void profiling.
      This is mostly work by Sungwoo Park, who spent a summer internship at
      MSR Cambridge this year implementing these two types of heap profiling
      in GHC.
      Relative to Sungwoo's original work, I've made some improvements to
      the code:
         - it's now possible to apply constraints to retainer and LDV profiles
           in the same way as we do for other types of heap profile (eg.
           +RTS -hc{foo,bar} -hR -RTS gives you a retainer profiling considering
           only closures with cost centres 'foo' and 'bar').
         - the heap-profile timer implementation is cleaned up.
         - heap profiling no longer has to be run in a two-space heap.
         - general cleanup of the code and application of the SDM C coding
           style guidelines.
      Profiling will be a little slower and require more space than before,
      mainly because closures have an extra header word to support either
      retainer profiling or LDV profiling (you can't do both at the same
      We've used the new profiling tools on GHC itself, with moderate
      success.  Fixes for some space leaks in GHC to follow...