remove unused TICK_FREQUENCY
[ghc-hetmet.git] / 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 THREADED_RTS
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    GC interaction
50    --------------
51 */
52
53 extern void stmPreGCHook(void);
54
55 /*----------------------------------------------------------------------
56
57    Transaction context management
58    ------------------------------
59
60 */
61
62 /* Create and enter a new transaction context */
63
64 extern StgTRecHeader *stmStartTransaction(Capability *cap, StgTRecHeader *outer);
65 extern StgTRecHeader *stmStartNestedTransaction(Capability *cap, StgTRecHeader *outer
66 );
67
68 /*
69  * Roll back the current transatcion context.  NB: if this is a nested tx
70  * then we merge its read set into its parents.  This is because a change
71  * to that read set could change whether or not the tx should abort.
72  */
73
74 extern void stmAbortTransaction(Capability *cap, StgTRecHeader *trec);
75 extern void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec);
76
77 /*
78  * Ensure that a subsequent commit / validation will fail.  We use this 
79  * in our current handling of transactions that may have become invalid
80  * and started looping.  We strip their stack back to the ATOMICALLY_FRAME,
81  * and, when the thread is next scheduled, discover it to be invalid and
82  * re-execute it.  However, we need to force the transaction to stay invalid
83  * in case other threads' updates make it valid in the mean time.
84  */
85
86 extern void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec);
87
88 /*
89  * Return the trec within which the specified trec was created (not
90  * valid if trec==NO_TREC).
91  */
92
93 extern StgTRecHeader *stmGetEnclosingTRec(StgTRecHeader *trec);
94
95 /*----------------------------------------------------------------------
96
97    Validation
98    ----------
99
100   Test whether the specified transaction record, and all those within which
101   it is nested, are still valid.
102
103   Note: the caller can assume that once stmValidateTransaction has
104   returned FALSE for a given trec then that transaction will never
105   again be valid -- we rely on this in Schedule.c when kicking invalid
106   threads at GC (in case they are stuck looping)
107 */
108
109 extern StgBool stmValidateNestOfTransactions(StgTRecHeader *trec);
110
111 /*----------------------------------------------------------------------
112
113    Commit/wait/rewait operations
114    -----------------------------
115
116    These four operations return boolean results which should be interpreted
117    as follows:
118
119    true  => The transaction record was definitely valid 
120
121    false => The transaction record may not have been valid
122
123    Note that, for nested operations, validity here is solely in terms
124    of the specified trec: it does not say whether those that it may be
125    nested are themselves valid.  Callers can check this with 
126    stmValidateNestOfTransactions.
127
128    The user of the STM should ensure that it is always safe to assume that a
129    transaction context is not valid when in fact it is (i.e. to return false in
130    place of true, with side-effects as defined below).  This may cause
131    needless retries of transactions (in the case of validate and commit), or it
132    may cause needless spinning instead of blocking (in the case of wait and
133    rewait).
134
135    In defining the behaviour of wait and rewait we distinguish between two
136    different aspects of a thread's runnability:
137
138     - We say that a thread is "blocked" when it is not running or
139       runnable as far as the scheduler is concerned.
140
141     - We say that a thread is "waiting" when its StgTRecHeader is linked on an
142       tvar's wait queue.
143
144    Considering only STM operations, (blocked) => (waiting).  The user of the STM
145    should ensure that they are prepared for threads to be unblocked spuriously
146    and for wait/reWait to return false even when the previous transaction context
147    is actually still valid.
148 */
149
150 /*
151  * Fill in the trec's list of invariants that might be violated by the current
152  * transaction.  
153  */
154
155 extern StgInvariantCheckQueue *stmGetInvariantsToCheck(Capability *cap, 
156                                                        StgTRecHeader *trec);
157
158 extern void stmAddInvariantToCheck(Capability *cap, 
159                                    StgTRecHeader *trec,
160                                    StgClosure *code);
161
162 /*
163  * Test whether the current transaction context is valid and, if so,
164  * commit its memory accesses to the heap.  stmCommitTransaction must
165  * unblock any threads which are waiting on tvars that updates have
166  * been committed to.
167  */
168
169 extern StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec);
170 extern StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec);
171
172 /*
173  * Test whether the current transaction context is valid and, if so,
174  * start the thread waiting for updates to any of the tvars it has
175  * ready from and mark it as blocked.  It is an error to call stmWait
176  * if the thread is already waiting.  
177  */
178
179 extern StgBool stmWait(Capability *cap,
180                        StgTSO *tso, 
181                        StgTRecHeader *trec);
182
183 extern void stmWaitUnlock(Capability *cap, StgTRecHeader *trec);
184
185 /*
186  * Test whether the current transaction context is valid and, if so,
187  * leave the thread waiting and mark it as blocked again.  If the
188  * transaction context is no longer valid then stop the thread waiting
189  * and leave it as unblocked.  It is an error to call stmReWait if the
190  * thread is not waiting.
191  */
192
193 extern StgBool stmReWait(Capability *cap, StgTSO *tso);
194
195 /*----------------------------------------------------------------------
196
197    TVar management operations
198    --------------------------
199 */
200
201 extern StgTVar *stmNewTVar(Capability *cap,
202                            StgClosure *new_value);
203
204 /*----------------------------------------------------------------------
205
206    Data access operations
207    ----------------------
208 */
209
210 /*
211  * Return the logical contents of 'tvar' within the context of the
212  * thread's current transaction.
213  */
214
215 extern StgClosure *stmReadTVar(Capability *cap,
216                                StgTRecHeader *trec, 
217                                StgTVar *tvar);
218
219 /* Update the logical contents of 'tvar' within the context of the
220  * thread's current transaction.
221  */
222
223 extern void stmWriteTVar(Capability *cap,
224                          StgTRecHeader *trec,
225                          StgTVar *tvar, 
226                          StgClosure *new_value);
227
228 /*----------------------------------------------------------------------*/
229
230 /* NULLs */
231
232 #define END_STM_WATCH_QUEUE ((StgTVarWatchQueue *)(void *)&stg_END_STM_WATCH_QUEUE_closure)
233 #define END_INVARIANT_CHECK_QUEUE ((StgInvariantCheckQueue *)(void *)&stg_END_INVARIANT_CHECK_QUEUE_closure)
234 #define END_STM_CHUNK_LIST ((StgTRecChunk *)(void *)&stg_END_STM_CHUNK_LIST_closure)
235
236 #define NO_TREC ((StgTRecHeader *)(void *)&stg_NO_TREC_closure)
237
238 /*----------------------------------------------------------------------*/
239
240 #ifdef __cplusplus
241 }
242 #endif
243
244 #endif /* STM_H */
245