libitm_i.h 12 KB

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