0db5185ecfac8f779bc06d8414f565f77516458a
[ghc-hetmet.git] / ghc / includes / STM.h
1 /*----------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2004
4  *
5  * STM interface definition
6  *
7  *----------------------------------------------------------------------
8
9   STM.h defines the C-level interface to the STM.  
10
11   The design follows that of the PPoPP 2005 paper "Composable memory
12   transactions" extended to include fine-grained locking of TVars.
13
14   Three different implementations can be built.  In overview:
15   
16   STM_UNIPROC  -- no locking at all: not safe for concurrent invocations
17  
18   STM_CG_LOCK  -- coarse-grained locking : a single mutex protects all
19                   TVars
20  
21   STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at
22                   most one TRec at any time.  This allows dynamically
23                   non-conflicting transactions to commit in parallel.
24                   The implementation treats reads optimisitcally --
25                   extra versioning information is retained in the 
26                   saw_update_by field of the TVars so that they do not 
27                   need to be locked for reading.
28
29   STM.C contains more details about the locking schemes used.
30
31 */
32
33 #ifndef STM_H
34 #define STM_H
35
36 #ifdef SMP
37 //#define STM_CG_LOCK
38 #define STM_FG_LOCKS
39 #else
40 #define STM_UNIPROC
41 #endif
42
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46
47 /*----------------------------------------------------------------------
48
49    Start of day
50    ------------
51
52 */
53
54 extern void initSTM(void);
55
56 extern void stmPreGCHook(void);
57
58 /*----------------------------------------------------------------------
59
60    Transaction context management
61    ------------------------------
62
63 */
64
65 /* Create and enter a new transaction context */
66
67 extern StgTRecHeader *stmStartTransaction(StgRegTable *reg, StgTRecHeader *outer);
68 extern StgTRecHeader *stmStartNestedTransaction(StgRegTable *reg, StgTRecHeader *outer
69 );
70
71 /*
72  * Exit the current transaction context, abandoning any read/write
73  * operations performed within it and removing the thread from any
74  * tvar wait queues if it was waitin.  Note that if nested transactions
75  * are not fully supported then this may leave the enclosing
76  * transaction contexts doomed to abort.
77  */
78
79 extern void stmAbortTransaction(StgTRecHeader *trec);
80
81 /*
82  * Ensure that a subsequent commit / validation will fail.  We use this 
83  * in our current handling of transactions that may have become invalid
84  * and started looping.  We strip their stack back to the ATOMICALLY_FRAME,
85  * and, when the thread is next scheduled, discover it to be invalid and
86  * re-execute it.  However, we need to force the transaction to stay invalid
87  * in case other threads' updates make it valid in the mean time.
88  */
89
90 extern void stmCondemnTransaction(StgTRecHeader *trec);
91
92 /*
93  * Return the trec within which the specified trec was created (not
94  * valid if trec==NO_TREC).
95  */
96
97 extern StgTRecHeader *stmGetEnclosingTRec(StgTRecHeader *trec);
98
99 /*----------------------------------------------------------------------
100
101    Validation
102    ----------
103
104   Test whether the specified transaction record, and all those within which
105   it is nested, are still valid.
106
107   Note: the caller can assume that once stmValidateTransaction has
108   returned FALSE for a given trec then that transaction will never
109   again be valid -- we rely on this in Schedule.c when kicking invalid
110   threads at GC (in case they are stuck looping)
111 */
112
113 extern StgBool stmValidateNestOfTransactions(StgTRecHeader *trec);
114
115 /*----------------------------------------------------------------------
116
117    Commit/wait/rewait operations
118    -----------------------------
119
120    These four operations return boolean results which should be interpreted
121    as follows:
122
123    true  => The transaction record was definitely valid 
124
125    false => The transaction record may not have been valid
126
127    Note that, for nested operations, validity here is solely in terms
128    of the specified trec: it does not say whether those that it may be
129    nested are themselves valid.  Callers can check this with 
130    stmValidateNestOfTransactions.
131
132    The user of the STM should ensure that it is always safe to assume that a
133    transaction context is not valid when in fact it is (i.e. to return false in
134    place of true, with side-effects as defined below).  This may cause
135    needless retries of transactions (in the case of validate and commit), or it
136    may cause needless spinning instead of blocking (in the case of wait and
137    rewait).
138
139    In defining the behaviour of wait and rewait we distinguish between two
140    different aspects of a thread's runnability:
141
142     - We say that a thread is "blocked" when it is not running or
143       runnable as far as the scheduler is concerned.
144
145     - We say that a thread is "waiting" when its StgTRecHeader is linked on an
146       tvar's wait queue.
147
148    Considering only STM operations, (blocked) => (waiting).  The user of the STM
149    should ensure that they are prepared for threads to be unblocked spuriously
150    and for wait/reWait to return false even when the previous transaction context
151    is actually still valid.
152 */
153
154 /*
155  * Test whether the current transaction context is valid and, if so,
156  * commit its memory accesses to the heap.  stmCommitTransaction must
157  * unblock any threads which are waiting on tvars that updates have
158  * been committed to.
159  */
160
161 extern StgBool stmCommitTransaction(StgRegTable *reg, StgTRecHeader *trec);
162 extern StgBool stmCommitNestedTransaction(StgRegTable *reg, StgTRecHeader *trec);
163
164 /*
165  * Test whether the current transaction context is valid and, if so,
166  * start the thread waiting for updates to any of the tvars it has
167  * ready from and mark it as blocked.  It is an error to call stmWait
168  * if the thread is already waiting.
169  */
170
171 extern StgBool stmWait(StgRegTable *reg,
172                        StgTSO *tso, 
173                        StgTRecHeader *trec);
174
175 /*
176  * Test whether the current transaction context is valid and, if so,
177  * leave the thread waiting and mark it as blocked again.  If the
178  * transaction context is no longer valid then stop the thread waiting
179  * and leave it as unblocked.  It is an error to call stmReWait if the
180  * thread is not waiting.
181  */
182
183 extern StgBool stmReWait(StgTSO *tso);
184
185 /*----------------------------------------------------------------------
186
187    TVar management operations
188    --------------------------
189 */
190
191 extern StgTVar *stmNewTVar(StgRegTable *reg,
192                            StgClosure *new_value);
193
194 /*----------------------------------------------------------------------
195
196    Data access operations
197    ----------------------
198 */
199
200 /*
201  * Return the logical contents of 'tvar' within the context of the
202  * thread's current transaction.
203  */
204
205 extern StgClosure *stmReadTVar(StgRegTable *reg,
206                                StgTRecHeader *trec, 
207                                StgTVar *tvar);
208
209 /* Update the logical contents of 'tvar' within the context of the
210  * thread's current transaction.
211  */
212
213 extern void stmWriteTVar(StgRegTable *reg,
214                          StgTRecHeader *trec,
215                          StgTVar *tvar, 
216                          StgClosure *new_value);
217
218 /*----------------------------------------------------------------------*/
219
220 /* NULLs */
221
222 #define END_STM_WAIT_QUEUE ((StgTVarWaitQueue *)(void *)&stg_END_STM_WAIT_QUEUE_closure)
223 #define END_STM_CHUNK_LIST ((StgTRecChunk *)(void *)&stg_END_STM_CHUNK_LIST_closure)
224
225 #if IN_STG_CODE
226 #define NO_TREC (stg_NO_TREC_closure)
227 #else
228 #define NO_TREC ((StgTRecHeader *)(void *)&stg_NO_TREC_closure)
229 #endif
230
231 /*----------------------------------------------------------------------*/
232
233 #ifdef __cplusplus
234 }
235 #endif
236
237 #endif /* STM_H */
238