tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
metadata.hpp
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2011
3  * University of Rochester Department of Computer Science
4  * and
5  * Lehigh University Department of Computer Science and Engineering
6  *
7  * License: Modified BSD
8  * Please see the file LICENSE.RSTM for licensing information
9  */
10 
11 /**
12  * The global metadata types used by our STM implementations are defined in
13  * this file, along with many of the types used by the TxThread object of
14  * logging the progress of a transaction.
15  */
16 
17 #ifndef METADATA_HPP__
18 #define METADATA_HPP__
19 
20 #include <stm/config.h>
21 #include "stm/MiniVector.hpp"
22 #include "stm/BitFilter.hpp"
23 
24 namespace stm
25 {
26  // forward declare for avoiding a SunCC issue
27  NORETURN void UNRECOVERABLE(const char*);
28 
29  /**
30  * Many of our data structures benefit from having a cap on the number of
31  * threads. Here we set that cap at 256
32  */
33  static const unsigned MAX_THREADS = 256;
34 
35  /**
36  * Forward declare the TxThread type, so we can use it in some of our
37  * metadata types
38  */
39  struct TxThread;
40 
41  /**
42  * A scope_t is an opaque type used by an API to unwind.
43  */
44  typedef void scope_t;
45 
46  /**
47  * id_version_t uses the msb as the lock bit. If the msb is zero, treat
48  * the word as a version number. Otherwise, treat it as a struct with the
49  * lower 8 bits giving the ID of the lock-holding thread.
50  */
52  {
53  struct
54  {
55  // ensure msb is lock bit regardless of platform
56 #if defined(STM_CPU_X86) /* little endian */
57  uintptr_t id:(8*sizeof(uintptr_t))-1;
58  uintptr_t lock:1;
59 #else /* big endian (probably SPARC) */
60  uintptr_t lock:1;
61  uintptr_t id:(8*sizeof(uintptr_t))-1;
62 #endif
63  } fields;
64  uintptr_t all; // read entire struct in a single load
65  };
66 
67  /**
68  * When we acquire an orec, we may ultimately need to reset it to its old
69  * value (if we abort). Saving the old value with the orec is an easy way to
70  * support this need without having exta logging in the descriptor.
71  */
72  struct orec_t
73  {
74  volatile id_version_t v; // current version number or lockBit + ownerId
75  volatile uintptr_t p; // previous version number
76  };
77 
78  /**
79  * Nano requires that we log not just the orec address, but also its value
80  */
81  struct nanorec_t
82  {
83  orec_t* o; // address of the orec
84  uintptr_t v; // value of the orec
85  nanorec_t(orec_t* _o, uintptr_t _v) : o(_o), v(_v) { }
86  };
87 
88  /**
89  * TLRW-style algorithms don't use orecs, but instead use "byte locks".
90  * This is the type of a byte lock. We have 32 bits for the lock, and
91  * then 60 bytes corresponding to 60 named threads.
92  *
93  * NB: We don't support more than 60 threads in ByteLock-based algorithms.
94  * If you have more than that many threads, you should use adaptivity
95  * to switch to a different algorithm.
96  */
97  struct bytelock_t
98  {
99  volatile uint32_t owner; // no need for more than 32 bits
100  volatile unsigned char reader[CACHELINE_BYTES - sizeof(uint32_t)];
101 
102  /**
103  * Setting the read byte is platform-specific, so we make it a method
104  * of the bytelock_t
105  *
106  * NB: implemented in algs.hpp, so that it is visible where needed,
107  * but not visible globally
108  */
109  void set_read_byte(uint32_t id);
110  };
111 
112  /**
113  * Padded word-sized value for keeping a value in its own cache line
114  */
115  struct pad_word_t
116  {
117  volatile uintptr_t val;
118  char pad[CACHELINE_BYTES-sizeof(uintptr_t)];
119  };
120 
121  /**
122  * a reader record (rrec) holds bits representing up to MAX_THREADS reader
123  * transactions
124  *
125  * NB: methods are implemented in algs.hpp, so that they are visible where
126  * needed, but not visible globally
127  */
128  struct rrec_t
129  {
130  /*** MAX_THREADS bits, to represent MAX_THREADS readers */
131  static const uint32_t BUCKETS = MAX_THREADS / (8*sizeof(uintptr_t));
132  static const uint32_t BITS = 8*sizeof(uintptr_t);
133  volatile uintptr_t bits[BUCKETS];
134 
135  /*** set a bit */
136  void setbit(unsigned slot);
137 
138  /*** test a bit */
139  bool getbit(unsigned slot);
140 
141  /*** unset a bit */
142  void unsetbit(unsigned slot);
143 
144  /*** combine test and set */
145  bool setif(unsigned slot);
146 
147  /*** bitwise or */
148  void operator |= (rrec_t& rhs);
149  };
150 
151  /**
152  * If we want to do an STM with RSTM-style visible readers, this lets us
153  * have an owner and a bunch of readers in a single struct, instead of via
154  * separate orec and rrec tables. Note that these data structures do not
155  * have nice alignment
156  */
157  struct bitlock_t
158  {
159  volatile uintptr_t owner; // this is the single wrter
160  rrec_t readers; // large bitmap for readers
161  };
162 
163  /**
164  * In order to avoid a circular dependency, we need to declare some
165  * WriteSet support here.
166  */
169 #if defined(STM_WS_WORDLOG)
170  typedef WordLoggingWriteSetEntry WriteSetEntry;
171 #elif defined(STM_WS_BYTELOG)
172  typedef ByteLoggingWriteSetEntry WriteSetEntry;
173 #else
174 # error WriteSet logging granularity configuration error.
175 #endif
176 
177  /**
178  * Common TypeDefs
179  */
180  typedef MiniVector<orec_t*> OrecList; // vector of orecs
181  typedef MiniVector<rrec_t*> RRecList; // vector of rrecs
182  typedef MiniVector<bytelock_t*> ByteLockList; // vector of bytelocks
183  typedef MiniVector<bitlock_t*> BitLockList; // vector of bitlocks
184  typedef BitFilter<1024> filter_t; // flat 1024-bit Bloom filter
185  typedef MiniVector<nanorec_t> NanorecList; // <orec,val> pairs
186  typedef MiniVector<void*> AddressList; // for the mmpolicy
187 
188  /**
189  * These are for counting consecutive aborts in a histogram. We use them
190  * for measuring toxic transactions. Note that there is special support
191  * for counting how many times an hourglass transaction commits or aborts.
192  */
194  {
195  /*** the highest number of consec aborts > 16 */
196  uint32_t max;
197 
198  /*** how many hourglass commits occurred? */
199  uint32_t hg_commits;
200 
201  /*** how many hourglass aborts occurred? */
202  uint32_t hg_aborts;
203 
204  /*** histogram with 0-16 + overflow */
205  uint32_t buckets[18];
206 
207  /*** on commit, update the appropriate bucket */
208  void onCommit(uint32_t aborts);
209 
210  /*** simple printout */
211  void dump();
212 
213  /*** on hourglass commit */
214  void onHGCommit();
215 
216  /*** on hourglass abort() */
217  void onHGAbort();
218 
219  /*** simple constructor */
221  {
222  for (int i = 0; i < 18; ++i)
223  buckets[i] = 0;
224  }
225  };
226 
227  /**
228  * When STM_COUNTCONSEC_YES is not set, we don't do anything for these
229  * events
230  */
231  struct toxic_nop_t
232  {
233  void onCommit(uint32_t) { }
234  void dump() { }
235  void onHGCommit() { }
236  void onHGAbort() { }
237  };
238 
239 #ifdef STM_COUNTCONSEC_YES
240  typedef toxic_histogram_t toxic_t;
241 #else
243 #endif
244 
245 } // namespace stm
246 
247 #endif // METADATA_HPP__
volatile uintptr_t owner
Definition: metadata.hpp:159
orec_t * o
Definition: metadata.hpp:83
MiniVector< bytelock_t * > ByteLockList
Definition: metadata.hpp:182
MiniVector< nanorec_t > NanorecList
Definition: metadata.hpp:185
uint32_t buckets[18]
Definition: metadata.hpp:205
Definition: metadata.hpp:115
void setbit(unsigned slot)
Definition: algs.hpp:392
Definition: stm_fraser.c:61
bool getbit(unsigned slot)
Definition: algs.hpp:407
uint32_t max
Definition: metadata.hpp:196
Definition: metadata.hpp:97
Definition: metadata.hpp:128
Definition: metadata.hpp:231
void onCommit(uint32_t aborts)
Definition: algs.hpp:468
bool setif(unsigned slot)
Definition: algs.hpp:437
Definition: metadata.hpp:193
#define CACHELINE_BYTES
Definition: platform.hpp:46
void onCommit(uint32_t)
Definition: metadata.hpp:233
volatile uintptr_t val
Definition: metadata.hpp:117
volatile uint32_t owner
Definition: metadata.hpp:99
volatile unsigned char reader[CACHELINE_BYTES-sizeof(uint32_t)]
Definition: metadata.hpp:100
Definition: metadata.hpp:157
void onHGAbort()
Definition: metadata.hpp:236
void onHGAbort()
Definition: algs.hpp:492
uint32_t hg_aborts
Definition: metadata.hpp:202
uintptr_t v
Definition: metadata.hpp:84
struct stm::id_version_t::@2 fields
Definition: WriteSet.hpp:44
void set_read_byte(uint32_t id)
Definition: algs.hpp:382
Definition: WriteSet.hpp:112
Definition: metadata.hpp:81
toxic_histogram_t()
Definition: metadata.hpp:220
void scope_t
Definition: metadata.hpp:39
void operator|=(rrec_t &rhs)
Definition: algs.hpp:459
MiniVector< orec_t * > OrecList
Definition: metadata.hpp:168
uintptr_t lock
Definition: metadata.hpp:60
void dump()
Definition: metadata.hpp:234
volatile uintptr_t bits[BUCKETS]
Definition: metadata.hpp:133
MiniVector< rrec_t * > RRecList
Definition: metadata.hpp:181
MiniVector< void * > AddressList
Definition: metadata.hpp:186
void onHGCommit()
Definition: metadata.hpp:235
rrec_t readers
Definition: metadata.hpp:160
uintptr_t all
Definition: metadata.hpp:64
volatile uintptr_t p
Definition: metadata.hpp:75
Definition: txthread.hpp:47
BitFilter< 1024 > filter_t
Definition: metadata.hpp:184
void NORETURN UNRECOVERABLE(const char *)
Definition: txthread.cpp:155
static const unsigned MAX_THREADS
Definition: metadata.hpp:33
Definition: metadata.hpp:51
nanorec_t(orec_t *_o, uintptr_t _v)
Definition: metadata.hpp:85
toxic_nop_t toxic_t
Definition: metadata.hpp:242
char pad[CACHELINE_BYTES-sizeof(uintptr_t)]
Definition: metadata.hpp:118
Definition: metadata.hpp:72
uint32_t hg_commits
Definition: metadata.hpp:199
static const uint32_t BUCKETS
Definition: metadata.hpp:131
void unsetbit(unsigned slot)
Definition: algs.hpp:416
Definition: BitFilter.hpp:36
void onHGCommit()
Definition: algs.hpp:491
volatile id_version_t v
Definition: metadata.hpp:74
MiniVector< bitlock_t * > BitLockList
Definition: metadata.hpp:183
#define NORETURN
Definition: platform.hpp:47
void dump()
Definition: algs.hpp:482
static const uint32_t BITS
Definition: metadata.hpp:132