Advertisement
Guest User

Untitled

a guest
Feb 25th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.45 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <atomic.hpp>
  4. #include <backoff.hpp>
  5. #include <support.hpp>
  6.  
  7. #include <vector>
  8.  
  9. namespace tpcc {
  10. namespace solutions {
  11.  
  12. class PetersonLock {
  13. public:
  14. PetersonLock() {
  15. want_[0].store(false);
  16. want_[1].store(false);
  17. victim_.store(0);
  18. }
  19.  
  20. PetersonLock(const PetersonLock&) = delete;
  21. PetersonLock(PetersonLock&&) = delete;
  22.  
  23. void Lock(const size_t thread_index) {
  24. want_[thread_index].store(true);
  25. victim_.store(thread_index);
  26.  
  27. Backoff backoff{};
  28. while (want_[1 - thread_index].load() && victim_.load() == thread_index) {
  29. backoff();
  30. }
  31. }
  32.  
  33. void Unlock(const size_t thread_index) {
  34. want_[thread_index].store(false);
  35. }
  36.  
  37. private:
  38. tpcc::atomic<bool> want_[2];
  39. tpcc::atomic<size_t> victim_;
  40. };
  41.  
  42. class TournamentTreeLock {
  43. public:
  44. explicit TournamentTreeLock(const size_t num_threads)
  45. : tree_size_(CountSize(num_threads)),
  46. locks_index_(tree_size_) {}
  47.  
  48. TournamentTreeLock(const TournamentTreeLock&) = delete;
  49. TournamentTreeLock(TournamentTreeLock&&) = delete;
  50.  
  51. void Lock(const size_t thread_index) {
  52. size_t current_node_index = GetThreadLeaf(thread_index);
  53.  
  54. while (current_node_index > 0) {
  55. locks_index_[GetParent(current_node_index)].Lock(GetPetersonLockIndex(current_node_index));
  56. current_node_index = GetParent(current_node_index);
  57. }
  58. }
  59.  
  60. void Unlock(const size_t thread_index) {
  61. size_t current_node_index = GetThreadLeaf(thread_index);
  62. std::vector<size_t> unlock_path;
  63.  
  64. while (current_node_index > 0) {
  65. unlock_path.push_back(current_node_index);
  66. current_node_index = GetParent(current_node_index);
  67. }
  68.  
  69. for (auto it = unlock_path.rbegin(); it != unlock_path.rend(); ++it) {
  70. locks_index_[GetParent(*it)].Unlock(GetPetersonLockIndex(*it));
  71. }
  72. }
  73.  
  74. private:
  75. size_t CountSize(const size_t num_threads) const {
  76. size_t temp_size_ = 1;
  77. while (temp_size_ < num_threads) {
  78. temp_size_ <<= 1;
  79. }
  80. return temp_size_ - 1;
  81. }
  82.  
  83. size_t GetParent(const size_t node_index) const {
  84. return (node_index - 1) / 2;
  85. }
  86.  
  87. size_t GetThreadLeaf(const size_t thread_index) const {
  88. return thread_index + tree_size_;
  89. }
  90.  
  91. size_t GetPetersonLockIndex(const size_t node_index) const {
  92. return node_index % 2;
  93. }
  94.  
  95. private:
  96. size_t tree_size_;
  97. std::vector<PetersonLock> locks_index_;
  98. };
  99.  
  100. } // namespace solutions
  101. } // namespace tpcc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement