1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include "Cmm.h"
#define SIZEOF_StgCounter (SIZEOF_StgHeader + WDS(1))
INFO_TABLE(stg_Counter, 0, 1, MUT_PRIM, "Counter", "Counter") ()
{
foreign "C" barf("stg_Counter entered!", NULL) never returns;
}
stg_newCounterzh (W_ x)
{
P_ c;
ALLOC_PRIM_N (SIZEOF_StgCounter, stg_newCounterzh, x);
c = Hp - SIZEOF_StgCounter + WDS(1);
SET_HDR(c, stg_Counter_info, CCCS);
W_[c + SIZEOF_StgHeader] = x;
return (c);
}
stg_atomicGetCounterzh (P_ c)
{
W_ x;
// load_seqcst64 is available since GHC 9.4
(x) = prim %load_seqcst64(c + SIZEOF_StgHeader);
return (x);
}
stg_atomicSetCounterzh (P_ c, W_ x)
{
// store_seqcst64 is available since GHC 9.4
prim %store_seqcst64(c + SIZEOF_StgHeader, x);
return ();
}
stg_atomicAddCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_add64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_add64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_atomicSubCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_sub64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_sub64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_atomicAndCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_and64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_and64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_atomicOrCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_or64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_or64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_atomicXorCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_xor64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_xor64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_atomicNandCounterzh (P_ c, W_ x)
{
W_ y;
#if __GLASGOW_HASKELL__ >= 907
(y) = prim %fetch_nand64(c + SIZEOF_StgHeader, x);
#else
(y) = ccall hs_atomic_nand64(c + SIZEOF_StgHeader, x);
#endif
return (y);
}
stg_casCounterzh (P_ c, W_ x, W_ y)
{
W_ z;
(z) = prim %cmpxchg64(c + SIZEOF_StgHeader, x, y);
return (z);
}
|