1 /* Copyright (C) 2008-2018 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 #ifndef LIBITM_TLS_H
26 #define LIBITM_TLS_H 1
27
28 namespace GTM HIDDEN {
29
30 #if !defined(HAVE_ARCH_GTM_THREAD) || !defined(HAVE_ARCH_GTM_THREAD_DISP)
31 // Provides a single place to store all this libraries thread-local data.
32 struct gtm_thread_tls
33 {
34 #ifndef HAVE_ARCH_GTM_THREAD
35 // The currently active transaction. Elided if the target provides
36 // some efficient mechanism for storing this.
37 gtm_thread *thr;
38 #endif
39 #ifndef HAVE_ARCH_GTM_THREAD_DISP
40 // The dispatch table for the STM implementation currently in use. Elided
41 // if the target provides some efficient mechanism for storing this.
42 abi_dispatch *disp;
43 #endif
44 };
45
46 extern __thread gtm_thread_tls _gtm_thr_tls;
47 #endif
48
49 #ifndef HAVE_ARCH_GTM_THREAD
50 // If the target does not provide optimized access to the thread-local
51 // data, simply access the TLS variable defined above.
gtm_thr()52 static inline gtm_thread *gtm_thr() { return _gtm_thr_tls.thr; }
set_gtm_thr(gtm_thread * x)53 static inline void set_gtm_thr(gtm_thread *x) { _gtm_thr_tls.thr = x; }
54 #endif
55
56 #ifndef HAVE_ARCH_GTM_THREAD_DISP
57 // If the target does not provide optimized access to the currently
58 // active dispatch table, simply access via GTM_THR.
abi_disp()59 static inline abi_dispatch * abi_disp() { return _gtm_thr_tls.disp; }
set_abi_disp(abi_dispatch * x)60 static inline void set_abi_disp(abi_dispatch *x) { _gtm_thr_tls.disp = x; }
61 #endif
62
63 #ifndef HAVE_ARCH_GTM_MASK_STACK
64 // To filter out any updates that overlap the libitm stack, we define
65 // gtm_mask_stack_top to the entry point to the library and
66 // gtm_mask_stack_bottom to below the calling function (enforced with the
67 // noinline attribute). This definition should be fine for all
68 // stack-grows-down architectures.
69 // FIXME We fake the bottom to be lower so that we are safe even if we might
70 // call further functions (compared to where we called gtm_mask_stack_bottom
71 // in the call hierarchy) to actually undo or redo writes (e.g., memcpy).
72 // This is a completely arbitrary value; can we instead ensure that there are
73 // no such calls, or can we determine a future-proof value otherwise?
74 static inline void *
mask_stack_top(gtm_thread * tx)75 mask_stack_top(gtm_thread *tx) { return tx->jb.cfa; }
76 void * __attribute__((noinline))
77 mask_stack_bottom(gtm_thread *tx);
78 #endif
79
80 } // namespace GTM
81
82 #endif // LIBITM_TLS_H
83