File: Counter.cmm

package info (click to toggle)
haskell-atomic-counter 0.1.2.4-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 144 kB
  • sloc: haskell: 490; makefile: 6
file content (106 lines) | stat: -rw-r--r-- 2,133 bytes parent folder | download
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);
}