Use latin1 code page on Windows for response files.
[ghc.git] / rts / SMPClosureOps.h
1 /* ----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 2005-2013
4 *
5 * Macros for THREADED_RTS support
6 *
7 * -------------------------------------------------------------------------- */
8
9 #ifndef RTS_STORAGE_SMPCLOSUREOPS_H
10 #define RTS_STORAGE_SMPCLOSUREOPS_H
11
12 #include "BeginPrivate.h"
13
14 #ifdef CMINUSMINUS
15
16 /* Lock closure, equivalent to ccall lockClosure but the condition is inlined.
17 * Arguments are swapped for uniformity with unlockClosure. */
18 #if defined(THREADED_RTS)
19 #define LOCK_CLOSURE(closure, info) \
20 if (CInt[n_capabilities] == 1 :: CInt) { \
21 info = GET_INFO(closure); \
22 } else { \
23 ("ptr" info) = ccall reallyLockClosure(closure "ptr"); \
24 }
25 #else
26 #define LOCK_CLOSURE(closure, info) info = GET_INFO(closure)
27 #endif
28
29 #define unlockClosure(ptr,info) \
30 prim_write_barrier; \
31 StgHeader_info(ptr) = info;
32
33 #else
34
35 INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p);
36 EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p);
37 EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p);
38 EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info);
39
40 #if defined(THREADED_RTS)
41
42 /* -----------------------------------------------------------------------------
43 * Locking/unlocking closures
44 *
45 * This is used primarily in the implementation of MVars.
46 * -------------------------------------------------------------------------- */
47
48 // We want a callable copy of reallyLockClosure() so that we can refer to it
49 // from .cmm files compiled using the native codegen, so these are given
50 // EXTERN_INLINE. C-- should use LOCK_CLOSURE not lockClosure, so we've
51 // kept it INLINE_HEADER.
52 EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p)
53 {
54 StgWord info;
55 do {
56 uint32_t i = 0;
57 do {
58 info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
59 if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
60 } while (++i < SPIN_COUNT);
61 yieldThread();
62 } while (1);
63 }
64
65 INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p)
66 {
67 if (n_capabilities == 1) {
68 return (StgInfoTable *)p->header.info;
69 }
70 else {
71 return reallyLockClosure(p);
72 }
73 }
74
75 // ToDo: consider splitting tryLockClosure into reallyTryLockClosure,
76 // same as lockClosure
77 EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p)
78 {
79 StgWord info;
80 if (n_capabilities == 1) {
81 return (StgInfoTable *)p->header.info;
82 }
83 else {
84 info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
85 if (info != (W_)&stg_WHITEHOLE_info) {
86 return (StgInfoTable *)info;
87 } else {
88 return NULL;
89 }
90 }
91 }
92
93 #else /* !THREADED_RTS */
94
95 EXTERN_INLINE StgInfoTable *
96 reallyLockClosure(StgClosure *p)
97 { return (StgInfoTable *)p->header.info; }
98
99 INLINE_HEADER StgInfoTable *
100 lockClosure(StgClosure *p)
101 { return (StgInfoTable *)p->header.info; }
102
103 EXTERN_INLINE StgInfoTable *
104 tryLockClosure(StgClosure *p)
105 { return (StgInfoTable *)p->header.info; }
106
107 #endif /* THREADED_RTS */
108
109 EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info)
110 {
111 // This is a strictly ordered write, so we need a write_barrier():
112 write_barrier();
113 p->header.info = info;
114 }
115
116 // Handy specialised versions of lockClosure()/unlockClosure()
117 INLINE_HEADER void lockTSO(StgTSO *tso);
118 INLINE_HEADER void lockTSO(StgTSO *tso)
119 { lockClosure((StgClosure *)tso); }
120
121 INLINE_HEADER void unlockTSO(StgTSO *tso);
122 INLINE_HEADER void unlockTSO(StgTSO *tso)
123 { unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
124
125 #endif /* CMINUSMINUS */
126
127 #include "EndPrivate.h"
128
129 #endif /* RTS_STORAGE_SMPCLOSUREOPS_H */