Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Implement MVar. #25

master-q opened this Issue · 2 comments

2 participants


GHC's MVar is implemented at ghc/libraries/base/GHC/MVar.hs and ghc/rts/PrimOps.cmm.

// File: ghc/rts/PrimOps.cmm
/* -----------------------------------------------------------------------------
 * MVar primitives
 * take & putMVar work as follows.  Firstly, an important invariant:
 *    If the MVar is full, then the blocking queue contains only
 *    threads blocked on putMVar, and if the MVar is empty then the
 *    blocking queue contains only threads blocked on takeMVar.
 * takeMvar:
 *    MVar empty : then add ourselves to the blocking queue
 *    MVar full  : remove the value from the MVar, and
 *                 blocking queue empty     : return
 *                 blocking queue non-empty : perform the first blocked putMVar
 *                                            from the queue, and wake up the
 *                                            thread (MVar is now full again)
 * putMVar is just the dual of the above algorithm.
 * How do we "perform a putMVar"?  Well, we have to fiddle around with
 * the stack of the thread waiting to do the putMVar.  See
 * stg_block_putmvar and stg_block_takemvar in HeapStackCheck.c for
 * the stack layout, and the PerformPut and PerformTake macros below.
 * It is important that a blocked take or put is woken up with the
 * take/put already performed, because otherwise there would be a
 * small window of vulnerability where the thread could receive an
 * exception and never perform its take or put, and we'd end up with a
 * deadlock.
 * -------------------------------------------------------------------------- */

    /* args: R1 = MVar closure */

    if (StgMVar_value(R1) == stg_END_TSO_QUEUE_closure) {
    } else {

    /* args: none */
    W_ mvar;

    ALLOC_PRIM ( SIZEOF_StgMVar, NO_PTRS, stg_newMVarzh );

    mvar = Hp - SIZEOF_StgMVar + WDS(1);
        // MVARs start dirty: generation 0 has no mutable list
    StgMVar_head(mvar)  = stg_END_TSO_QUEUE_closure;
    StgMVar_tail(mvar)  = stg_END_TSO_QUEUE_closure;
    StgMVar_value(mvar) = stg_END_TSO_QUEUE_closure;

I think DGC has hint about Ajhc's MVar.

A Survey of Distributed Garbage Collection Techniques (1995)

@dec9ue dec9ue was assigned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.