Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Implement MVar. #25

Open
master-q opened this Issue Jun 19, 2013 · 2 comments

Comments

Projects
None yet
2 participants
Owner

master-q commented Jun 19, 2013

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.
 *
 * -------------------------------------------------------------------------- */

stg_isEmptyMVarzh
{
    /* args: R1 = MVar closure */

    if (StgMVar_value(R1) == stg_END_TSO_QUEUE_closure) {
    RET_N(1);
    } else {
    RET_N(0);
    }
}

stg_newMVarzh
{
    /* args: none */
    W_ mvar;

    ALLOC_PRIM ( SIZEOF_StgMVar, NO_PTRS, stg_newMVarzh );

    mvar = Hp - SIZEOF_StgMVar + WDS(1);
    SET_HDR(mvar,stg_MVAR_DIRTY_info,CCCS);
        // 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;
    RET_P(mvar);
}
......
Owner

master-q commented Jul 3, 2013

I think DGC has hint about Ajhc's MVar.

A Survey of Distributed Garbage Collection Techniques (1995)
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.6060

@ghost ghost assigned dec9ue Jul 3, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment