]> git.ipfire.org Git - thirdparty/gcc.git/blob - libitm/libitm_i.h
libitm: Filter out undo writes that overlap with the libitm stack.
[thirdparty/gcc.git] / libitm / libitm_i.h
1 /* Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
2 Contributed by Richard Henderson <rth@redhat.com>.
3
4 This file is part of the GNU Transactional Memory Library (libitm).
5
6 Libitm is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 Libitm is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
24
25 /* The following are internal implementation functions and definitions.
26 To distinguish them from those defined by the Intel ABI, they all
27 begin with GTM/gtm. */
28
29 #ifndef LIBITM_I_H
30 #define LIBITM_I_H 1
31
32 #include "libitm.h"
33 #include "config.h"
34
35 #include <assert.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unwind.h>
39 #include "local_type_traits"
40 #include "local_atomic"
41
42 /* Don't require libgcc_s.so for exceptions. */
43 extern void _Unwind_DeleteException (_Unwind_Exception*) __attribute__((weak));
44
45
46 #include "common.h"
47
48 namespace GTM HIDDEN {
49
50 using namespace std;
51
52 // A helper template for accessing an unsigned integral of SIZE bytes.
53 template<size_t SIZE> struct sized_integral { };
54 template<> struct sized_integral<1> { typedef uint8_t type; };
55 template<> struct sized_integral<2> { typedef uint16_t type; };
56 template<> struct sized_integral<4> { typedef uint32_t type; };
57 template<> struct sized_integral<8> { typedef uint64_t type; };
58
59 typedef unsigned int gtm_word __attribute__((mode (word)));
60
61 // These values are given to GTM_restart_transaction and indicate the
62 // reason for the restart. The reason is used to decide what STM
63 // implementation should be used during the next iteration.
64 enum gtm_restart_reason
65 {
66 RESTART_REALLOCATE,
67 RESTART_LOCKED_READ,
68 RESTART_LOCKED_WRITE,
69 RESTART_VALIDATE_READ,
70 RESTART_VALIDATE_WRITE,
71 RESTART_VALIDATE_COMMIT,
72 RESTART_SERIAL_IRR,
73 RESTART_NOT_READONLY,
74 RESTART_CLOSED_NESTING,
75 RESTART_INIT_METHOD_GROUP,
76 NUM_RESTARTS,
77 NO_RESTART = NUM_RESTARTS
78 };
79
80 } // namespace GTM
81
82 #include "target.h"
83 #include "rwlock.h"
84 #include "aatree.h"
85 #include "cacheline.h"
86 #include "stmlock.h"
87 #include "dispatch.h"
88 #include "containers.h"
89
90 namespace GTM HIDDEN {
91
92 // This type is private to alloc.c, but needs to be defined so that
93 // the template used inside gtm_thread can instantiate.
94 struct gtm_alloc_action
95 {
96 void (*free_fn)(void *);
97 bool allocated;
98 };
99
100 struct gtm_thread;
101
102 // A transaction checkpoint: data that has to saved and restored when doing
103 // closed nesting.
104 struct gtm_transaction_cp
105 {
106 gtm_jmpbuf jb;
107 size_t undolog_size;
108 aa_tree<uintptr_t, gtm_alloc_action> alloc_actions;
109 size_t user_actions_size;
110 _ITM_transactionId_t id;
111 uint32_t prop;
112 uint32_t cxa_catch_count;
113 void *cxa_unthrown;
114 // We might want to use a different but compatible dispatch method for
115 // a nested transaction.
116 abi_dispatch *disp;
117 // Nesting level of this checkpoint (1 means that this is a checkpoint of
118 // the outermost transaction).
119 uint32_t nesting;
120
121 void save(gtm_thread* tx);
122 void commit(gtm_thread* tx);
123 };
124
125 // An undo log for writes.
126 struct gtm_undolog
127 {
128 vector<gtm_word> undolog;
129
130 // Log the previous value at a certain address.
131 // The easiest way to inline this is to just define this here.
132 void log(const void *ptr, size_t len)
133 {
134 size_t words = (len + sizeof(gtm_word) - 1) / sizeof(gtm_word);
135 gtm_word *undo = undolog.push(words + 2);
136 memcpy(undo, ptr, len);
137 undo[words] = len;
138 undo[words + 1] = (gtm_word) ptr;
139 }
140
141 void commit () { undolog.clear(); }
142 size_t size() const { return undolog.size(); }
143
144 // In local.cc
145 void rollback (gtm_thread* tx, size_t until_size = 0);
146 };
147
148 // Contains all thread-specific data required by the entire library.
149 // This includes all data relevant to a single transaction. Because most
150 // thread-specific data is about the current transaction, we also refer to
151 // the transaction-specific parts of gtm_thread as "the transaction" (the
152 // same applies to names of variables and arguments).
153 // All but the shared part of this data structure are thread-local data.
154 // gtm_thread could be split into transaction-specific structures and other
155 // per-thread data (with those parts then nested in gtm_thread), but this
156 // would make it harder to later rearrange individual members to optimize data
157 // accesses. Thus, for now we keep one flat object, and will only split it if
158 // the code gets too messy.
159 struct gtm_thread
160 {
161
162 struct user_action
163 {
164 _ITM_userCommitFunction fn;
165 void *arg;
166 bool on_commit;
167 _ITM_transactionId_t resuming_id;
168 };
169
170 // The jump buffer by which GTM_longjmp restarts the transaction.
171 // This field *must* be at the beginning of the transaction.
172 gtm_jmpbuf jb;
173
174 // Data used by local.c for the undo log for both local and shared memory.
175 gtm_undolog undolog;
176
177 // Data used by alloc.c for the malloc/free undo log.
178 aa_tree<uintptr_t, gtm_alloc_action> alloc_actions;
179
180 // Data used by useraction.c for the user-defined commit/abort handlers.
181 vector<user_action> user_actions;
182
183 // A numerical identifier for this transaction.
184 _ITM_transactionId_t id;
185
186 // The _ITM_codeProperties of this transaction as given by the compiler.
187 uint32_t prop;
188
189 // The nesting depth for subsequently started transactions. This variable
190 // will be set to 1 when starting an outermost transaction.
191 uint32_t nesting;
192
193 // Set if this transaction owns the serial write lock.
194 // Can be reset only when restarting the outermost transaction.
195 static const uint32_t STATE_SERIAL = 0x0001;
196 // Set if the serial-irrevocable dispatch table is installed.
197 // Implies that no logging is being done, and abort is not possible.
198 // Can be reset only when restarting the outermost transaction.
199 static const uint32_t STATE_IRREVOCABLE = 0x0002;
200
201 // A bitmask of the above.
202 uint32_t state;
203
204 // In order to reduce cacheline contention on global_tid during
205 // beginTransaction, we allocate a block of 2**N ids to the thread
206 // all at once. This number is the next value to be allocated from
207 // the block, or 0 % 2**N if no such block is allocated.
208 _ITM_transactionId_t local_tid;
209
210 // Data used by eh_cpp.c for managing exceptions within the transaction.
211 uint32_t cxa_catch_count;
212 void *cxa_unthrown;
213 void *eh_in_flight;
214
215 // Checkpoints for closed nesting.
216 vector<gtm_transaction_cp> parent_txns;
217
218 // Data used by retry.c for deciding what STM implementation should
219 // be used for the next iteration of the transaction.
220 // Only restart_total is reset to zero when the transaction commits, the
221 // other counters are total values for all previously executed transactions.
222 uint32_t restart_reason[NUM_RESTARTS];
223 uint32_t restart_total;
224
225 // *** The shared part of gtm_thread starts here. ***
226 // Shared state is on separate cachelines to avoid false sharing with
227 // thread-local parts of gtm_thread.
228
229 // Points to the next thread in the list of all threads.
230 gtm_thread *next_thread __attribute__((__aligned__(HW_CACHELINE_SIZE)));
231
232 // If this transaction is inactive, shared_state is ~0. Otherwise, this is
233 // an active or serial transaction.
234 atomic<gtm_word> shared_state;
235
236 // The lock that provides access to serial mode. Non-serialized
237 // transactions acquire read locks; a serialized transaction aquires
238 // a write lock.
239 static gtm_rwlock serial_lock;
240
241 // The head of the list of all threads' transactions.
242 static gtm_thread *list_of_threads;
243 // The number of all registered threads.
244 static unsigned number_of_threads;
245
246 // In alloc.cc
247 void commit_allocations (bool, aa_tree<uintptr_t, gtm_alloc_action>*);
248 void record_allocation (void *, void (*)(void *));
249 void forget_allocation (void *, void (*)(void *));
250 void drop_references_allocations (const void *ptr)
251 {
252 this->alloc_actions.erase((uintptr_t) ptr);
253 }
254
255 // In beginend.cc
256 void rollback (gtm_transaction_cp *cp = 0, bool aborting = false);
257 bool trycommit ();
258 void restart (gtm_restart_reason, bool finish_serial_upgrade = false)
259 ITM_NORETURN;
260
261 gtm_thread();
262 ~gtm_thread();
263
264 static void *operator new(size_t);
265 static void operator delete(void *);
266
267 // Invoked from assembly language, thus the "asm" specifier on
268 // the name, avoiding complex name mangling.
269 #ifdef __USER_LABEL_PREFIX__
270 #define UPFX1(t) UPFX(t)
271 #define UPFX(t) #t
272 static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
273 __asm__(UPFX1(__USER_LABEL_PREFIX__) "GTM_begin_transaction") ITM_REGPARM;
274 #else
275 static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
276 __asm__("GTM_begin_transaction") ITM_REGPARM;
277 #endif
278 // In eh_cpp.cc
279 void revert_cpp_exceptions (gtm_transaction_cp *cp = 0);
280
281 // In retry.cc
282 // Must be called outside of transactions (i.e., after rollback).
283 void decide_retry_strategy (gtm_restart_reason);
284 abi_dispatch* decide_begin_dispatch (uint32_t prop);
285 void number_of_threads_changed(unsigned previous, unsigned now);
286 // Must be called from serial mode. Does not call set_abi_disp().
287 void set_default_dispatch(abi_dispatch* disp);
288
289 // In method-serial.cc
290 void serialirr_mode ();
291
292 // In useraction.cc
293 void rollback_user_actions (size_t until_size = 0);
294 void commit_user_actions ();
295 };
296
297 } // namespace GTM
298
299 #include "tls.h"
300
301 namespace GTM HIDDEN {
302
303 // An unscaled count of the number of times we should spin attempting to
304 // acquire locks before we block the current thread and defer to the OS.
305 // This variable isn't used when the standard POSIX lock implementations
306 // are used.
307 extern uint64_t gtm_spin_count_var;
308
309 extern "C" uint32_t GTM_longjmp (uint32_t, const gtm_jmpbuf *, uint32_t)
310 ITM_NORETURN ITM_REGPARM;
311
312 extern "C" void GTM_LB (const void *, size_t) ITM_REGPARM;
313
314 extern void GTM_error (const char *fmt, ...)
315 __attribute__((format (printf, 1, 2)));
316 extern void GTM_fatal (const char *fmt, ...)
317 __attribute__((noreturn, format (printf, 1, 2)));
318
319 extern abi_dispatch *dispatch_serial();
320 extern abi_dispatch *dispatch_serialirr();
321 extern abi_dispatch *dispatch_serialirr_onwrite();
322 extern abi_dispatch *dispatch_gl_wt();
323
324 extern gtm_cacheline_mask gtm_mask_stack(gtm_cacheline *, gtm_cacheline_mask);
325
326 } // namespace GTM
327
328 #endif // LIBITM_I_H