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