OSDN Git Service

libitm: Optimize synchronization in gl_wt rollback.
[pf3gnuchains/gcc-fork.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 // An entry of a read or write log.  Used by multi-lock TM methods.
149 struct gtm_rwlog_entry
150 {
151   atomic<gtm_word> *orec;
152   gtm_word value;
153 };
154
155 // Contains all thread-specific data required by the entire library.
156 // This includes all data relevant to a single transaction. Because most
157 // thread-specific data is about the current transaction, we also refer to
158 // the transaction-specific parts of gtm_thread as "the transaction" (the
159 // same applies to names of variables and arguments).
160 // All but the shared part of this data structure are thread-local data.
161 // gtm_thread could be split into transaction-specific structures and other
162 // per-thread data (with those parts then nested in gtm_thread), but this
163 // would make it harder to later rearrange individual members to optimize data
164 // accesses. Thus, for now we keep one flat object, and will only split it if
165 // the code gets too messy.
166 struct gtm_thread
167 {
168
169   struct user_action
170   {
171     _ITM_userCommitFunction fn;
172     void *arg;
173     bool on_commit;
174     _ITM_transactionId_t resuming_id;
175   };
176
177   // The jump buffer by which GTM_longjmp restarts the transaction.
178   // This field *must* be at the beginning of the transaction.
179   gtm_jmpbuf jb;
180
181   // Data used by local.c for the undo log for both local and shared memory.
182   gtm_undolog undolog;
183
184   // Read and write logs.  Used by multi-lock TM methods.
185   vector<gtm_rwlog_entry> readlog;
186   vector<gtm_rwlog_entry> writelog;
187
188   // Data used by alloc.c for the malloc/free undo log.
189   aa_tree<uintptr_t, gtm_alloc_action> alloc_actions;
190
191   // Data used by useraction.c for the user-defined commit/abort handlers.
192   vector<user_action> user_actions;
193
194   // A numerical identifier for this transaction.
195   _ITM_transactionId_t id;
196
197   // The _ITM_codeProperties of this transaction as given by the compiler.
198   uint32_t prop;
199
200   // The nesting depth for subsequently started transactions. This variable
201   // will be set to 1 when starting an outermost transaction.
202   uint32_t nesting;
203
204   // Set if this transaction owns the serial write lock.
205   // Can be reset only when restarting the outermost transaction.
206   static const uint32_t STATE_SERIAL            = 0x0001;
207   // Set if the serial-irrevocable dispatch table is installed.
208   // Implies that no logging is being done, and abort is not possible.
209   // Can be reset only when restarting the outermost transaction.
210   static const uint32_t STATE_IRREVOCABLE       = 0x0002;
211
212   // A bitmask of the above.
213   uint32_t state;
214
215   // In order to reduce cacheline contention on global_tid during
216   // beginTransaction, we allocate a block of 2**N ids to the thread
217   // all at once.  This number is the next value to be allocated from
218   // the block, or 0 % 2**N if no such block is allocated.
219   _ITM_transactionId_t local_tid;
220
221   // Data used by eh_cpp.c for managing exceptions within the transaction.
222   uint32_t cxa_catch_count;
223   void *cxa_unthrown;
224   void *eh_in_flight;
225
226   // Checkpoints for closed nesting.
227   vector<gtm_transaction_cp> parent_txns;
228
229   // Data used by retry.c for deciding what STM implementation should
230   // be used for the next iteration of the transaction.
231   // Only restart_total is reset to zero when the transaction commits, the
232   // other counters are total values for all previously executed transactions.
233   uint32_t restart_reason[NUM_RESTARTS];
234   uint32_t restart_total;
235
236   // *** The shared part of gtm_thread starts here. ***
237   // Shared state is on separate cachelines to avoid false sharing with
238   // thread-local parts of gtm_thread.
239
240   // Points to the next thread in the list of all threads.
241   gtm_thread *next_thread __attribute__((__aligned__(HW_CACHELINE_SIZE)));
242
243   // If this transaction is inactive, shared_state is ~0. Otherwise, this is
244   // an active or serial transaction.
245   atomic<gtm_word> shared_state;
246
247   // The lock that provides access to serial mode.  Non-serialized
248   // transactions acquire read locks; a serialized transaction aquires
249   // a write lock.
250   static gtm_rwlock serial_lock;
251
252   // The head of the list of all threads' transactions.
253   static gtm_thread *list_of_threads;
254   // The number of all registered threads.
255   static unsigned number_of_threads;
256
257   // In alloc.cc
258   void commit_allocations (bool, aa_tree<uintptr_t, gtm_alloc_action>*);
259   void record_allocation (void *, void (*)(void *));
260   void forget_allocation (void *, void (*)(void *));
261   void drop_references_allocations (const void *ptr)
262   {
263     this->alloc_actions.erase((uintptr_t) ptr);
264   }
265
266   // In beginend.cc
267   void rollback (gtm_transaction_cp *cp = 0, bool aborting = false);
268   bool trycommit ();
269   void restart (gtm_restart_reason, bool finish_serial_upgrade = false)
270         ITM_NORETURN;
271
272   gtm_thread();
273   ~gtm_thread();
274
275   static void *operator new(size_t);
276   static void operator delete(void *);
277
278   // Invoked from assembly language, thus the "asm" specifier on
279   // the name, avoiding complex name mangling.
280 #ifdef __USER_LABEL_PREFIX__
281 #define UPFX1(t) UPFX(t)
282 #define UPFX(t) #t
283   static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
284         __asm__(UPFX1(__USER_LABEL_PREFIX__) "GTM_begin_transaction") ITM_REGPARM;
285 #else
286   static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
287         __asm__("GTM_begin_transaction") ITM_REGPARM;
288 #endif
289   // In eh_cpp.cc
290   void revert_cpp_exceptions (gtm_transaction_cp *cp = 0);
291
292   // In retry.cc
293   // Must be called outside of transactions (i.e., after rollback).
294   void decide_retry_strategy (gtm_restart_reason);
295   abi_dispatch* decide_begin_dispatch (uint32_t prop);
296   void number_of_threads_changed(unsigned previous, unsigned now);
297   // Must be called from serial mode. Does not call set_abi_disp().
298   void set_default_dispatch(abi_dispatch* disp);
299
300   // In method-serial.cc
301   void serialirr_mode ();
302
303   // In useraction.cc
304   void rollback_user_actions (size_t until_size = 0);
305   void commit_user_actions ();
306 };
307
308 } // namespace GTM
309
310 #include "tls.h"
311
312 namespace GTM HIDDEN {
313
314 // An unscaled count of the number of times we should spin attempting to
315 // acquire locks before we block the current thread and defer to the OS.
316 // This variable isn't used when the standard POSIX lock implementations
317 // are used.
318 extern uint64_t gtm_spin_count_var;
319
320 extern "C" uint32_t GTM_longjmp (uint32_t, const gtm_jmpbuf *, uint32_t)
321         ITM_NORETURN ITM_REGPARM;
322
323 extern "C" void GTM_LB (const void *, size_t) ITM_REGPARM;
324
325 extern void GTM_error (const char *fmt, ...)
326         __attribute__((format (printf, 1, 2)));
327 extern void GTM_fatal (const char *fmt, ...)
328         __attribute__((noreturn, format (printf, 1, 2)));
329
330 extern abi_dispatch *dispatch_serial();
331 extern abi_dispatch *dispatch_serialirr();
332 extern abi_dispatch *dispatch_serialirr_onwrite();
333 extern abi_dispatch *dispatch_gl_wt();
334 extern abi_dispatch *dispatch_ml_wt();
335
336 extern gtm_cacheline_mask gtm_mask_stack(gtm_cacheline *, gtm_cacheline_mask);
337
338 } // namespace GTM
339
340 #endif // LIBITM_I_H