Ticket #4001: 0001-atomicReadMVar.2.patch

File 0001-atomicReadMVar.2.patch, 21.0 KB (added by ezyang, 10 months ago)

Patch

  • compiler/prelude/primops.txt.pp

    From 658362e2f3a94ebf1eab6ebe77e873c9389523a0 Mon Sep 17 00:00:00 2001
    From: "Edward Z. Yang" <ezyang@mit.edu>
    Date: Fri, 14 Jun 2013 14:19:42 -0700
    Subject: [PATCH] atomicReadMVar
    
    Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
    ---
     compiler/prelude/primops.txt.pp          |    9 +++
     includes/rts/Constants.h                 |   25 ++++----
     includes/rts/storage/Closures.h          |    1 +
     includes/stg/MiscClosures.h              |    3 +
     rts/HeapStackCheck.cmm                   |   33 ++++++++++
     rts/Linker.c                             |    2 +
     rts/PrimOps.cmm                          |   96 ++++++++++++++++++++++++++++--
     rts/RaiseAsync.c                         |   28 ++++++++-
     rts/RaiseAsync.h                         |    1 +
     rts/RetainerProfile.c                    |    1 +
     rts/Schedule.c                           |    2 +
     rts/StgMiscClosures.cmm                  |    4 +-
     rts/Threads.c                            |    4 ++
     rts/Trace.c                              |    1 +
     rts/sm/Compact.c                         |    1 +
     rts/sm/Sanity.c                          |    1 +
     rts/sm/Scav.c                            |    1 +
     utils/deriveConstants/DeriveConstants.hs |    1 +
     18 files changed, 192 insertions(+), 22 deletions(-)
    
    diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
    index 4547281..1e7da58 100644
    a b primop TryPutMVarOp "tryPutMVar#" GenPrimOp 
    17171717   out_of_line      = True 
    17181718   has_side_effects = True 
    17191719 
     1720primop  AtomicReadMVarOp "atomicReadMVar#" GenPrimOp 
     1721   MVar# s a -> State# s -> (# State# s, a #) 
     1722   {If {\tt MVar\#} is empty, block until it becomes full. 
     1723   Then read its contents without modifying the MVar, without possibility 
     1724   of intervention from other threads.} 
     1725   with 
     1726   out_of_line      = True 
     1727   has_side_effects = True 
     1728 
    17201729primop  SameMVarOp "sameMVar#" GenPrimOp 
    17211730   MVar# s a -> MVar# s a -> Bool 
    17221731 
  • includes/rts/Constants.h

    diff --git a/includes/rts/Constants.h b/includes/rts/Constants.h
    index 5ff4d4e..4739e3a 100644
    a b  
    202202 */ 
    203203#define NotBlocked          0 
    204204#define BlockedOnMVar       1 
    205 #define BlockedOnBlackHole  2 
    206 #define BlockedOnRead       3 
    207 #define BlockedOnWrite      4 
    208 #define BlockedOnDelay      5 
    209 #define BlockedOnSTM        6 
     205#define BlockedOnMVarRead   2 
     206#define BlockedOnBlackHole  3 
     207#define BlockedOnRead       4 
     208#define BlockedOnWrite      5 
     209#define BlockedOnDelay      6 
     210#define BlockedOnSTM        7 
    210211 
    211212/* Win32 only: */ 
    212 #define BlockedOnDoProc     7 
     213#define BlockedOnDoProc     8 
    213214 
    214215/* Only relevant for PAR: */ 
    215216  /* blocked on a remote closure represented by a Global Address: */ 
    216 #define BlockedOnGA         8 
     217#define BlockedOnGA         9 
    217218  /* same as above but without sending a Fetch message */ 
    218 #define BlockedOnGA_NoSend  9 
     219#define BlockedOnGA_NoSend  10 
    219220/* Only relevant for THREADED_RTS: */ 
    220 #define BlockedOnCCall      10 
    221 #define BlockedOnCCall_Interruptible 11 
     221#define BlockedOnCCall      11 
     222#define BlockedOnCCall_Interruptible 12 
    222223   /* same as above but permit killing the worker thread */ 
    223224 
    224225/* Involved in a message sent to tso->msg_cap */ 
    225 #define BlockedOnMsgThrowTo 12 
     226#define BlockedOnMsgThrowTo 13 
    226227 
    227228/* The thread is not on any run queues, but can be woken up 
    228229   by tryWakeupThread() */ 
    229 #define ThreadMigrating     13 
     230#define ThreadMigrating     14 
    230231 
    231232/* 
    232233 * These constants are returned to the scheduler by a thread that has 
  • includes/rts/storage/Closures.h

    diff --git a/includes/rts/storage/Closures.h b/includes/rts/storage/Closures.h
    index 1eef182..b494112 100644
    a b typedef struct { 
    266266    StgHeader                header; 
    267267    struct StgMVarTSOQueue_ *head; 
    268268    struct StgMVarTSOQueue_ *tail; 
     269    struct StgMVarTSOQueue_ *readers; 
    269270    StgClosure*              value; 
    270271} StgMVar; 
    271272 
  • includes/stg/MiscClosures.h

    diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h
    index b9b4f23..037508b 100644
    a b RTS_FUN_DECL(stg_block_noregs); 
    292292RTS_FUN_DECL(stg_block_blackhole); 
    293293RTS_FUN_DECL(stg_block_blackhole_finally); 
    294294RTS_FUN_DECL(stg_block_takemvar); 
     295RTS_FUN_DECL(stg_block_atomicreadmvar); 
    295296RTS_RET(stg_block_takemvar); 
     297RTS_RET(stg_block_atomicreadmvar); 
    296298RTS_FUN_DECL(stg_block_putmvar); 
    297299RTS_RET(stg_block_putmvar); 
    298300#ifdef mingw32_HOST_OS 
    RTS_FUN_DECL(stg_isEmptyMVarzh); 
    375377RTS_FUN_DECL(stg_newMVarzh); 
    376378RTS_FUN_DECL(stg_takeMVarzh); 
    377379RTS_FUN_DECL(stg_putMVarzh); 
     380RTS_FUN_DECL(stg_atomicReadMVarzh); 
    378381RTS_FUN_DECL(stg_tryTakeMVarzh); 
    379382RTS_FUN_DECL(stg_tryPutMVarzh); 
    380383 
  • rts/HeapStackCheck.cmm

    diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
    index fbceb76..9950810 100644
    a b stg_block_noregs 
    493493 *       ptr to MVar   (R1) 
    494494 *       stg_block_takemvar_info 
    495495 * 
     496 * Stack layout for a thread blocked in atomicReadMVar: 
     497 * 
     498 *       ret. addr 
     499 *       ptr to MVar   (R1) 
     500 *       stg_block_readmvar_info 
     501 * 
    496502 * Stack layout for a thread blocked in putMVar: 
    497503 *       
    498504 *       ret. addr 
    stg_block_takemvar /* mvar passed in R1 */ 
    531537    BLOCK_BUT_FIRST(stg_block_takemvar_finally); 
    532538} 
    533539 
     540INFO_TABLE_RET ( stg_block_atomicreadmvar, RET_SMALL, W_ info_ptr, P_ mvar ) 
     541    return () 
     542{ 
     543    jump stg_atomicReadMVarzh(mvar); 
     544} 
     545 
     546// code fragment executed just before we return to the scheduler 
     547stg_block_atomicreadmvar_finally 
     548{ 
     549    W_ r1, r3; 
     550    r1 = R1; 
     551    r3 = R3; 
     552    unlockClosure(R3, stg_MVAR_DIRTY_info); 
     553    R1 = r1; 
     554    R3 = r3; 
     555    jump StgReturn [R1]; 
     556} 
     557 
     558stg_block_atomicreadmvar /* mvar passed in R1 */ 
     559{ 
     560    Sp_adj(-2); 
     561    Sp(1) = R1; 
     562    Sp(0) = stg_block_atomicreadmvar_info; 
     563    R3 = R1; // mvar communicated to stg_block_atomicreadmvar_finally in R3 
     564    BLOCK_BUT_FIRST(stg_block_atomicreadmvar_finally); 
     565} 
     566 
    534567INFO_TABLE_RET( stg_block_putmvar, RET_SMALL, W_ info_ptr, 
    535568                P_ mvar, P_ val ) 
    536569    return () 
  • rts/Linker.c

    diff --git a/rts/Linker.c b/rts/Linker.c
    index 47eb6b0..20978af 100644
    a b typedef struct _RtsSymbolVal { 
    10581058      SymI_HasProto(stg_yield_to_interpreter)                           \ 
    10591059      SymI_HasProto(stg_block_noregs)                                   \ 
    10601060      SymI_HasProto(stg_block_takemvar)                                 \ 
     1061      SymI_HasProto(stg_block_atomicreadmvar)                           \ 
    10611062      SymI_HasProto(stg_block_putmvar)                                  \ 
    10621063      MAIN_CAP_SYM                                                      \ 
    10631064      SymI_HasProto(MallocFailHook)                                     \ 
    typedef struct _RtsSymbolVal { 
    13141315      SymI_HasProto(stg_bh_upd_frame_info)                              \ 
    13151316      SymI_HasProto(suspendThread)                                      \ 
    13161317      SymI_HasProto(stg_takeMVarzh)                                     \ 
     1318      SymI_HasProto(stg_atomicReadMVarzh)                               \ 
    13171319      SymI_HasProto(stg_threadStatuszh)                                 \ 
    13181320      SymI_HasProto(stg_tryPutMVarzh)                                   \ 
    13191321      SymI_HasProto(stg_tryTakeMVarzh)                                  \ 
  • rts/PrimOps.cmm

    diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
    index 230b929..9be9114 100644
    a b stg_newMVarzh () 
    11701170    StgMVar_head(mvar)  = stg_END_TSO_QUEUE_closure; 
    11711171    StgMVar_tail(mvar)  = stg_END_TSO_QUEUE_closure; 
    11721172    StgMVar_value(mvar) = stg_END_TSO_QUEUE_closure; 
     1173    StgMVar_readers(mvar) = stg_END_TSO_QUEUE_closure; 
    11731174    return (mvar); 
    11741175} 
    11751176 
    1176  
    11771177#define PerformTake(stack, value)               \ 
    11781178    W_ sp;                                      \ 
    11791179    sp = StgStack_sp(stack);                    \ 
    stg_newMVarzh () 
    11861186    StgStack_sp(stack) = sp;                    \ 
    11871187    lval = W_[sp - WDS(1)]; 
    11881188 
    1189  
    11901189stg_takeMVarzh ( P_ mvar /* :: MVar a */ ) 
    11911190{ 
    11921191    W_ val, info, tso, q; 
    loop: 
    13481347    return (1,val); 
    13491348} 
    13501349 
     1350#define WakeupReaders(mvar, val)                                \ 
     1351    W_ q, tso, stack;                                           \ 
     1352    q = StgMVar_readers(mvar);                                  \ 
     1353rloop:                                                          \ 
     1354    if (q == stg_END_TSO_QUEUE_closure) {                       \ 
     1355        StgMVar_readers(mvar) = stg_END_TSO_QUEUE_closure;      \ 
     1356        goto rdone;                                             \ 
     1357    }                                                           \ 
     1358    if (StgHeader_info(q) == stg_IND_info) {                    \ 
     1359        q = StgInd_indirectee(q);                               \ 
     1360        goto rloop;                                             \ 
     1361    }                                                           \ 
     1362    tso = StgMVarTSOQueue_tso(q);                               \ 
     1363                                                                \ 
     1364    ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVarRead::I16);  \ 
     1365    ASSERT(StgTSO_block_info(tso) == mvar);                     \ 
     1366                                                                \ 
     1367    stack = StgTSO_stackobj(tso);                               \ 
     1368    PerformTake(stack, val);                                    \ 
     1369    StgTSO__link(tso) = stg_END_TSO_QUEUE_closure;              \ 
     1370    if (TO_W_(StgStack_dirty(stack)) == 0) {                    \ 
     1371        ccall dirty_STACK(MyCapability() "ptr", stack "ptr");   \ 
     1372    }                                                           \ 
     1373                                                                \ 
     1374    ccall tryWakeupThread(MyCapability() "ptr", tso);           \ 
     1375                                                                \ 
     1376    q = StgMVarTSOQueue_link(q);                                \ 
     1377    goto rloop;                                                 \ 
     1378rdone: 
     1379 
    13511380stg_putMVarzh ( P_ mvar, /* :: MVar a */ 
    13521381                P_ val,  /* :: a */ ) 
    13531382{ 
    1354     W_ info, tso, q; 
     1383    W_ info, q; 
     1384    W_ stack; 
    13551385 
    13561386#if defined(THREADED_RTS) 
    13571387    ("ptr" info) = ccall lockClosure(mvar "ptr"); 
    stg_putMVarzh ( P_ mvar, /* :: MVar a */ 
    13941424        jump stg_block_putmvar(mvar,val); 
    13951425    } 
    13961426 
     1427    WakeupReaders(mvar, val); 
     1428 
    13971429    q = StgMVar_head(mvar); 
    13981430loop: 
    13991431    if (q == stg_END_TSO_QUEUE_closure) { 
    loop: 
    14101442 
    14111443    // There are takeMVar(s) waiting: wake up the first one 
    14121444 
     1445    W_ tso; 
    14131446    tso = StgMVarTSOQueue_tso(q); 
    14141447    StgMVar_head(mvar) = StgMVarTSOQueue_link(q); 
    14151448    if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { 
    loop: 
    14201453    ASSERT(StgTSO_block_info(tso) == mvar); 
    14211454 
    14221455    // actually perform the takeMVar 
    1423     W_ stack; 
    14241456    stack = StgTSO_stackobj(tso); 
    14251457    PerformTake(stack, val); 
    14261458 
    loop: 
    14411473stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */ 
    14421474                   P_ val,  /* :: a */ ) 
    14431475{ 
    1444     W_ info, tso, q; 
     1476    W_ info, q; 
     1477    W_ stack; 
    14451478 
    14461479#if defined(THREADED_RTS) 
    14471480    ("ptr" info) = ccall lockClosure(mvar "ptr"); 
    stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */ 
    14601493        ccall dirty_MVAR(BaseReg "ptr", mvar "ptr"); 
    14611494    } 
    14621495 
     1496    WakeupReaders(mvar, val); 
     1497 
    14631498    q = StgMVar_head(mvar); 
    14641499loop: 
    14651500    if (q == stg_END_TSO_QUEUE_closure) { 
    loop: 
    14761511 
    14771512    // There are takeMVar(s) waiting: wake up the first one 
    14781513 
     1514    W_ tso; 
    14791515    tso = StgMVarTSOQueue_tso(q); 
    14801516    StgMVar_head(mvar) = StgMVarTSOQueue_link(q); 
    14811517    if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { 
    loop: 
    14861522    ASSERT(StgTSO_block_info(tso) == mvar); 
    14871523 
    14881524    // actually perform the takeMVar 
    1489     W_ stack; 
    14901525    stack = StgTSO_stackobj(tso); 
    14911526    PerformTake(stack, val); 
    14921527 
    loop: 
    15031538    return (1); 
    15041539} 
    15051540 
     1541stg_atomicReadMVarzh ( P_ mvar, /* :: MVar a */ ) 
     1542{ 
     1543    W_ val, info, tso, q; 
     1544 
     1545#if defined(THREADED_RTS) 
     1546    ("ptr" info) = ccall lockClosure(mvar "ptr"); 
     1547#else 
     1548    info = GET_INFO(mvar); 
     1549#endif 
     1550 
     1551    if (info == stg_MVAR_CLEAN_info) { 
     1552        ccall dirty_MVAR(BaseReg "ptr", mvar "ptr"); 
     1553    } 
     1554 
     1555    /* If the MVar is empty, put ourselves on the blocked readers 
     1556     * list and wait until we're woken up. 
     1557     */ 
     1558    if (StgMVar_value(mvar) == stg_END_TSO_QUEUE_closure) { 
     1559 
     1560        // We want to put the heap check down here in the slow path, 
     1561        // but be careful to unlock the closure before returning to 
     1562        // the RTS if the check fails. 
     1563        ALLOC_PRIM_WITH_CUSTOM_FAILURE 
     1564            (SIZEOF_StgMVarTSOQueue, 
     1565             unlockClosure(mvar, stg_MVAR_DIRTY_info); 
     1566             GC_PRIM_P(stg_atomicReadMVarzh, mvar)); 
     1567 
     1568        q = Hp - SIZEOF_StgMVarTSOQueue + WDS(1); 
     1569 
     1570        // not a queue, so we can just push it onto the front 
     1571        SET_HDR(q, stg_MVAR_TSO_QUEUE_info, CCS_SYSTEM); 
     1572        StgMVarTSOQueue_link(q) = StgMVar_readers(mvar); 
     1573        StgMVarTSOQueue_tso(q)  = CurrentTSO; 
     1574 
     1575        StgTSO__link(CurrentTSO)       = q; 
     1576        StgTSO_block_info(CurrentTSO)  = mvar; 
     1577        StgTSO_why_blocked(CurrentTSO) = BlockedOnMVarRead::I16; 
     1578        StgMVar_readers(mvar)          = q; 
     1579 
     1580        jump stg_block_atomicreadmvar(mvar); 
     1581    } 
     1582 
     1583    /* we got the value... */ 
     1584    val = StgMVar_value(mvar); 
     1585 
     1586    unlockClosure(mvar, stg_MVAR_DIRTY_info); 
     1587    return (val); 
     1588} 
     1589 
    15061590 
    15071591/* ----------------------------------------------------------------------------- 
    15081592   Stable pointer primitives 
  • rts/RaiseAsync.c

    diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
    index 11f518a..2b87b26 100644
    a b static StgTSO* raiseAsync (Capability *cap, 
    3232static void removeFromQueues(Capability *cap, StgTSO *tso); 
    3333 
    3434static void removeFromMVarBlockedQueue (StgTSO *tso); 
     35static void removeFromMVarReadBlockedQueue (StgTSO *tso); 
    3536 
    3637static void blockedThrowTo (Capability *cap,  
    3738                            StgTSO *target, MessageThrowTo *msg); 
    check_target: 
    294295    } 
    295296 
    296297    case BlockedOnMVar: 
     298    case BlockedOnMVarRead: 
    297299    { 
    298300        /* 
    299301          To establish ownership of this TSO, we need to acquire a 
    check_target: 
    318320 
    319321        // we have the MVar, let's check whether the thread 
    320322        // is still blocked on the same MVar. 
    321         if (target->why_blocked != BlockedOnMVar 
     323        if (target->why_blocked != status 
    322324            || (StgMVar *)target->block_info.closure != mvar) { 
    323325            unlockClosure((StgClosure *)mvar, info); 
    324326            goto retry; 
    check_target: 
    341343            return THROWTO_BLOCKED; 
    342344        } else { 
    343345            // revoke the MVar operation 
    344             removeFromMVarBlockedQueue(target); 
     346            if (status == BlockedOnMVar) { 
     347                removeFromMVarBlockedQueue(target); 
     348            } else { 
     349                ASSERT(status == BlockedOnMVarRead); 
     350                removeFromMVarReadBlockedQueue(target); 
     351            } 
    345352            raiseAsync(cap, target, msg->exception, rtsFalse, NULL); 
    346353            unlockClosure((StgClosure *)mvar, info); 
    347354            return THROWTO_SUCCESS; 
    removeFromMVarBlockedQueue (StgTSO *tso) 
    619626} 
    620627 
    621628static void 
     629removeFromMVarReadBlockedQueue (StgTSO *tso) 
     630{ 
     631    StgMVarTSOQueue *q = (StgMVarTSOQueue*)tso->_link; 
     632 
     633    if (q == (StgMVarTSOQueue*)END_TSO_QUEUE) { 
     634        return; 
     635    } 
     636 
     637    OVERWRITE_INFO(q, &stg_IND_info); 
     638    tso->_link = END_TSO_QUEUE; 
     639} 
     640 
     641static void 
    622642removeFromQueues(Capability *cap, StgTSO *tso) 
    623643{ 
    624644  switch (tso->why_blocked) { 
    removeFromQueues(Capability *cap, StgTSO *tso) 
    640660      removeFromMVarBlockedQueue(tso); 
    641661      goto done; 
    642662 
     663  case BlockedOnMVarRead: 
     664      removeFromMVarReadBlockedQueue(tso); 
     665      goto done; 
     666 
    643667  case BlockedOnBlackHole: 
    644668      // nothing to do 
    645669      goto done; 
  • rts/RaiseAsync.h

    diff --git a/rts/RaiseAsync.h b/rts/RaiseAsync.h
    index 336ab30..d804f6b 100644
    a b interruptible(StgTSO *t) 
    4949{ 
    5050  switch (t->why_blocked) { 
    5151  case BlockedOnMVar: 
     52  case BlockedOnMVarRead: 
    5253  case BlockedOnMsgThrowTo: 
    5354  case BlockedOnRead: 
    5455  case BlockedOnWrite: 
  • rts/RetainerProfile.c

    diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c
    index 4e7ed3e..c25c4b4 100644
    a b inner_loop: 
    16721672        retainClosure(tso->bq,                 c, c_child_r); 
    16731673        retainClosure(tso->trec,               c, c_child_r); 
    16741674        if (   tso->why_blocked == BlockedOnMVar 
     1675               || tso->why_blocked == BlockedOnMVarRead 
    16751676               || tso->why_blocked == BlockedOnBlackHole 
    16761677               || tso->why_blocked == BlockedOnMsgThrowTo 
    16771678            ) { 
  • rts/Schedule.c

    diff --git a/rts/Schedule.c b/rts/Schedule.c
    index abd317c..85bb89e 100644
    a b scheduleDetectDeadlock (Capability **pcap, Task *task) 
    947947            case BlockedOnBlackHole: 
    948948            case BlockedOnMsgThrowTo: 
    949949            case BlockedOnMVar: 
     950            case BlockedOnMVarRead: 
    950951                throwToSingleThreaded(cap, task->incall->tso,  
    951952                                      (StgClosure *)nonTermination_closure); 
    952953                return; 
    resurrectThreads (StgTSO *threads) 
    28312832         
    28322833        switch (tso->why_blocked) { 
    28332834        case BlockedOnMVar: 
     2835        case BlockedOnMVarRead: 
    28342836            /* Called by GC - sched_mutex lock is currently held. */ 
    28352837            throwToSingleThreaded(cap, tso, 
    28362838                                  (StgClosure *)blockedIndefinitelyOnMVar_closure); 
  • rts/StgMiscClosures.cmm

    diff --git a/rts/StgMiscClosures.cmm b/rts/StgMiscClosures.cmm
    index 28a41ad..63bc67f 100644
    a b INFO_TABLE(stg_STABLE_NAME,0,1,PRIM,"STABLE_NAME","STABLE_NAME") 
    464464   and entry code for each type. 
    465465   ------------------------------------------------------------------------- */ 
    466466 
    467 INFO_TABLE(stg_MVAR_CLEAN,3,0,MVAR_CLEAN,"MVAR","MVAR") 
     467INFO_TABLE(stg_MVAR_CLEAN,4,0,MVAR_CLEAN,"MVAR","MVAR") 
    468468{ foreign "C" barf("MVAR object entered!") never returns; } 
    469469 
    470 INFO_TABLE(stg_MVAR_DIRTY,3,0,MVAR_DIRTY,"MVAR","MVAR") 
     470INFO_TABLE(stg_MVAR_DIRTY,4,0,MVAR_DIRTY,"MVAR","MVAR") 
    471471{ foreign "C" barf("MVAR object entered!") never returns; } 
    472472 
    473473/* ----------------------------------------------------------------------------- 
  • rts/Threads.c

    diff --git a/rts/Threads.c b/rts/Threads.c
    index 4c990f1..f2b8005 100644
    a b tryWakeupThread (Capability *cap, StgTSO *tso) 
    255255    switch (tso->why_blocked) 
    256256    { 
    257257    case BlockedOnMVar: 
     258    case BlockedOnMVarRead: 
    258259    { 
    259260        if (tso->_link == END_TSO_QUEUE) { 
    260261            tso->block_info.closure = (StgClosure*)END_TSO_QUEUE; 
    printThreadBlockage(StgTSO *tso) 
    734735  case BlockedOnMVar: 
    735736    debugBelch("is blocked on an MVar @ %p", tso->block_info.closure); 
    736737    break; 
     738  case BlockedOnMVarRead: 
     739    debugBelch("is blocked on atomic MVar read @ %p", tso->block_info.closure); 
     740    break; 
    737741  case BlockedOnBlackHole: 
    738742      debugBelch("is blocked on a black hole %p",  
    739743                 ((StgBlockingQueue*)tso->block_info.bh->bh)); 
  • rts/Trace.c

    diff --git a/rts/Trace.c b/rts/Trace.c
    index 78dfead..2190189 100644
    a b static char *thread_stop_reasons[] = { 
    179179    [ThreadFinished] = "finished", 
    180180    [THREAD_SUSPENDED_FOREIGN_CALL] = "suspended while making a foreign call", 
    181181    [6 + BlockedOnMVar]         = "blocked on an MVar", 
     182    [6 + BlockedOnMVarRead]     = "blocked on an atomic MVar read", 
    182183    [6 + BlockedOnBlackHole]    = "blocked on a black hole", 
    183184    [6 + BlockedOnRead]         = "blocked on a read operation", 
    184185    [6 + BlockedOnWrite]        = "blocked on a write operation", 
  • rts/sm/Compact.c

    diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c
    index 7c89418..fb40994 100644
    a b thread_TSO (StgTSO *tso) 
    442442    thread_(&tso->global_link); 
    443443 
    444444    if (   tso->why_blocked == BlockedOnMVar 
     445        || tso->why_blocked == BlockedOnMVarRead 
    445446        || tso->why_blocked == BlockedOnBlackHole 
    446447        || tso->why_blocked == BlockedOnMsgThrowTo 
    447448        || tso->why_blocked == NotBlocked 
  • rts/sm/Sanity.c

    diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c
    index f0e1659..9b579ab 100644
    a b checkTSO(StgTSO *tso) 
    519519           info == &stg_WHITEHOLE_info); // happens due to STM doing lockTSO() 
    520520 
    521521    if (   tso->why_blocked == BlockedOnMVar 
     522        || tso->why_blocked == BlockedOnMVarRead 
    522523        || tso->why_blocked == BlockedOnBlackHole 
    523524        || tso->why_blocked == BlockedOnMsgThrowTo 
    524525        || tso->why_blocked == NotBlocked 
  • rts/sm/Scav.c

    diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
    index 6137f6d..e0cc688 100644
    a b scavengeTSO (StgTSO *tso) 
    7171 
    7272    evacuate((StgClosure **)&tso->_link); 
    7373    if (   tso->why_blocked == BlockedOnMVar 
     74        || tso->why_blocked == BlockedOnMVarRead 
    7475        || tso->why_blocked == BlockedOnBlackHole 
    7576        || tso->why_blocked == BlockedOnMsgThrowTo 
    7677        || tso->why_blocked == NotBlocked 
  • utils/deriveConstants/DeriveConstants.hs

    diff --git a/utils/deriveConstants/DeriveConstants.hs b/utils/deriveConstants/DeriveConstants.hs
    index 78233a5..a57ceb3 100644
    a b wanteds = concat 
    477477          ,closureSize  C "StgMVar" 
    478478          ,closureField C "StgMVar" "head" 
    479479          ,closureField C "StgMVar" "tail" 
     480          ,closureField C "StgMVar" "readers" 
    480481          ,closureField C "StgMVar" "value" 
    481482 
    482483          ,closureSize  C "StgMVarTSOQueue"