annotate libitm/libitm.texi @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 \input texinfo @c -*-texinfo-*-
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 @c %**start of header
kono
parents:
diff changeset
4 @setfilename libitm.info
kono
parents:
diff changeset
5 @settitle GNU libitm
kono
parents:
diff changeset
6 @c %**end of header
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 @copying
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
10 Copyright @copyright{} 2011-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 Permission is granted to copy, distribute and/or modify this document
kono
parents:
diff changeset
13 under the terms of the GNU Free Documentation License, Version 1.2 or
kono
parents:
diff changeset
14 any later version published by the Free Software Foundation; with no
kono
parents:
diff changeset
15 Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
kono
parents:
diff changeset
16 A copy of the license is included in the section entitled ``GNU
kono
parents:
diff changeset
17 Free Documentation License''.
kono
parents:
diff changeset
18 @end copying
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 @ifinfo
kono
parents:
diff changeset
21 @dircategory GNU Libraries
kono
parents:
diff changeset
22 @direntry
kono
parents:
diff changeset
23 * libitm: (libitm). GNU Transactional Memory Library
kono
parents:
diff changeset
24 @end direntry
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 This manual documents the GNU Transactional Memory Library.
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 @insertcopying
kono
parents:
diff changeset
29 @end ifinfo
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 @setchapternewpage odd
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 @titlepage
kono
parents:
diff changeset
35 @title The GNU Transactional Memory Library
kono
parents:
diff changeset
36 @page
kono
parents:
diff changeset
37 @vskip 0pt plus 1filll
kono
parents:
diff changeset
38 @comment For the @value{version-GCC} Version*
kono
parents:
diff changeset
39 @sp 1
kono
parents:
diff changeset
40 @insertcopying
kono
parents:
diff changeset
41 @end titlepage
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 @summarycontents
kono
parents:
diff changeset
44 @contents
kono
parents:
diff changeset
45 @page
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 @node Top
kono
parents:
diff changeset
49 @top Introduction
kono
parents:
diff changeset
50 @cindex Introduction
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 This manual documents the usage and internals of libitm, the GNU Transactional
kono
parents:
diff changeset
53 Memory Library. It provides transaction support for accesses to a process'
kono
parents:
diff changeset
54 memory, enabling easy-to-use synchronization of accesses to shared memory by
kono
parents:
diff changeset
55 several threads.
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 @comment
kono
parents:
diff changeset
59 @comment When you add a new menu item, please keep the right hand
kono
parents:
diff changeset
60 @comment aligned to the same column. Do not use tabs. This provides
kono
parents:
diff changeset
61 @comment better formatting.
kono
parents:
diff changeset
62 @comment
kono
parents:
diff changeset
63 @menu
kono
parents:
diff changeset
64 * Enabling libitm:: How to enable libitm for your applications.
kono
parents:
diff changeset
65 * C/C++ Language Constructs for TM::
kono
parents:
diff changeset
66 Notes on the language-level interface supported
kono
parents:
diff changeset
67 by gcc.
kono
parents:
diff changeset
68 * The libitm ABI:: Notes on the external ABI provided by libitm.
kono
parents:
diff changeset
69 * Internals:: Notes on libitm's internal synchronization.
kono
parents:
diff changeset
70 * GNU Free Documentation License::
kono
parents:
diff changeset
71 How you can copy and share this manual.
kono
parents:
diff changeset
72 * Library Index:: Index of this documentation.
kono
parents:
diff changeset
73 @end menu
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
77 @c Enabling libitm
kono
parents:
diff changeset
78 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 @node Enabling libitm
kono
parents:
diff changeset
81 @chapter Enabling libitm
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 To activate support for TM in C/C++, the compile-time flag @option{-fgnu-tm}
kono
parents:
diff changeset
84 must be specified. This enables TM language-level constructs such as
kono
parents:
diff changeset
85 transaction statements (e.g., @code{__transaction_atomic}, @pxref{C/C++
kono
parents:
diff changeset
86 Language Constructs for TM} for details).
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
89 @c C/C++ Language Constructs for TM
kono
parents:
diff changeset
90 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 @node C/C++ Language Constructs for TM
kono
parents:
diff changeset
93 @chapter C/C++ Language Constructs for TM
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 Transactions are supported in C++ and C in the form of transaction statements,
kono
parents:
diff changeset
96 transaction expressions, and function transactions. In the following example,
kono
parents:
diff changeset
97 both @code{a} and @code{b} will be read and the difference will be written to
kono
parents:
diff changeset
98 @code{c}, all atomically and isolated from other transactions:
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 @example
kono
parents:
diff changeset
101 __transaction_atomic @{ c = a - b; @}
kono
parents:
diff changeset
102 @end example
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 Therefore, another thread can use the following code to concurrently update
kono
parents:
diff changeset
105 @code{b} without ever causing @code{c} to hold a negative value (and without
kono
parents:
diff changeset
106 having to use other synchronization constructs such as locks or C++11
kono
parents:
diff changeset
107 atomics):
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 @example
kono
parents:
diff changeset
110 __transaction_atomic @{ if (a > b) b++; @}
kono
parents:
diff changeset
111 @end example
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 GCC follows the @uref{https://sites.google.com/site/tmforcplusplus/, Draft
kono
parents:
diff changeset
114 Specification of Transactional Language Constructs for C++ (v1.1)} in its
kono
parents:
diff changeset
115 implementation of transactions.
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 The precise semantics of transactions are defined in terms of the C++11/C11
kono
parents:
diff changeset
118 memory model (see the specification). Roughly, transactions provide
kono
parents:
diff changeset
119 synchronization guarantees that are similar to what would be guaranteed when
kono
parents:
diff changeset
120 using a single global lock as a guard for all transactions. Note that like
kono
parents:
diff changeset
121 other synchronization constructs in C/C++, transactions rely on a
kono
parents:
diff changeset
122 data-race-free program (e.g., a nontransactional write that is concurrent
kono
parents:
diff changeset
123 with a transactional read to the same memory location is a data race).
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
126 @c The libitm ABI
kono
parents:
diff changeset
127 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 @node The libitm ABI
kono
parents:
diff changeset
130 @chapter The libitm ABI
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 The ABI provided by libitm is basically equal to the Linux variant of Intel's
kono
parents:
diff changeset
133 current TM ABI specification document (Revision 1.1, May 6 2009) but with the
kono
parents:
diff changeset
134 differences listed in this chapter. It would be good if these changes would
kono
parents:
diff changeset
135 eventually be merged into a future version of this specification. To ease
kono
parents:
diff changeset
136 look-up, the following subsections mirror the structure of this specification.
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 @section [No changes] Objectives
kono
parents:
diff changeset
139 @section [No changes] Non-objectives
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 @section Library design principles
kono
parents:
diff changeset
142 @subsection [No changes] Calling conventions
kono
parents:
diff changeset
143 @subsection [No changes] TM library algorithms
kono
parents:
diff changeset
144 @subsection [No changes] Optimized load and store routines
kono
parents:
diff changeset
145 @subsection [No changes] Aligned load and store routines
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 @subsection Data logging functions
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 The memory locations accessed with transactional loads and stores and the
kono
parents:
diff changeset
150 memory locations whose values are logged must not overlap. This required
kono
parents:
diff changeset
151 separation only extends to the scope of the execution of one transaction
kono
parents:
diff changeset
152 including all the executions of all nested transactions.
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 The compiler must be consistent (within the scope of a single transaction)
kono
parents:
diff changeset
155 about which memory locations are shared and which are not shared with other
kono
parents:
diff changeset
156 threads (i.e., data must be accessed either transactionally or
kono
parents:
diff changeset
157 nontransactionally). Otherwise, non-write-through TM algorithms would not work.
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 For memory locations on the stack, this requirement extends to only the
kono
parents:
diff changeset
160 lifetime of the stack frame that the memory location belongs to (or the
kono
parents:
diff changeset
161 lifetime of the transaction, whichever is shorter). Thus, memory that is
kono
parents:
diff changeset
162 reused for several stack frames could be target of both data logging and
kono
parents:
diff changeset
163 transactional accesses; however, this is harmless because these stack frames'
kono
parents:
diff changeset
164 lifetimes will end before the transaction finishes.
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 @subsection [No changes] Scatter/gather calls
kono
parents:
diff changeset
167 @subsection [No changes] Serial and irrevocable mode
kono
parents:
diff changeset
168 @subsection [No changes] Transaction descriptor
kono
parents:
diff changeset
169 @subsection Store allocation
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 There is no @code{getTransaction} function.
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 @subsection [No changes] Naming conventions
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 @subsection Function pointer encryption
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 Currently, this is not implemented.
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 @section Types and macros list
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 @code{_ITM_codeProperties} has changed, @pxref{txn-code-properties,,Starting a
kono
parents:
diff changeset
183 transaction}.
kono
parents:
diff changeset
184 @code{_ITM_srcLocation} is not used.
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 @section Function list
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 @subsection Initialization and finalization functions
kono
parents:
diff changeset
190 These functions are not part of the ABI.
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 @subsection [No changes] Version checking
kono
parents:
diff changeset
193 @subsection [No changes] Error reporting
kono
parents:
diff changeset
194 @subsection [No changes] inTransaction call
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 @subsection State manipulation functions
kono
parents:
diff changeset
197 There is no @code{getTransaction} function. Transaction identifiers for
kono
parents:
diff changeset
198 nested transactions will be ordered but not necessarily sequential (i.e., for
kono
parents:
diff changeset
199 a nested transaction's identifier @var{IN} and its enclosing transaction's
kono
parents:
diff changeset
200 identifier @var{IE}, it is guaranteed that @math{IN >= IE}).
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 @subsection [No changes] Source locations
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 @subsection Starting a transaction
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 @subsubsection Transaction code properties
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 @anchor{txn-code-properties}
kono
parents:
diff changeset
209 The bit @code{hasNoXMMUpdate} is instead called @code{hasNoVectorUpdate}.
kono
parents:
diff changeset
210 Iff it is set, vector register save/restore is not necessary for any target
kono
parents:
diff changeset
211 machine.
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 The @code{hasNoFloatUpdate} bit (@code{0x0010}) is new. Iff it is set, floating
kono
parents:
diff changeset
214 point register save/restore is not necessary for any target machine.
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 @code{undoLogCode} is not supported and a fatal runtime error will be raised
kono
parents:
diff changeset
217 if this bit is set. It is not properly defined in the ABI why barriers
kono
parents:
diff changeset
218 other than undo logging are not present; Are they not necessary (e.g., a
kono
parents:
diff changeset
219 transaction operating purely on thread-local data) or have they been omitted by
kono
parents:
diff changeset
220 the compiler because it thinks that some kind of global synchronization
kono
parents:
diff changeset
221 (e.g., serial mode) might perform better? The specification suggests that the
kono
parents:
diff changeset
222 latter might be the case, but the former seems to be more useful.
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 The @code{readOnly} bit (@code{0x4000}) is new. @strong{TODO} Lexical or dynamic
kono
parents:
diff changeset
225 scope?
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 @code{hasNoRetry} is not supported. If this bit is not set, but
kono
parents:
diff changeset
228 @code{hasNoAbort} is set, the library can assume that transaction
kono
parents:
diff changeset
229 rollback will not be requested.
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 It would be useful if the absence of externally-triggered rollbacks would be
kono
parents:
diff changeset
232 reported for the dynamic scope as well, not just for the lexical scope
kono
parents:
diff changeset
233 (@code{hasNoAbort}). Without this, a library cannot exploit this together
kono
parents:
diff changeset
234 with flat nesting.
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 @code{exceptionBlock} is not supported because exception blocks are not used.
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 @subsubsection [No changes] Windows exception state
kono
parents:
diff changeset
239 @subsubsection [No changes] Other machine state
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 @subsubsection [No changes] Results from beginTransaction
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 @subsection Aborting a transaction
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 @code{_ITM_rollbackTransaction} is not supported. @code{_ITM_abortTransaction}
kono
parents:
diff changeset
246 is supported but the abort reasons @code{exceptionBlockAbort},
kono
parents:
diff changeset
247 @code{TMConflict}, and @code{userRetry} are not supported. There are no
kono
parents:
diff changeset
248 exception blocks in general, so the related cases also do not have to be
kono
parents:
diff changeset
249 considered. To encode @code{__transaction_cancel [[outer]]}, compilers must
kono
parents:
diff changeset
250 set the new @code{outerAbort} bit (@code{0x10}) additionally to the
kono
parents:
diff changeset
251 @code{userAbort} bit in the abort reason.
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 @subsection Committing a transaction
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 The exception handling (EH) scheme is different. The Intel ABI requires the
kono
parents:
diff changeset
256 @code{_ITM_tryCommitTransaction} function that will return even when the
kono
parents:
diff changeset
257 commit failed and will have to be matched with calls to either
kono
parents:
diff changeset
258 @code{_ITM_abortTransaction} or @code{_ITM_commitTransaction}. In contrast,
kono
parents:
diff changeset
259 gcc relies on transactional wrappers for the functions of the Exception
kono
parents:
diff changeset
260 Handling ABI and on one additional commit function (shown below). This allows
kono
parents:
diff changeset
261 the TM to keep track of EH internally and thus it does not have to embed the
kono
parents:
diff changeset
262 cleanup of EH state into the existing EH code in the program.
kono
parents:
diff changeset
263 @code{_ITM_tryCommitTransaction} is not supported.
kono
parents:
diff changeset
264 @code{_ITM_commitTransactionToId} is also not supported because the
kono
parents:
diff changeset
265 propagation of thrown exceptions will not bypass commits of nested
kono
parents:
diff changeset
266 transactions.
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 @example
kono
parents:
diff changeset
269 void _ITM_commitTransactionEH(void *exc_ptr) ITM_REGPARM;
kono
parents:
diff changeset
270 void *_ITM_cxa_allocate_exception (size_t);
kono
parents:
diff changeset
271 void _ITM_cxa_free_exception (void *exc_ptr);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
272 void _ITM_cxa_throw (void *obj, void *tinfo, void (*dest) (void *));
111
kono
parents:
diff changeset
273 void *_ITM_cxa_begin_catch (void *exc_ptr);
kono
parents:
diff changeset
274 void _ITM_cxa_end_catch (void);
kono
parents:
diff changeset
275 @end example
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 The EH scheme changed in version 6 of GCC. Previously, the compiler
kono
parents:
diff changeset
278 added a call to @code{_ITM_commitTransactionEH} to commit a transaction if
kono
parents:
diff changeset
279 an exception could be in flight at this position in the code; @code{exc_ptr} is
kono
parents:
diff changeset
280 the address of the current exception and must be non-zero. Now, the
kono
parents:
diff changeset
281 compiler must catch all exceptions that are about to be thrown out of a
kono
parents:
diff changeset
282 transaction and call @code{_ITM_commitTransactionEH} from the catch clause,
kono
parents:
diff changeset
283 with @code{exc_ptr} being zero.
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 Note that the old EH scheme never worked completely in GCC's implementation;
kono
parents:
diff changeset
286 libitm currently does not try to be compatible with the old scheme.
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 The @code{_ITM_cxa...} functions are transactional wrappers for the respective
kono
parents:
diff changeset
289 @code{__cxa...} functions and must be called instead of these in transactional
kono
parents:
diff changeset
290 code. @code{_ITM_cxa_free_exception} is new in GCC 6.
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 To support this EH scheme, libstdc++ needs to provide one additional function
kono
parents:
diff changeset
293 (@code{_cxa_tm_cleanup}), which is used by the TM to clean up the exception
kono
parents:
diff changeset
294 handling state while rolling back a transaction:
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 @example
kono
parents:
diff changeset
297 void __cxa_tm_cleanup (void *unthrown_obj, void *cleanup_exc,
kono
parents:
diff changeset
298 unsigned int caught_count);
kono
parents:
diff changeset
299 @end example
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 Since GCC 6, @code{unthrown_obj} is not used anymore and always null;
kono
parents:
diff changeset
302 prior to that, @code{unthrown_obj} is non-null if the program called
kono
parents:
diff changeset
303 @code{__cxa_allocate_exception} for this exception but did not yet called
kono
parents:
diff changeset
304 @code{__cxa_throw} for it. @code{cleanup_exc} is non-null if the program is
kono
parents:
diff changeset
305 currently processing a cleanup along an exception path but has not caught this
kono
parents:
diff changeset
306 exception yet. @code{caught_count} is the nesting depth of
kono
parents:
diff changeset
307 @code{__cxa_begin_catch} within the transaction (which can be counted by the TM
kono
parents:
diff changeset
308 using @code{_ITM_cxa_begin_catch} and @code{_ITM_cxa_end_catch});
kono
parents:
diff changeset
309 @code{__cxa_tm_cleanup} then performs rollback by essentially performing
kono
parents:
diff changeset
310 @code{__cxa_end_catch} that many times.
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 @subsection Exception handling support
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 Currently, there is no support for functionality like
kono
parents:
diff changeset
317 @code{__transaction_cancel throw} as described in the C++ TM specification.
kono
parents:
diff changeset
318 Supporting this should be possible with the EH scheme explained previously
kono
parents:
diff changeset
319 because via the transactional wrappers for the EH ABI, the TM is able to
kono
parents:
diff changeset
320 observe and intercept EH.
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 @subsection [No changes] Transition to serial--irrevocable mode
kono
parents:
diff changeset
324 @subsection [No changes] Data transfer functions
kono
parents:
diff changeset
325 @subsection [No changes] Transactional memory copies
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 @subsection Transactional versions of memmove
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 If either the source or destination memory region is to be accessed
kono
parents:
diff changeset
330 nontransactionally, then source and destination regions must not be
kono
parents:
diff changeset
331 overlapping. The respective @code{_ITM_memmove} functions are still
kono
parents:
diff changeset
332 available but a fatal runtime error will be raised if such regions do overlap.
kono
parents:
diff changeset
333 To support this functionality, the ABI would have to specify how the
kono
parents:
diff changeset
334 intersection of the regions has to be accessed (i.e., transactionally or
kono
parents:
diff changeset
335 nontransactionally).
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 @subsection [No changes] Transactional versions of memset
kono
parents:
diff changeset
338 @subsection [No changes] Logging functions
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 @subsection User-registered commit and undo actions
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 Commit actions will get executed in the same order in which the respective
kono
parents:
diff changeset
343 calls to @code{_ITM_addUserCommitAction} happened. Only
kono
parents:
diff changeset
344 @code{_ITM_noTransactionId} is allowed as value for the
kono
parents:
diff changeset
345 @code{resumingTransactionId} argument. Commit actions get executed after
kono
parents:
diff changeset
346 privatization safety has been ensured.
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 Undo actions will get executed in reverse order compared to the order in which
kono
parents:
diff changeset
349 the respective calls to @code{_ITM_addUserUndoAction} happened. The ordering of
kono
parents:
diff changeset
350 undo actions w.r.t. the roll-back of other actions (e.g., data transfers or
kono
parents:
diff changeset
351 memory allocations) is undefined.
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 @code{_ITM_getThreadnum} is not supported currently because its only purpose
kono
parents:
diff changeset
354 is to provide a thread ID that matches some assumed performance tuning output,
kono
parents:
diff changeset
355 but this output is not part of the ABI nor further defined by it.
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 @code{_ITM_dropReferences} is not supported currently because its semantics and
kono
parents:
diff changeset
358 the intention behind it is not entirely clear. The
kono
parents:
diff changeset
359 specification suggests that this function is necessary because of certain
kono
parents:
diff changeset
360 orderings of data transfer undos and the releasing of memory regions (i.e.,
kono
parents:
diff changeset
361 privatization). However, this ordering is never defined, nor is the ordering of
kono
parents:
diff changeset
362 dropping references w.r.t. other events.
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 @subsection [New] Transactional indirect calls
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 Indirect calls (i.e., calls through a function pointer) within transactions
kono
parents:
diff changeset
367 should execute the transactional clone of the original function (i.e., a clone
kono
parents:
diff changeset
368 of the original that has been fully instrumented to use the TM runtime), if
kono
parents:
diff changeset
369 such a clone is available. The runtime provides two functions to
kono
parents:
diff changeset
370 register/deregister clone tables:
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 @example
kono
parents:
diff changeset
373 struct clone_entry
kono
parents:
diff changeset
374 @{
kono
parents:
diff changeset
375 void *orig, *clone;
kono
parents:
diff changeset
376 @};
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 void _ITM_registerTMCloneTable (clone_entry *table, size_t entries);
kono
parents:
diff changeset
379 void _ITM_deregisterTMCloneTable (clone_entry *table);
kono
parents:
diff changeset
380 @end example
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 Registered tables must be writable by the TM runtime, and must be live
kono
parents:
diff changeset
383 throughout the life-time of the TM runtime.
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 @strong{TODO} The intention was always to drop the registration functions
kono
parents:
diff changeset
386 entirely, and create a new ELF Phdr describing the linker-sorted table. Much
kono
parents:
diff changeset
387 like what currently happens for @code{PT_GNU_EH_FRAME}.
kono
parents:
diff changeset
388 This work kept getting bogged down in how to represent the @var{N} different
kono
parents:
diff changeset
389 code generation variants. We clearly needed at least two---SW and HW
kono
parents:
diff changeset
390 transactional clones---but there was always a suggestion of more variants for
kono
parents:
diff changeset
391 different TM assumptions/invariants.
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 The compiler can then use two TM runtime functions to perform indirect calls in
kono
parents:
diff changeset
394 transactions:
kono
parents:
diff changeset
395 @example
kono
parents:
diff changeset
396 void *_ITM_getTMCloneOrIrrevocable (void *function) ITM_REGPARM;
kono
parents:
diff changeset
397 void *_ITM_getTMCloneSafe (void *function) ITM_REGPARM;
kono
parents:
diff changeset
398 @end example
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 If there is a registered clone for supplied function, both will return a
kono
parents:
diff changeset
401 pointer to the clone. If not, the first runtime function will attempt to switch
kono
parents:
diff changeset
402 to serial--irrevocable mode and return the original pointer, whereas the second
kono
parents:
diff changeset
403 will raise a fatal runtime error.
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 @subsection [New] Transactional dynamic memory management
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 @example
kono
parents:
diff changeset
408 void *_ITM_malloc (size_t)
kono
parents:
diff changeset
409 __attribute__((__malloc__)) ITM_PURE;
kono
parents:
diff changeset
410 void *_ITM_calloc (size_t, size_t)
kono
parents:
diff changeset
411 __attribute__((__malloc__)) ITM_PURE;
kono
parents:
diff changeset
412 void _ITM_free (void *) ITM_PURE;
kono
parents:
diff changeset
413 @end example
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 These functions are essentially transactional wrappers for @code{malloc},
kono
parents:
diff changeset
416 @code{calloc}, and @code{free}. Within transactions, the compiler should
kono
parents:
diff changeset
417 replace calls to the original functions with calls to the wrapper functions.
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 libitm also provides transactional clones of C++ memory management functions
kono
parents:
diff changeset
420 such as global operator new and delete. They are part of libitm for historic
kono
parents:
diff changeset
421 reasons but do not need to be part of this ABI.
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 @section [No changes] Future Enhancements to the ABI
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 @section Sample code
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 The code examples might not be correct w.r.t. the current version of the ABI,
kono
parents:
diff changeset
429 especially everything related to exception handling.
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 @section [New] Memory model
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 The ABI should define a memory model and the ordering that is guaranteed for
kono
parents:
diff changeset
435 data transfers and commit/undo actions, or at least refer to another memory
kono
parents:
diff changeset
436 model that needs to be preserved. Without that, the compiler cannot ensure the
kono
parents:
diff changeset
437 memory model specified on the level of the programming language (e.g., by the
kono
parents:
diff changeset
438 C++ TM specification).
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 For example, if a transactional load is ordered before another load/store, then
kono
parents:
diff changeset
441 the TM runtime must also ensure this ordering when accessing shared state. If
kono
parents:
diff changeset
442 not, this might break the kind of publication safety used in the C++ TM
kono
parents:
diff changeset
443 specification. Likewise, the TM runtime must ensure privatization safety.
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
448 @c Internals
kono
parents:
diff changeset
449 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 @node Internals
kono
parents:
diff changeset
452 @chapter Internals
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 @section TM methods and method groups
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 libitm supports several ways of synchronizing transactions with each other.
kono
parents:
diff changeset
457 These TM methods (or TM algorithms) are implemented in the form of
kono
parents:
diff changeset
458 subclasses of @code{abi_dispatch}, which provide methods for
kono
parents:
diff changeset
459 transactional loads and stores as well as callbacks for rollback and commit.
kono
parents:
diff changeset
460 All methods that are compatible with each other (i.e., that let concurrently
kono
parents:
diff changeset
461 running transactions still synchronize correctly even if different methods
kono
parents:
diff changeset
462 are used) belong to the same TM method group. Pointers to TM methods can be
kono
parents:
diff changeset
463 obtained using the factory methods prefixed with @code{dispatch_} in
kono
parents:
diff changeset
464 @file{libitm_i.h}. There are two special methods, @code{dispatch_serial} and
kono
parents:
diff changeset
465 @code{dispatch_serialirr}, that are compatible with all methods because they
kono
parents:
diff changeset
466 run transactions completely in serial mode.
kono
parents:
diff changeset
467
kono
parents:
diff changeset
468 @subsection TM method life cycle
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 The state of TM methods does not change after construction, but they do alter
kono
parents:
diff changeset
471 the state of transactions that use this method. However, because
kono
parents:
diff changeset
472 per-transaction data gets used by several methods, @code{gtm_thread} is
kono
parents:
diff changeset
473 responsible for setting an initial state that is useful for all methods.
kono
parents:
diff changeset
474 After that, methods are responsible for resetting/clearing this state on each
kono
parents:
diff changeset
475 rollback or commit (of outermost transactions), so that the transaction
kono
parents:
diff changeset
476 executed next is not affected by the previous transaction.
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 There is also global state associated with each method group, which is
kono
parents:
diff changeset
479 initialized and shut down (@code{method_group::init()} and @code{fini()})
kono
parents:
diff changeset
480 when switching between method groups (see @file{retry.cc}).
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 @subsection Selecting the default method
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 The default method that libitm uses for freshly started transactions (but
kono
parents:
diff changeset
485 not necessarily for restarted transactions) can be set via an environment
kono
parents:
diff changeset
486 variable (@env{ITM_DEFAULT_METHOD}), whose value should be equal to the name
kono
parents:
diff changeset
487 of one of the factory methods returning abi_dispatch subclasses but without
kono
parents:
diff changeset
488 the "dispatch_" prefix (e.g., "serialirr" instead of
kono
parents:
diff changeset
489 @code{GTM::dispatch_serialirr()}).
kono
parents:
diff changeset
490
kono
parents:
diff changeset
491 Note that this environment variable is only a hint for libitm and might not
kono
parents:
diff changeset
492 be supported in the future.
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 @section Nesting: flat vs. closed
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 We support two different kinds of nesting of transactions. In the case of
kono
parents:
diff changeset
498 @emph{flat nesting}, the nesting structure is flattened and all nested
kono
parents:
diff changeset
499 transactions are subsumed by the enclosing transaction. In contrast,
kono
parents:
diff changeset
500 with @emph{closed nesting}, nested transactions that have not yet committed
kono
parents:
diff changeset
501 can be rolled back separately from the enclosing transactions; when they
kono
parents:
diff changeset
502 commit, they are subsumed by the enclosing transaction, and their effects
kono
parents:
diff changeset
503 will be finally committed when the outermost transaction commits.
kono
parents:
diff changeset
504 @emph{Open nesting} (where nested transactions can commit independently of the
kono
parents:
diff changeset
505 enclosing transactions) are not supported.
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 Flat nesting is the default nesting mode, but closed nesting is supported and
kono
parents:
diff changeset
508 used when transactions contain user-controlled aborts
kono
parents:
diff changeset
509 (@code{__transaction_cancel} statements). We assume that user-controlled
kono
parents:
diff changeset
510 aborts are rare in typical code and used mostly in exceptional situations.
kono
parents:
diff changeset
511 Thus, it makes more sense to use flat nesting by default to avoid the
kono
parents:
diff changeset
512 performance overhead of the additional checkpoints required for closed
kono
parents:
diff changeset
513 nesting. User-controlled aborts will correctly abort the innermost enclosing
kono
parents:
diff changeset
514 transaction, whereas the whole (i.e., outermost) transaction will be restarted
kono
parents:
diff changeset
515 otherwise (e.g., when a transaction encounters data conflicts during
kono
parents:
diff changeset
516 optimistic execution).
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 @section Locking conventions
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 This section documents the locking scheme and rules for all uses of locking
kono
parents:
diff changeset
522 in libitm. We have to support serial(-irrevocable) mode, which is implemented
kono
parents:
diff changeset
523 using a global lock as explained next (called the @emph{serial lock}). To
kono
parents:
diff changeset
524 simplify the overall design, we use the same lock as catch-all locking
kono
parents:
diff changeset
525 mechanism for other infrequent tasks such as (de)registering clone tables or
kono
parents:
diff changeset
526 threads. Besides the serial lock, there are @emph{per-method-group locks} that
kono
parents:
diff changeset
527 are managed by specific method groups (i.e., groups of similar TM concurrency
kono
parents:
diff changeset
528 control algorithms), and lock-like constructs for quiescence-based operations
kono
parents:
diff changeset
529 such as ensuring privatization safety.
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 Thus, the actions that participate in the libitm-internal locking are either
kono
parents:
diff changeset
532 @emph{active transactions} that do not run in serial mode, @emph{serial
kono
parents:
diff changeset
533 transactions} (which (are about to) run in serial mode), and management tasks
kono
parents:
diff changeset
534 that do not execute within a transaction but have acquired the serial mode
kono
parents:
diff changeset
535 like a serial transaction would do (e.g., to be able to register threads with
kono
parents:
diff changeset
536 libitm). Transactions become active as soon as they have successfully used the
kono
parents:
diff changeset
537 serial lock to announce this globally (@pxref{serial-lock-impl,,Serial lock
kono
parents:
diff changeset
538 implementation}). Likewise, transactions become serial transactions as soon as
kono
parents:
diff changeset
539 they have acquired the exclusive rights provided by the serial lock (i.e.,
kono
parents:
diff changeset
540 serial mode, which also means that there are no other concurrent active or
kono
parents:
diff changeset
541 serial transactions). Note that active transactions can become serial
kono
parents:
diff changeset
542 transactions when they enter serial mode during the runtime of the
kono
parents:
diff changeset
543 transaction.
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 @subsection State-to-lock mapping
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 Application data is protected by the serial lock if there is a serial
kono
parents:
diff changeset
548 transaction and no concurrently running active transaction (i.e., non-serial).
kono
parents:
diff changeset
549 Otherwise, application data is protected by the currently selected method
kono
parents:
diff changeset
550 group, which might use per-method-group locks or other mechanisms. Also note
kono
parents:
diff changeset
551 that application data that is about to be privatized might not be allowed to be
kono
parents:
diff changeset
552 accessed by nontransactional code until privatization safety has been ensured;
kono
parents:
diff changeset
553 the details of this are handled by the current method group.
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 libitm-internal state is either protected by the serial lock or accessed
kono
parents:
diff changeset
556 through custom concurrent code. The latter applies to the public/shared part
kono
parents:
diff changeset
557 of a transaction object and most typical method-group-specific state.
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 The former category (protected by the serial lock) includes:
kono
parents:
diff changeset
560 @itemize @bullet
kono
parents:
diff changeset
561 @item The list of active threads that have used transactions.
kono
parents:
diff changeset
562 @item The tables that map functions to their transactional clones.
kono
parents:
diff changeset
563 @item The current selection of which method group to use.
kono
parents:
diff changeset
564 @item Some method-group-specific data, or invariants of this data. For example,
kono
parents:
diff changeset
565 resetting a method group to its initial state is handled by switching to the
kono
parents:
diff changeset
566 same method group, so the serial lock protects such resetting as well.
kono
parents:
diff changeset
567 @end itemize
kono
parents:
diff changeset
568 In general, such state is immutable whenever there exists an active
kono
parents:
diff changeset
569 (non-serial) transaction. If there is no active transaction, a serial
kono
parents:
diff changeset
570 transaction (or a thread that is not currently executing a transaction but has
kono
parents:
diff changeset
571 acquired the serial lock) is allowed to modify this state (but must of course
kono
parents:
diff changeset
572 be careful to not surprise the current method group's implementation with such
kono
parents:
diff changeset
573 modifications).
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 @subsection Lock acquisition order
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 To prevent deadlocks, locks acquisition must happen in a globally agreed-upon
kono
parents:
diff changeset
578 order. Note that this applies to other forms of blocking too, but does not
kono
parents:
diff changeset
579 necessarily apply to lock acquisitions that do not block (e.g., trylock()
kono
parents:
diff changeset
580 calls that do not get retried forever). Note that serial transactions are
kono
parents:
diff changeset
581 never return back to active transactions until the transaction has committed.
kono
parents:
diff changeset
582 Likewise, active transactions stay active until they have committed.
kono
parents:
diff changeset
583 Per-method-group locks are typically also not released before commit.
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 Lock acquisition / blocking rules:
kono
parents:
diff changeset
586 @itemize @bullet
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 @item Transactions must become active or serial before they are allowed to
kono
parents:
diff changeset
589 use method-group-specific locks or blocking (i.e., the serial lock must be
kono
parents:
diff changeset
590 acquired before those other locks, either in serial or nonserial mode).
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 @item Any number of threads that do not currently run active transactions can
kono
parents:
diff changeset
593 block while trying to get the serial lock in exclusive mode. Note that active
kono
parents:
diff changeset
594 transactions must not block when trying to upgrade to serial mode unless there
kono
parents:
diff changeset
595 is no other transaction that is trying that (the latter is ensured by the
kono
parents:
diff changeset
596 serial lock implementation.
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 @item Method groups must prevent deadlocks on their locks. In particular, they
kono
parents:
diff changeset
599 must also be prepared for another active transaction that has acquired
kono
parents:
diff changeset
600 method-group-specific locks but is blocked during an attempt to upgrade to
kono
parents:
diff changeset
601 being a serial transaction. See below for details.
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 @item Serial transactions can acquire method-group-specific locks because there
kono
parents:
diff changeset
604 will be no other active nor serial transaction.
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 @end itemize
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 There is no single rule for per-method-group blocking because this depends on
kono
parents:
diff changeset
609 when a TM method might acquire locks. If no active transaction can upgrade to
kono
parents:
diff changeset
610 being a serial transaction after it has acquired per-method-group locks (e.g.,
kono
parents:
diff changeset
611 when those locks are only acquired during an attempt to commit), then the TM
kono
parents:
diff changeset
612 method does not need to consider a potential deadlock due to serial mode.
kono
parents:
diff changeset
613
kono
parents:
diff changeset
614 If there can be upgrades to serial mode after the acquisition of
kono
parents:
diff changeset
615 per-method-group locks, then TM methods need to avoid those deadlocks:
kono
parents:
diff changeset
616 @itemize @bullet
kono
parents:
diff changeset
617 @item When upgrading to a serial transaction, after acquiring exclusive rights
kono
parents:
diff changeset
618 to the serial lock but before waiting for concurrent active transactions to
kono
parents:
diff changeset
619 finish (@pxref{serial-lock-impl,,Serial lock implementation} for details),
kono
parents:
diff changeset
620 we have to wake up all active transactions waiting on the upgrader's
kono
parents:
diff changeset
621 per-method-group locks.
kono
parents:
diff changeset
622 @item Active transactions blocking on per-method-group locks need to check the
kono
parents:
diff changeset
623 serial lock and abort if there is a pending serial transaction.
kono
parents:
diff changeset
624 @item Lost wake-ups have to be prevented (e.g., by changing a bit in each
kono
parents:
diff changeset
625 per-method-group lock before doing the wake-up, and only blocking on this lock
kono
parents:
diff changeset
626 using a futex if this bit is not group).
kono
parents:
diff changeset
627 @end itemize
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 @strong{TODO}: Can reuse serial lock for gl-*? And if we can, does it make
kono
parents:
diff changeset
630 sense to introduce further complexity in the serial lock? For gl-*, we can
kono
parents:
diff changeset
631 really only avoid an abort if we do -wb and -vbv.
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 @subsection Serial lock implementation
kono
parents:
diff changeset
635 @anchor{serial-lock-impl}
kono
parents:
diff changeset
636
kono
parents:
diff changeset
637 The serial lock implementation is optimized towards assuming that serial
kono
parents:
diff changeset
638 transactions are infrequent and not the common case. However, the performance
kono
parents:
diff changeset
639 of entering serial mode can matter because when only few transactions are run
kono
parents:
diff changeset
640 concurrently or if there are few threads, then it can be efficient to run
kono
parents:
diff changeset
641 transactions serially.
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 The serial lock is similar to a multi-reader-single-writer lock in that there
kono
parents:
diff changeset
644 can be several active transactions but only one serial transaction. However,
kono
parents:
diff changeset
645 we do want to avoid contention (in the lock implementation) between active
kono
parents:
diff changeset
646 transactions, so we split up the reader side of the lock into per-transaction
kono
parents:
diff changeset
647 flags that are true iff the transaction is active. The exclusive writer side
kono
parents:
diff changeset
648 remains a shared single flag, which is acquired using a CAS, for example.
kono
parents:
diff changeset
649 On the fast-path, the serial lock then works similar to Dekker's algorithm but
kono
parents:
diff changeset
650 with several reader flags that a serial transaction would have to check.
kono
parents:
diff changeset
651 A serial transaction thus requires a list of all threads with potentially
kono
parents:
diff changeset
652 active transactions; we can use the serial lock itself to protect this list
kono
parents:
diff changeset
653 (i.e., only threads that have acquired the serial lock can modify this list).
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 We want starvation-freedom for the serial lock to allow for using it to ensure
kono
parents:
diff changeset
656 progress for potentially starved transactions (@pxref{progress-guarantees,,
kono
parents:
diff changeset
657 Progress Guarantees} for details). However, this is currently not enforced by
kono
parents:
diff changeset
658 the implementation of the serial lock.
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 Here is pseudo-code for the read/write fast paths of acquiring the serial
kono
parents:
diff changeset
661 lock (read-to-write upgrade is similar to write_lock:
kono
parents:
diff changeset
662 @example
kono
parents:
diff changeset
663 // read_lock:
kono
parents:
diff changeset
664 tx->shared_state |= active;
kono
parents:
diff changeset
665 __sync_synchronize(); // or STLD membar, or C++0x seq-cst fence
kono
parents:
diff changeset
666 while (!serial_lock.exclusive)
kono
parents:
diff changeset
667 if (spinning_for_too_long) goto slowpath;
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 // write_lock:
kono
parents:
diff changeset
670 if (CAS(&serial_lock.exclusive, 0, this) != 0)
kono
parents:
diff changeset
671 goto slowpath; // writer-writer contention
kono
parents:
diff changeset
672 // need a membar here, but CAS already has full membar semantics
kono
parents:
diff changeset
673 bool need_blocking = false;
kono
parents:
diff changeset
674 for (t: all txns)
kono
parents:
diff changeset
675 @{
kono
parents:
diff changeset
676 for (;t->shared_state & active;)
kono
parents:
diff changeset
677 if (spinning_for_too_long) @{ need_blocking = true; break; @}
kono
parents:
diff changeset
678 @}
kono
parents:
diff changeset
679 if (need_blocking) goto slowpath;
kono
parents:
diff changeset
680 @end example
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 Releasing a lock in this spin-lock version then just consists of resetting
kono
parents:
diff changeset
683 @code{tx->shared_state} to inactive or clearing @code{serial_lock.exclusive}.
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 However, we can't rely on a pure spinlock because we need to get the OS
kono
parents:
diff changeset
686 involved at some time (e.g., when there are more threads than CPUs to run on).
kono
parents:
diff changeset
687 Therefore, the real implementation falls back to a blocking slow path, either
kono
parents:
diff changeset
688 based on pthread mutexes or Linux futexes.
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 @subsection Reentrancy
kono
parents:
diff changeset
692
kono
parents:
diff changeset
693 libitm has to consider the following cases of reentrancy:
kono
parents:
diff changeset
694 @itemize @bullet
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 @item Transaction calls unsafe code that starts a new transaction: The outer
kono
parents:
diff changeset
697 transaction will become a serial transaction before executing unsafe code.
kono
parents:
diff changeset
698 Therefore, nesting within serial transactions must work, even if the nested
kono
parents:
diff changeset
699 transaction is called from within uninstrumented code.
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 @item Transaction calls either a transactional wrapper or safe code, which in
kono
parents:
diff changeset
702 turn starts a new transaction: It is not yet defined in the specification
kono
parents:
diff changeset
703 whether this is allowed. Thus, it is undefined whether libitm supports this.
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 @item Code that starts new transactions might be called from within any part
kono
parents:
diff changeset
706 of libitm: This kind of reentrancy would likely be rather complex and can
kono
parents:
diff changeset
707 probably be avoided. Therefore, it is not supported.
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 @end itemize
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 @subsection Privatization safety
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 Privatization safety is ensured by libitm using a quiescence-based approach.
kono
parents:
diff changeset
714 Basically, a privatizing transaction waits until all concurrent active
kono
parents:
diff changeset
715 transactions will either have finished (are not active anymore) or operate on
kono
parents:
diff changeset
716 a sufficiently recent snapshot to not access the privatized data anymore. This
kono
parents:
diff changeset
717 happens after the privatizing transaction has stopped being an active
kono
parents:
diff changeset
718 transaction, so waiting for quiescence does not contribute to deadlocks.
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 In method groups that need to ensure publication safety explicitly, active
kono
parents:
diff changeset
721 transactions maintain a flag or timestamp in the public/shared part of the
kono
parents:
diff changeset
722 transaction descriptor. Before blocking, privatizers need to let the other
kono
parents:
diff changeset
723 transactions know that they should wake up the privatizer.
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 @strong{TODO} Ho to implement the waiters? Should those flags be
kono
parents:
diff changeset
726 per-transaction or at a central place? We want to avoid one wake/wait call
kono
parents:
diff changeset
727 per active transactions, so we might want to use either a tree or combining
kono
parents:
diff changeset
728 to reduce the syscall overhead, or rather spin for a long amount of time
kono
parents:
diff changeset
729 instead of doing blocking. Also, it would be good if only the last transaction
kono
parents:
diff changeset
730 that the privatizer waits for would do the wake-up.
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 @subsection Progress guarantees
kono
parents:
diff changeset
733 @anchor{progress-guarantees}
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 Transactions that do not make progress when using the current TM method will
kono
parents:
diff changeset
736 eventually try to execute in serial mode. Thus, the serial lock's progress
kono
parents:
diff changeset
737 guarantees determine the progress guarantees of the whole TM. Obviously, we at
kono
parents:
diff changeset
738 least need deadlock-freedom for the serial lock, but it would also be good to
kono
parents:
diff changeset
739 provide starvation-freedom (informally, all threads will finish executing a
kono
parents:
diff changeset
740 transaction eventually iff they get enough cycles).
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 However, the scheduling of transactions (e.g., thread scheduling by the OS)
kono
parents:
diff changeset
743 also affects the handling of progress guarantees by the TM. First, the TM
kono
parents:
diff changeset
744 can only guarantee deadlock-freedom if threads do not get stopped. Likewise,
kono
parents:
diff changeset
745 low-priority threads can starve if they do not get scheduled when other
kono
parents:
diff changeset
746 high-priority threads get those cycles instead.
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 If all threads get scheduled eventually, correct lock implementations will
kono
parents:
diff changeset
749 provide deadlock-freedom, but might not provide starvation-freedom. We can
kono
parents:
diff changeset
750 either enforce the latter in the TM's lock implementation, or assume that
kono
parents:
diff changeset
751 the scheduling is sufficiently random to yield a probabilistic guarantee that
kono
parents:
diff changeset
752 no thread will starve (because eventually, a transaction will encounter a
kono
parents:
diff changeset
753 scheduling that will allow it to run). This can indeed work well in practice
kono
parents:
diff changeset
754 but is not necessarily guaranteed to work (e.g., simple spin locks can be
kono
parents:
diff changeset
755 pretty efficient).
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 Because enforcing stronger progress guarantees in the TM has a higher runtime
kono
parents:
diff changeset
758 overhead, we focus on deadlock-freedom right now and assume that the threads
kono
parents:
diff changeset
759 will get scheduled eventually by the OS (but don't consider threads with
kono
parents:
diff changeset
760 different priorities). We should support starvation-freedom for serial
kono
parents:
diff changeset
761 transactions in the future. Everything beyond that is highly related to proper
kono
parents:
diff changeset
762 contention management across all of the TM (including with TM method to
kono
parents:
diff changeset
763 choose), and is future work.
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 @strong{TODO} Handling thread priorities: We want to avoid priority inversion
kono
parents:
diff changeset
766 but it's unclear how often that actually matters in practice. Workloads that
kono
parents:
diff changeset
767 have threads with different priorities will likely also require lower latency
kono
parents:
diff changeset
768 or higher throughput for high-priority threads. Therefore, it probably makes
kono
parents:
diff changeset
769 not that much sense (except for eventual progress guarantees) to use
kono
parents:
diff changeset
770 priority inheritance until the TM has priority-aware contention management.
kono
parents:
diff changeset
771
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
774 @c GNU Free Documentation License
kono
parents:
diff changeset
775 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 @include fdl.texi
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
780 @c Index
kono
parents:
diff changeset
781 @c ---------------------------------------------------------------------
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 @node Library Index
kono
parents:
diff changeset
784 @unnumbered Library Index
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 @printindex cp
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 @bye