OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libitm/] [libitm_i.h] - Blame information for rev 737

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 737 jeremybenn
/* 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.