libfoedus-core
FOEDUS Core Library
xct.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
18 #ifndef FOEDUS_XCT_XCT_HPP_
19 #define FOEDUS_XCT_XCT_HPP_
20 
21 #include <iosfwd>
22 
23 #include "foedus/assert_nd.hpp"
24 #include "foedus/compiler.hpp"
25 #include "foedus/cxx11.hpp"
26 #include "foedus/epoch.hpp"
27 #include "foedus/error_code.hpp"
28 #include "foedus/fwd.hpp"
30 
31 // For log verification. Only in debug mode
32 #ifndef NDEBUG
34 #endif // NDEBUG
35 
36 #include "foedus/memory/fwd.hpp"
37 #include "foedus/storage/fwd.hpp"
38 #include "foedus/storage/page.hpp"
40 #include "foedus/thread/fwd.hpp"
42 #include "foedus/xct/fwd.hpp"
45 #include "foedus/xct/xct_id.hpp"
46 
47 namespace foedus {
48 namespace xct {
49 
58 class Xct {
59  public:
60  enum Constants {
63  };
64 
65  Xct(Engine* engine, thread::Thread* context, thread::ThreadId thread_id);
66 
67  // No copy
68  Xct(const Xct& other) CXX11_FUNC_DELETE;
69  Xct& operator=(const Xct& other) CXX11_FUNC_DELETE;
70 
71  void initialize(
72  memory::NumaCoreMemory* core_memory,
73  uint32_t* mcs_block_current,
74  uint32_t* mcs_rw_async_mapping_current);
75 
79  void activate(IsolationLevel isolation_level) {
80  ASSERT_ND(!active_);
81  active_ = true;
82  enable_rll_for_this_xct_ = default_rll_for_this_xct_;
83  hot_threshold_for_this_xct_ = default_hot_threshold_for_this_xct_;
84  rll_threshold_for_this_xct_ = default_rll_threshold_for_this_xct_;
85  isolation_level_ = isolation_level;
86  pointer_set_size_ = 0;
87  page_version_set_size_ = 0;
88  read_set_size_ = 0;
89  write_set_size_ = 0;
90  lock_free_read_set_size_ = 0;
91  lock_free_write_set_size_ = 0;
92  *mcs_block_current_ = 0;
93  *mcs_rw_async_mapping_current_ = 0;
94  local_work_memory_cur_ = 0;
95  current_lock_list_.clear_entries();
96  if (!retrospective_lock_list_.is_empty()) {
97  // If we have RLL, we will highly likely lock all of them.
98  // So, let's make CLL entries for all of them at the beginning.
99  // This is both for simplicity and performance.
100  current_lock_list_.prepopulate_for_retrospective_lock_list(retrospective_lock_list_);
101  }
102  }
103 
108  void deactivate() {
109  ASSERT_ND(active_);
110  ASSERT_ND(current_lock_list_.is_empty());
111  active_ = false;
112  *mcs_block_current_ = 0;
113  *mcs_rw_async_mapping_current_ = 0;
114  }
115 
116  uint32_t get_mcs_block_current() const { return *mcs_block_current_; }
117  uint32_t increment_mcs_block_current() { return ++(*mcs_block_current_); }
118  void decrement_mcs_block_current() { --(*mcs_block_current_); }
119 
121  bool is_active() const { return active_; }
122 
123  bool is_enable_rll_for_this_xct() const { return enable_rll_for_this_xct_; }
124  void set_enable_rll_for_this_xct(bool value) { enable_rll_for_this_xct_ = value; }
125  bool is_default_rll_for_this_xct() const { return default_rll_for_this_xct_ ; }
126  void set_default_rll_for_this_xct(bool value) { default_rll_for_this_xct_ = value; }
127 
128  uint16_t get_hot_threshold_for_this_xct() const { return hot_threshold_for_this_xct_; }
129  void set_hot_threshold_for_this_xct(uint16_t value) { hot_threshold_for_this_xct_ = value; }
131  return default_hot_threshold_for_this_xct_ ; }
133  default_hot_threshold_for_this_xct_ = value; }
134 
135  uint16_t get_rll_threshold_for_this_xct() const { return rll_threshold_for_this_xct_; }
136  void set_rll_threshold_for_this_xct(uint16_t value) { rll_threshold_for_this_xct_ = value; }
138  return default_rll_threshold_for_this_xct_ ; }
140  default_rll_threshold_for_this_xct_ = value; }
141 
142  SysxctWorkspace* get_sysxct_workspace() const { return sysxct_workspace_; }
143 
145  bool is_read_only() const {
146  return write_set_size_ == 0 && lock_free_write_set_size_ == 0;
147  }
149  IsolationLevel get_isolation_level() const { return isolation_level_; }
151  const XctId& get_id() const { return id_; }
152  thread::Thread* get_thread_context() { return context_; }
153  thread::ThreadId get_thread_id() const { return thread_id_; }
154  uint32_t get_pointer_set_size() const { return pointer_set_size_; }
155  uint32_t get_page_version_set_size() const { return page_version_set_size_; }
156  uint32_t get_read_set_size() const { return read_set_size_; }
157  uint32_t get_write_set_size() const { return write_set_size_; }
158  uint32_t get_lock_free_read_set_size() const { return lock_free_read_set_size_; }
159  uint32_t get_lock_free_write_set_size() const { return lock_free_write_set_size_; }
160  const PointerAccess* get_pointer_set() const { return pointer_set_; }
161  const PageVersionAccess* get_page_version_set() const { return page_version_set_; }
162  ReadXctAccess* get_read_set() { return read_set_; }
163  WriteXctAccess* get_write_set() { return write_set_; }
164  LockFreeReadXctAccess* get_lock_free_read_set() { return lock_free_read_set_; }
165  LockFreeWriteXctAccess* get_lock_free_write_set() { return lock_free_write_set_; }
166 
167 
185  void issue_next_id(XctId max_xct_id, Epoch *epoch);
186 
202  const storage::VolatilePagePointer* pointer_address,
204 
210  const storage::VolatilePagePointer* pointer_address,
212 
225  const storage::PageVersion* version_address,
226  storage::PageVersionStatus observed);
227 
279  bool intended_for_write,
280  RwLockableXctId* tid_address,
281  XctId* observed_xid,
282  ReadXctAccess** read_set_address,
283  bool no_readset_if_moved = false,
284  bool no_readset_if_next_layer = false);
287  bool intended_for_write,
288  RwLockableXctId* tid_address,
289  bool no_readset_if_moved = false,
290  bool no_readset_if_next_layer = false) {
291  XctId dummy_xctid;
292  ReadXctAccess* dummy_read_set;
293  return on_record_read(
294  intended_for_write,
295  tid_address,
296  &dummy_xctid,
297  &dummy_read_set,
298  no_readset_if_moved ,
299  no_readset_if_next_layer);
300  }
305  bool intended_for_write,
306  const storage::Page* page_address,
307  UniversalLockId lock_id,
308  RwLockableXctId* tid_address);
309 
318  ReadXctAccess* related_read_set,
319  RwLockableXctId* tid_address,
320  char* payload_address,
321  log::RecordLogType* log_entry);
322 
330  storage::StorageId storage_id,
331  XctId observed_owner_id,
332  RwLockableXctId* owner_id_address,
333  ReadXctAccess** read_set_address);
336  storage::StorageId storage_id,
337  XctId observed_owner_id,
338  UniversalLockId owner_lock_id,
339  RwLockableXctId* owner_id_address,
340  ReadXctAccess** read_set_address);
341 
346  storage::StorageId storage_id,
347  RwLockableXctId* owner_id_address,
348  char* payload_address,
349  log::RecordLogType* log_entry);
350 
355  storage::StorageId storage_id,
356  storage::Record* record,
357  log::RecordLogType* log_entry) {
358  return add_to_write_set(storage_id, &record->owner_id_, record->payload_, log_entry);
359  }
360 
365  storage::StorageId storage_id,
366  XctId observed_owner_id,
367  RwLockableXctId* owner_id_address,
368  char* payload_address,
369  log::RecordLogType* log_entry);
370 
375  storage::StorageId storage_id,
376  XctId observed_owner_id,
377  RwLockableXctId* owner_id_address);
378 
383  storage::StorageId storage_id,
384  log::RecordLogType* log_entry);
385 
387  ASSERT_ND(id_.before(new_id));
388  id_ = new_id;
389  ASSERT_ND(id_.get_ordinal() > 0);
390  ASSERT_ND(id_.is_valid());
391  }
392 
397  ErrorCode acquire_local_work_memory(uint32_t size, void** out, uint32_t alignment = 8) {
398  if (size % alignment != 0) {
399  size = ((size / alignment) + 1U) * alignment;
400  }
401  uint64_t begin = local_work_memory_cur_;
402  if (begin % alignment != 0) {
403  begin = ((begin / alignment) + 1U) * alignment;
404  }
405  if (UNLIKELY(size + begin > local_work_memory_size_)) {
407  }
408  local_work_memory_cur_ = size + begin;
409  *out = reinterpret_cast<char*>(local_work_memory_) + begin;
410  return kErrorCodeOk;
411  }
412 
413  xct::CurrentLockList* get_current_lock_list() { return &current_lock_list_; }
414  const xct::CurrentLockList* get_current_lock_list() const { return &current_lock_list_; }
416  return &retrospective_lock_list_;
417  }
418 
425 
426  friend std::ostream& operator<<(std::ostream& o, const Xct& v);
427 
428  private:
429  Engine* const engine_;
433  thread::Thread* const context_;
434 
436  const thread::ThreadId thread_id_;
437 
442  XctId id_;
443 
445  IsolationLevel isolation_level_;
446 
448  bool active_;
449 
463  bool enable_rll_for_this_xct_;
470  bool default_rll_for_this_xct_;
474  uint16_t hot_threshold_for_this_xct_;
475  uint16_t default_hot_threshold_for_this_xct_;
479  uint16_t rll_threshold_for_this_xct_;
480  uint16_t default_rll_threshold_for_this_xct_;
481 
482 
486  SysxctWorkspace* sysxct_workspace_;
487 
494  uint32_t* mcs_block_current_;
495 
496  uint32_t* mcs_rw_async_mapping_current_;
497 
498  ReadXctAccess* read_set_;
499  uint32_t read_set_size_;
500  uint32_t max_read_set_size_;
501 
502  WriteXctAccess* write_set_;
503  uint32_t write_set_size_;
504  uint32_t max_write_set_size_;
505 
506  LockFreeReadXctAccess* lock_free_read_set_;
507  uint32_t lock_free_read_set_size_;
508  uint32_t max_lock_free_read_set_size_;
509 
510  LockFreeWriteXctAccess* lock_free_write_set_;
511  uint32_t lock_free_write_set_size_;
512  uint32_t max_lock_free_write_set_size_;
513 
514  PointerAccess* pointer_set_;
515  uint32_t pointer_set_size_;
516 
517  PageVersionAccess* page_version_set_;
518  uint32_t page_version_set_size_;
519 
524  xct::CurrentLockList current_lock_list_;
525 
530  xct::RetrospectiveLockList retrospective_lock_list_;
531 
532  void* local_work_memory_;
533  uint64_t local_work_memory_size_;
535  uint64_t local_work_memory_cur_;
536 };
537 
538 inline bool Xct::assert_related_read_write() const {
539 #ifndef NDEBUG
540  for (uint32_t i = 0; i < write_set_size_; ++i) {
541  WriteXctAccess* write = write_set_ + i;
542  if (write->related_read_) {
543  ASSERT_ND(write->related_read_ >= read_set_);
544  uint32_t index = write->related_read_ - read_set_;
545  ASSERT_ND(index < read_set_size_);
547  ASSERT_ND(write == write->related_read_->related_write_);
548  }
549  }
550 
551  for (uint32_t i = 0; i < read_set_size_; ++i) {
552  ReadXctAccess* read = read_set_ + i;
553  if (read->related_write_) {
554  ASSERT_ND(read->related_write_ >= write_set_);
555  uint32_t index = read->related_write_ - write_set_;
556  ASSERT_ND(index < write_set_size_);
558  ASSERT_ND(read == read->related_write_->related_read_);
559  }
560  }
561 #endif // NDEBUG
562  return true;
563 }
564 
568 
569 } // namespace xct
570 } // namespace foedus
571 #endif // FOEDUS_XCT_XCT_HPP_
void set_default_rll_for_this_xct(bool value)
Definition: xct.hpp:126
ReadXctAccess * related_read_
Definition: xct_access.hpp:178
void issue_next_id(XctId max_xct_id, Epoch *epoch)
Called while a successful commit of xct to issue a new xct id.
Definition: xct.cpp:134
uint32_t get_mcs_block_current() const
Definition: xct.hpp:116
Represents a record of special read-access during a transaction without any need for locking...
Definition: xct_access.hpp:200
uint16_t get_default_rll_threshold_for_this_xct() const
Definition: xct.hpp:137
Represents one record in our key-value store.
Definition: record.hpp:33
ErrorCode add_to_write_set(storage::StorageId storage_id, storage::Record *record, log::RecordLogType *log_entry)
Add the given record to the write set of this transaction.
Definition: xct.hpp:354
void set_enable_rll_for_this_xct(bool value)
Definition: xct.hpp:124
ErrorCode add_to_read_set(storage::StorageId storage_id, XctId observed_owner_id, RwLockableXctId *owner_id_address, ReadXctAccess **read_set_address)
Add the given record to the read set of this transaction.
Definition: xct.cpp:395
xct::CurrentLockList * get_current_lock_list()
Definition: xct.hpp:413
void set_default_hot_threshold_for_this_xct(uint16_t value)
Definition: xct.hpp:132
bool assert_related_read_write() const __attribute__((always_inline))
This debug method checks whether the related_read_ and related_write_ fileds in read/write sets are c...
Definition: xct.hpp:538
const PointerAccess * get_pointer_set() const
Definition: xct.hpp:160
uint32_t StorageId
Unique ID for storage.
Definition: storage_id.hpp:55
uint32_t get_write_set_size() const
Definition: xct.hpp:157
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
Represents a record of write-access during a transaction.
Definition: xct_access.hpp:168
Represents one thread running on one NUMA core.
Definition: thread.hpp:48
ErrorCode on_record_read(bool intended_for_write, RwLockableXctId *tid_address, XctId *observed_xid, ReadXctAccess **read_set_address, bool no_readset_if_moved=false, bool no_readset_if_next_layer=false)
The general logic invoked for every record read.
Definition: xct.cpp:258
Typedefs of ID types used in thread package.
void deactivate()
Closes the transaction.
Definition: xct.hpp:108
Forward declarations of classes in transaction package.
const XctId & get_id() const
Returns the ID of this transaction, but note that it is not issued until commit time! ...
Definition: xct.hpp:151
void set_hot_threshold_for_this_xct(uint16_t value)
Definition: xct.hpp:129
Represents a pointer to a volatile page with modification count for preventing ABA.
Definition: storage_id.hpp:194
bool before(const XctId &other) const __attribute__((always_inline))
Returns if this XctId is before other in serialization order, meaning this is either an invalid (unus...
Definition: xct_id.hpp:1074
Represents a user transaction.
Definition: xct.hpp:58
Just a synonym of XctId to be used as a page lock mechanism.
Definition: page.hpp:129
Forward declarations of classes in root package.
Persistent status part of Transaction ID.
Definition: xct_id.hpp:955
STL namespace.
Represents a record of read-access during a transaction.
Definition: xct_access.hpp:139
Represents a time epoch.
Definition: epoch.hpp:61
bool is_active() const
Returns whether the object is an active transaction.
Definition: xct.hpp:121
ErrorCode add_to_write_set(storage::StorageId storage_id, RwLockableXctId *owner_id_address, char *payload_address, log::RecordLogType *log_entry)
Add the given record to the write set of this transaction.
Definition: xct.cpp:444
ErrorCode on_record_read(bool intended_for_write, RwLockableXctId *tid_address, bool no_readset_if_moved=false, bool no_readset_if_next_layer=false)
Shortcut for a case when you don't need observed_xid/read_set_address back.
Definition: xct.hpp:286
void prepopulate_for_retrospective_lock_list(const RetrospectiveLockList &rll)
Another batch-insert method used at the beginning of a transaction.
Declares common log types used in all packages.
ReadXctAccess * get_read_set()
Definition: xct.hpp:162
ErrorCode add_to_read_and_write_set(storage::StorageId storage_id, XctId observed_owner_id, RwLockableXctId *owner_id_address, char *payload_address, log::RecordLogType *log_entry)
Add a pair of read and write set of this transaction.
Definition: xct.cpp:474
thread::ThreadId get_thread_id() const
Definition: xct.hpp:153
ErrorCode add_to_lock_free_read_set(storage::StorageId storage_id, XctId observed_owner_id, RwLockableXctId *owner_id_address)
Add the given record to the special read-set that is not placed in usual data pages.
Definition: xct.cpp:532
Represents a record of special write-access during a transaction without any need for locking...
Definition: xct_access.hpp:228
Repository of memories dynamically acquired within one CPU core (thread).
uintptr_t UniversalLockId
Universally ordered identifier of each lock.
Definition: xct_id.hpp:134
uint32_t increment_mcs_block_current()
Definition: xct.hpp:117
The MCS reader-writer lock variant of LockableXctId.
Definition: xct_id.hpp:1132
void set_rll_threshold_for_this_xct(uint16_t value)
Definition: xct.hpp:136
void decrement_mcs_block_current()
Definition: xct.hpp:118
bool is_default_rll_for_this_xct() const
Definition: xct.hpp:125
void remember_previous_xct_id(XctId new_id)
Definition: xct.hpp:386
0 means no-error.
Definition: error_code.hpp:87
Forward declarations of classes in storage package.
char payload_[8]
Arbitrary payload given by the user.
Definition: record.hpp:45
Definitions of IDs in this package and a few related constant values.
uint32_t get_read_set_size() const
Definition: xct.hpp:156
ErrorCode add_related_write_set(ReadXctAccess *related_read_set, RwLockableXctId *tid_address, char *payload_address, log::RecordLogType *log_entry)
Registers a write-set related to an existing read-set.
Definition: xct.cpp:506
ErrorCode add_to_lock_free_write_set(storage::StorageId storage_id, log::RecordLogType *log_entry)
Add the given log to the lock-free write set of this transaction.
Definition: xct.cpp:551
uint16_t get_default_hot_threshold_for_this_xct() const
Definition: xct.hpp:130
RwLockableXctId * owner_id_address_
Pointer to the accessed record.
Definition: xct_access.hpp:102
uint16_t get_hot_threshold_for_this_xct() const
Definition: xct.hpp:128
bool is_read_only() const
Returns if this transaction makes no writes.
Definition: xct.hpp:145
const xct::CurrentLockList * get_current_lock_list() const
Definition: xct.hpp:414
Database engine object that holds all resources and provides APIs.
Definition: engine.hpp:109
uint32_t get_page_version_set_size() const
Definition: xct.hpp:155
Just a marker to denote that the memory region represents a data page.
Definition: page.hpp:334
SysxctWorkspace * get_sysxct_workspace() const
Definition: xct.hpp:142
void on_record_read_take_locks_if_needed(bool intended_for_write, const storage::Page *page_address, UniversalLockId lock_id, RwLockableXctId *tid_address)
subroutine of on_record_read() to take lock(s).
Definition: xct.cpp:334
WriteXctAccess * related_write_
An optional member that points to a write access related to this read.
Definition: xct_access.hpp:153
xct::RetrospectiveLockList * get_retrospective_lock_list()
Definition: xct.hpp:415
Xct & operator=(const Xct &other)=delete
Forward declarations of classes in memory package.
uint32_t get_pointer_set_size() const
Definition: xct.hpp:154
WriteXctAccess * get_write_set()
Definition: xct.hpp:163
IsolationLevel
Specifies the level of isolation during transaction processing.
Definition: xct_id.hpp:55
#define CXX11_FUNC_DELETE
Used in public headers in place of " = delete" of C++11.
Definition: cxx11.hpp:128
uint32_t get_lock_free_read_set_size() const
Definition: xct.hpp:158
IsolationLevel get_isolation_level() const
Returns the level of isolation for this transaction.
Definition: xct.hpp:149
void activate(IsolationLevel isolation_level)
Begins the transaction.
Definition: xct.hpp:79
uint16_t ThreadId
Typedef for a global ID of Thread (core), which is unique across NUMA nodes.
Definition: thread_id.hpp:80
thread::Thread * get_thread_context()
Definition: xct.hpp:152
uint16_t get_rll_threshold_for_this_xct() const
Definition: xct.hpp:135
void set_default_rll_threshold_for_this_xct(uint16_t value)
Definition: xct.hpp:139
ErrorCode add_to_page_version_set(const storage::PageVersion *version_address, storage::PageVersionStatus observed)
Add the given page version to the page version set of this transaction.
Definition: xct.cpp:242
Sorted list of all locks, either read-lock or write-lock, taken in the current run.
bool is_enable_rll_for_this_xct() const
Definition: xct.hpp:123
ErrorCode acquire_local_work_memory(uint32_t size, void **out, uint32_t alignment=8)
Get a tentative work memory of the specified size from pre-allocated thread-private memory...
Definition: xct.hpp:397
Base class for log type of record-wise operation.
#define UNLIKELY(x)
Hints that x is highly likely false.
Definition: compiler.hpp:104
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
Represents a record of following a page pointer during a transaction.
Definition: xct_access.hpp:48
const PageVersionAccess * get_page_version_set() const
Definition: xct.hpp:161
LockFreeWriteXctAccess * get_lock_free_write_set()
Definition: xct.hpp:165
Forward declarations of classes in thread package.
uint32_t get_lock_free_write_set_size() const
Definition: xct.hpp:159
#define ALWAYS_INLINE
A function suffix to hint that the function should always be inlined.
Definition: compiler.hpp:106
Represents a record of reading a page during a transaction.
Definition: xct_access.hpp:72
void overwrite_to_pointer_set(const storage::VolatilePagePointer *pointer_address, storage::VolatilePagePointer observed)
The transaction that has updated the volatile pointer should not abort itself.
Definition: xct.cpp:226
ErrorCode add_to_pointer_set(const storage::VolatilePagePointer *pointer_address, storage::VolatilePagePointer observed)
Add the given page pointer to the pointer set of this transaction.
Definition: xct.cpp:198
0x0A09 : "XCTION : Out of local work memory for the current transaction. Adjust XctOptions::local_wor...
Definition: error_code.hpp:204
ErrorCode
Enum of error codes defined in error_code.xmacro.
Definition: error_code.hpp:85
xct::RwLockableXctId owner_id_
This indicates the transaction that most recently modified this record.
Definition: record.hpp:39
Per-thread reused work memory for system transactions.
Xct(Engine *engine, thread::Thread *context, thread::ThreadId thread_id)
Definition: xct.cpp:41
void initialize(memory::NumaCoreMemory *core_memory, uint32_t *mcs_block_current, uint32_t *mcs_rw_async_mapping_current)
Definition: xct.cpp:77
LockFreeReadXctAccess * get_lock_free_read_set()
Definition: xct.hpp:164