OSDN Git Service

d57872ede7bef1c713fa7bb1676109603d3a7db2
[pf3gnuchains/gcc-fork.git] / libitm / libitm_i.h
1 /* Copyright (C) 2008, 2009, 2011 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 #include "common.h"
43
44 namespace GTM HIDDEN {
45
46 using namespace std;
47
48 // A helper template for accessing an unsigned integral of SIZE bytes.
49 template<size_t SIZE> struct sized_integral { };
50 template<> struct sized_integral<1> { typedef uint8_t type; };
51 template<> struct sized_integral<2> { typedef uint16_t type; };
52 template<> struct sized_integral<4> { typedef uint32_t type; };
53 template<> struct sized_integral<8> { typedef uint64_t type; };
54
55 typedef 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.
60 enum 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"
82 #include "stmlock.h"
83 #include "dispatch.h"
84 #include "containers.h"
85
86 namespace 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.
90 struct gtm_alloc_action
91 {
92   void (*free_fn)(void *);
93   bool allocated;
94 };
95
96 // This type is private to local.c.
97 struct gtm_undolog_entry;
98
99 struct gtm_thread;
100
101 // A transaction checkpoint: data that has to saved and restored when doing
102 // closed nesting.
103 struct gtm_transaction_cp
104 {
105   gtm_jmpbuf jb;
106   size_t undolog_size;
107   aa_tree<uintptr_t, gtm_alloc_action> alloc_actions;
108   size_t user_actions_size;
109   _ITM_transactionId_t id;
110   uint32_t prop;
111   uint32_t cxa_catch_count;
112   void *cxa_unthrown;
113   // We might want to use a different but compatible dispatch method for
114   // a nested transaction.
115   abi_dispatch *disp;
116   // Nesting level of this checkpoint (1 means that this is a checkpoint of
117   // the outermost transaction).
118   uint32_t nesting;
119
120   void save(gtm_thread* tx);
121   void commit(gtm_thread* tx);
122 };
123
124 // Contains all thread-specific data required by the entire library.
125 // This includes all data relevant to a single transaction. Because most
126 // thread-specific data is about the current transaction, we also refer to
127 // the transaction-specific parts of gtm_thread as "the transaction" (the
128 // same applies to names of variables and arguments).
129 // All but the shared part of this data structure are thread-local data.
130 // gtm_thread could be split into transaction-specific structures and other
131 // per-thread data (with those parts then nested in gtm_thread), but this
132 // would make it harder to later rearrange individual members to optimize data
133 // accesses. Thus, for now we keep one flat object, and will only split it if
134 // the code gets too messy.
135 struct gtm_thread
136 {
137
138   struct user_action
139   {
140     _ITM_userCommitFunction fn;
141     void *arg;
142     bool on_commit;
143     _ITM_transactionId_t resuming_id;
144   };
145
146   // The jump buffer by which GTM_longjmp restarts the transaction.
147   // This field *must* be at the beginning of the transaction.
148   gtm_jmpbuf jb;
149
150   // Data used by local.c for the undo log for both local and shared memory.
151   vector<gtm_undolog_entry*> undolog;
152
153   // Data used by alloc.c for the malloc/free undo log.
154   aa_tree<uintptr_t, gtm_alloc_action> alloc_actions;
155
156   // Data used by useraction.c for the user-defined commit/abort handlers.
157   vector<user_action> user_actions;
158
159   // A numerical identifier for this transaction.
160   _ITM_transactionId_t id;
161
162   // The _ITM_codeProperties of this transaction as given by the compiler.
163   uint32_t prop;
164
165   // The nesting depth for subsequently started transactions. This variable
166   // will be set to 1 when starting an outermost transaction.
167   uint32_t nesting;
168
169   // Set if this transaction owns the serial write lock.
170   // Can be reset only when restarting the outermost transaction.
171   static const uint32_t STATE_SERIAL            = 0x0001;
172   // Set if the serial-irrevocable dispatch table is installed.
173   // Implies that no logging is being done, and abort is not possible.
174   // Can be reset only when restarting the outermost transaction.
175   static const uint32_t STATE_IRREVOCABLE       = 0x0002;
176
177   // A bitmask of the above.
178   uint32_t state;
179
180   // In order to reduce cacheline contention on global_tid during
181   // beginTransaction, we allocate a block of 2**N ids to the thread
182   // all at once.  This number is the next value to be allocated from
183   // the block, or 0 % 2**N if no such block is allocated.
184   _ITM_transactionId_t local_tid;
185
186   // Data used by eh_cpp.c for managing exceptions within the transaction.
187   uint32_t cxa_catch_count;
188   void *cxa_unthrown;
189   void *eh_in_flight;
190
191   // Checkpoints for closed nesting.
192   vector<gtm_transaction_cp> parent_txns;
193
194   // Data used by retry.c for deciding what STM implementation should
195   // be used for the next iteration of the transaction.
196   // Only restart_total is reset to zero when the transaction commits, the
197   // other counters are total values for all previously executed transactions.
198   uint32_t restart_reason[NUM_RESTARTS];
199   uint32_t restart_total;
200
201   // *** The shared part of gtm_thread starts here. ***
202   // Shared state is on separate cachelines to avoid false sharing with
203   // thread-local parts of gtm_thread.
204
205   // Points to the next thread in the list of all threads.
206   gtm_thread *next_thread __attribute__((__aligned__(HW_CACHELINE_SIZE)));
207
208   // If this transaction is inactive, shared_state is ~0. Otherwise, this is
209   // an active or serial transaction.
210   atomic<gtm_word> shared_state;
211
212   // The lock that provides access to serial mode.  Non-serialized
213   // transactions acquire read locks; a serialized transaction aquires
214   // a write lock.
215   static gtm_rwlock serial_lock;
216
217   // The head of the list of all threads' transactions.
218   static gtm_thread *list_of_threads;
219   // The number of all registered threads.
220   static unsigned number_of_threads;
221
222   // In alloc.cc
223   void commit_allocations (bool, aa_tree<uintptr_t, gtm_alloc_action>*);
224   void record_allocation (void *, void (*)(void *));
225   void forget_allocation (void *, void (*)(void *));
226   void drop_references_allocations (const void *ptr)
227   {
228     this->alloc_actions.erase((uintptr_t) ptr);
229   }
230
231   // In beginend.cc
232   void rollback (gtm_transaction_cp *cp = 0, bool aborting = false);
233   bool trycommit ();
234   void restart (gtm_restart_reason) ITM_NORETURN;
235
236   gtm_thread();
237   ~gtm_thread();
238
239   static void *operator new(size_t);
240   static void operator delete(void *);
241
242   // Invoked from assembly language, thus the "asm" specifier on
243   // the name, avoiding complex name mangling.
244 #ifdef __USER_LABEL_PREFIX__
245 #define UPFX1(t) UPFX(t)
246 #define UPFX(t) #t
247   static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
248         __asm__(UPFX1(__USER_LABEL_PREFIX__) "GTM_begin_transaction") ITM_REGPARM;
249 #else
250   static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
251         __asm__("GTM_begin_transaction") ITM_REGPARM;
252 #endif
253   // In eh_cpp.cc
254   void revert_cpp_exceptions (gtm_transaction_cp *cp = 0);
255
256   // In local.cc
257   void commit_undolog (void);
258   void rollback_undolog (size_t until_size = 0);
259   void drop_references_undolog (const void *, size_t);
260
261   // In retry.cc
262   // Must be called outside of transactions (i.e., after rollback).
263   void decide_retry_strategy (gtm_restart_reason);
264   abi_dispatch* decide_begin_dispatch (uint32_t prop);
265   void number_of_threads_changed(unsigned previous, unsigned now);
266   // Must be called from serial mode. Does not call set_abi_disp().
267   void set_default_dispatch(abi_dispatch* disp);
268
269   // In method-serial.cc
270   void serialirr_mode ();
271
272   // In useraction.cc
273   void rollback_user_actions (size_t until_size = 0);
274   void commit_user_actions ();
275 };
276
277 } // namespace GTM
278
279 #include "tls.h"
280
281 namespace GTM HIDDEN {
282
283 // An unscaled count of the number of times we should spin attempting to
284 // acquire locks before we block the current thread and defer to the OS.
285 // This variable isn't used when the standard POSIX lock implementations
286 // are used.
287 extern uint64_t gtm_spin_count_var;
288
289 extern "C" uint32_t GTM_longjmp (uint32_t, const gtm_jmpbuf *, uint32_t)
290         ITM_NORETURN ITM_REGPARM;
291
292 extern "C" void GTM_LB (const void *, size_t) ITM_REGPARM;
293
294 extern void GTM_error (const char *fmt, ...)
295         __attribute__((format (printf, 1, 2)));
296 extern void GTM_fatal (const char *fmt, ...)
297         __attribute__((noreturn, format (printf, 1, 2)));
298
299 extern abi_dispatch *dispatch_serial();
300 extern abi_dispatch *dispatch_serialirr();
301 extern abi_dispatch *dispatch_serialirr_onwrite();
302 extern abi_dispatch *dispatch_gl_wt();
303
304 extern gtm_cacheline_mask gtm_mask_stack(gtm_cacheline *, gtm_cacheline_mask);
305
306 } // namespace GTM
307
308 #endif // LIBITM_I_H