Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

8 changed files:

Changes:

  • compiler/GHC/Cmm/Utils.hs
    ... ... @@ -37,6 +37,7 @@ module GHC.Cmm.Utils(
    37 37
     
    
    38 38
             baseExpr, spExpr, hpExpr, spLimExpr, hpLimExpr,
    
    39 39
             currentTSOExpr, currentNurseryExpr, cccsExpr,
    
    40
    +        myCapabilityExpr,
    
    40 41
     
    
    41 42
             -- Tagging
    
    42 43
             cmmTagMask, cmmPointerMask, cmmUntag, cmmIsTagged, cmmIsNotTagged,
    
    ... ... @@ -569,7 +570,7 @@ blockTicks b = reverse $ foldBlockNodesF goStmt b []
    569 570
     -- Access to common global registers
    
    570 571
     
    
    571 572
     baseExpr, spExpr, hpExpr, currentTSOExpr, currentNurseryExpr,
    
    572
    -  spLimExpr, hpLimExpr, cccsExpr :: Platform -> CmmExpr
    
    573
    +  spLimExpr, hpLimExpr, cccsExpr, myCapabilityExpr :: Platform -> CmmExpr
    
    573 574
     baseExpr           p = CmmReg $ baseReg           p
    
    574 575
     spExpr             p = CmmReg $ spReg             p
    
    575 576
     spLimExpr          p = CmmReg $ spLimReg          p
    
    ... ... @@ -578,3 +579,5 @@ hpLimExpr p = CmmReg $ hpLimReg p
    578 579
     currentTSOExpr     p = CmmReg $ currentTSOReg     p
    
    579 580
     currentNurseryExpr p = CmmReg $ currentNurseryReg p
    
    580 581
     cccsExpr           p = CmmReg $ cccsReg           p
    
    582
    +myCapabilityExpr   p =
    
    583
    +  cmmRegOff (baseReg p) $ negate $ pc_OFFSET_Capability_r $ platformConstants p

  • compiler/GHC/StgToCmm/Prim.hs
    ... ... @@ -345,6 +345,25 @@ emitPrimOp cfg primop =
    345 345
         emitPrimCall [res] (MO_Xchg (wordWidth platform)) [dst, val]
    
    346 346
         emitDirtyMutVar mutv (CmmReg (CmmLocal res))
    
    347 347
     
    
    348
    +  TryPutMVarOp -> \[mvar, val] -> inlinePrimop $ \[res] -> do
    
    349
    +    cres <- newTemp b8
    
    350
    +    emitCCall
    
    351
    +      [(cres, NoHint)]
    
    352
    +      ( CmmLit
    
    353
    +          ( CmmLabel
    
    354
    +              ( mkForeignLabel
    
    355
    +                  (fsLit "performTryPutMVar")
    
    356
    +                  ForeignLabelInExternalPackage
    
    357
    +                  IsFunction
    
    358
    +              )
    
    359
    +          )
    
    360
    +      )
    
    361
    +      [(myCapabilityExpr platform, AddrHint), (mvar, AddrHint), (val, AddrHint)]
    
    362
    +    emitAssign (CmmLocal res) $
    
    363
    +      CmmMachOp
    
    364
    +        (MO_UU_Conv W8 (wordWidth platform))
    
    365
    +        [CmmReg (CmmLocal cres)]
    
    366
    +
    
    348 367
     --  #define sizzeofByteArrayzh(r,a) \
    
    349 368
     --     r = ((StgArrBytes *)(a))->bytes
    
    350 369
       SizeofByteArrayOp -> \[arg] -> inlinePrimop $ \[res] ->
    
    ... ... @@ -1777,7 +1796,6 @@ emitPrimOp cfg primop =
    1777 1796
       TakeMVarOp -> alwaysExternal
    
    1778 1797
       TryTakeMVarOp -> alwaysExternal
    
    1779 1798
       PutMVarOp -> alwaysExternal
    
    1780
    -  TryPutMVarOp -> alwaysExternal
    
    1781 1799
       ReadMVarOp -> alwaysExternal
    
    1782 1800
       TryReadMVarOp -> alwaysExternal
    
    1783 1801
       IsEmptyMVarOp -> alwaysExternal
    

  • rts/PrimOps.cmm
    ... ... @@ -1927,95 +1927,6 @@ loop:
    1927 1927
     }
    
    1928 1928
     
    
    1929 1929
     
    
    1930
    -// NOTE: there is another implementation of this function in
    
    1931
    -// Threads.c:performTryPutMVar().  Keep them in sync!  It was
    
    1932
    -// measurably slower to call the C function from here (70% for a
    
    1933
    -// tight loop doing tryPutMVar#).
    
    1934
    -//
    
    1935
    -// TODO: we could kill the duplication by making tryPutMVar# into an
    
    1936
    -// inline primop that expands into a C call to performTryPutMVar().
    
    1937
    -stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
    
    1938
    -                   P_ val,  /* :: a */ )
    
    1939
    -{
    
    1940
    -    W_ info, tso, q, qinfo;
    
    1941
    -
    
    1942
    -    LOCK_CLOSURE(mvar, info);
    
    1943
    -
    
    1944
    -    if (StgMVar_value(mvar) != stg_END_TSO_QUEUE_closure) {
    
    1945
    -#if defined(THREADED_RTS)
    
    1946
    -        unlockClosure(mvar, info);
    
    1947
    -#endif
    
    1948
    -        return (0);
    
    1949
    -    }
    
    1950
    -
    
    1951
    -    q = StgMVar_head(mvar);
    
    1952
    -loop:
    
    1953
    -    if (q == stg_END_TSO_QUEUE_closure) {
    
    1954
    -        /* No further takes, the MVar is now full. */
    
    1955
    -        if (info == stg_MVAR_CLEAN_info) {
    
    1956
    -            ccall dirty_MVAR(BaseReg "ptr", mvar "ptr", StgMVar_value(mvar) "ptr");
    
    1957
    -        }
    
    1958
    -
    
    1959
    -        StgMVar_value(mvar) = val;
    
    1960
    -        unlockClosure(mvar, stg_MVAR_DIRTY_info);
    
    1961
    -        return (1);
    
    1962
    -    }
    
    1963
    -
    
    1964
    -    qinfo = GET_INFO_ACQUIRE(q);
    
    1965
    -
    
    1966
    -    if (qinfo == stg_IND_info ||
    
    1967
    -        qinfo == stg_MSG_NULL_info) {
    
    1968
    -        q = %acquire StgInd_indirectee(q);
    
    1969
    -        goto loop;
    
    1970
    -    }
    
    1971
    -
    
    1972
    -    // There are takeMVar(s) waiting: wake up the first one
    
    1973
    -
    
    1974
    -    tso = StgMVarTSOQueue_tso(q);
    
    1975
    -    q = StgMVarTSOQueue_link(q);
    
    1976
    -    StgMVar_head(mvar) = q;
    
    1977
    -    if (q == stg_END_TSO_QUEUE_closure) {
    
    1978
    -        StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
    
    1979
    -    } else {
    
    1980
    -        if (info == stg_MVAR_CLEAN_info) {
    
    1981
    -            // Resolve #18919.
    
    1982
    -            ccall dirty_MVAR(BaseReg "ptr", mvar "ptr",
    
    1983
    -                             StgMVar_value(mvar) "ptr");
    
    1984
    -            info = stg_MVAR_DIRTY_info;
    
    1985
    -        }
    
    1986
    -    }
    
    1987
    -
    
    1988
    -    // save why_blocked here, because waking up the thread destroys
    
    1989
    -    // this information
    
    1990
    -    W_ why_blocked;
    
    1991
    -    why_blocked = TO_W_(StgTSO_why_blocked(tso)); // TODO: Missing barrier
    
    1992
    -    ASSERT(StgTSO_block_info(tso) == mvar);
    
    1993
    -
    
    1994
    -    // actually perform the takeMVar
    
    1995
    -    W_ stack;
    
    1996
    -    stack = StgTSO_stackobj(tso);
    
    1997
    -    if (IS_STACK_CLEAN(stack)) {
    
    1998
    -        ccall dirty_STACK(MyCapability() "ptr", stack "ptr");
    
    1999
    -    }
    
    2000
    -    PerformTake(stack, val);
    
    2001
    -
    
    2002
    -    // indicate that the MVar operation has now completed.
    
    2003
    -    StgTSO__link(tso) = stg_END_TSO_QUEUE_closure;
    
    2004
    -
    
    2005
    -    ccall tryWakeupThread(MyCapability() "ptr", tso);
    
    2006
    -
    
    2007
    -    // If it was a readMVar, then we can still do work,
    
    2008
    -    // so loop back. (XXX: This could take a while)
    
    2009
    -    if (why_blocked == BlockedOnMVarRead)
    
    2010
    -        goto loop;
    
    2011
    -
    
    2012
    -    ASSERT(why_blocked == BlockedOnMVar);
    
    2013
    -
    
    2014
    -    unlockClosure(mvar, info);
    
    2015
    -    return (1);
    
    2016
    -}
    
    2017
    -
    
    2018
    -
    
    2019 1930
     stg_readMVarzh ( P_ mvar, /* :: MVar a */ )
    
    2020 1931
     {
    
    2021 1932
         W_ val, info, tso, q;
    

  • rts/RtsSymbols.c
    ... ... @@ -678,6 +678,7 @@ extern char **environ;
    678 678
           SymI_HasDataProto(stg_readTVarIOzh)                                   \
    
    679 679
           SymI_HasProto(resumeThread)                                       \
    
    680 680
           SymI_HasProto(setNumCapabilities)                                 \
    
    681
    +      SymI_HasProto(performTryPutMVar)                                  \
    
    681 682
           SymI_HasProto(getNumberOfProcessors)                              \
    
    682 683
           SymI_HasProto(resolveObjs)                                        \
    
    683 684
           SymI_HasDataProto(stg_retryzh)                                        \
    
    ... ... @@ -869,7 +870,6 @@ extern char **environ;
    869 870
           SymI_HasDataProto(stg_takeMVarzh)                                     \
    
    870 871
           SymI_HasDataProto(stg_readMVarzh)                                     \
    
    871 872
           SymI_HasDataProto(stg_threadStatuszh)                                 \
    
    872
    -      SymI_HasDataProto(stg_tryPutMVarzh)                                   \
    
    873 873
           SymI_HasDataProto(stg_tryTakeMVarzh)                                  \
    
    874 874
           SymI_HasDataProto(stg_tryReadMVarzh)                                  \
    
    875 875
           SymI_HasDataProto(stg_unmaskAsyncExceptionszh)                        \
    

  • rts/Threads.c
    ... ... @@ -795,8 +795,6 @@ threadStackUnderflow (Capability *cap, StgTSO *tso)
    795 795
     
    
    796 796
     /* ----------------------------------------------------------------------------
    
    797 797
        Implementation of tryPutMVar#
    
    798
    -
    
    799
    -   NOTE: this should be kept in sync with stg_tryPutMVarzh in PrimOps.cmm
    
    800 798
        ------------------------------------------------------------------------- */
    
    801 799
     
    
    802 800
     bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value)
    

  • rts/Threads.h
    ... ... @@ -24,7 +24,7 @@ void migrateThread (Capability *from, StgTSO *tso, Capability *to);
    24 24
     //
    
    25 25
     #if defined(THREADED_RTS)
    
    26 26
     void wakeupThreadOnCapability (Capability *cap,
    
    27
    -                               Capability *other_cap, 
    
    27
    +                               Capability *other_cap,
    
    28 28
                                    StgTSO *tso);
    
    29 29
     #endif
    
    30 30
     
    
    ... ... @@ -40,8 +40,6 @@ StgBool isThreadBound (StgTSO* tso);
    40 40
     void threadStackOverflow  (Capability *cap, StgTSO *tso);
    
    41 41
     W_   threadStackUnderflow (Capability *cap, StgTSO *tso);
    
    42 42
     
    
    43
    -bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value);
    
    44
    -
    
    45 43
     #if defined(DEBUG)
    
    46 44
     void printThreadBlockage (StgTSO *tso);
    
    47 45
     void printThreadStatus (StgTSO *t);
    

  • rts/include/rts/Threads.h
    ... ... @@ -90,3 +90,5 @@ extern Capability MainCapability;
    90 90
     // current value at the moment).
    
    91 91
     //
    
    92 92
     extern void setNumCapabilities (uint32_t new_);
    
    93
    +
    
    94
    +bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value);

  • rts/include/stg/MiscClosures.h
    ... ... @@ -512,7 +512,6 @@ RTS_FUN_DECL(stg_takeMVarzh);
    512 512
     RTS_FUN_DECL(stg_putMVarzh);
    
    513 513
     RTS_FUN_DECL(stg_readMVarzh);
    
    514 514
     RTS_FUN_DECL(stg_tryTakeMVarzh);
    
    515
    -RTS_FUN_DECL(stg_tryPutMVarzh);
    
    516 515
     RTS_FUN_DECL(stg_tryReadMVarzh);
    
    517 516
     
    
    518 517
     RTS_FUN_DECL(stg_waitReadzh);