Advertisement
MystMe

Untitled

Feb 25th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.76 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <iostream>
  4. #include <atomic.hpp>
  5. #include <support.hpp>
  6.  
  7. namespace tpcc {
  8. namespace solutions {
  9.  
  10. class PetersonLock {
  11.   public:
  12.     void Lock(const size_t thread_index) {
  13.       const size_t another_thread = 1 - thread_index;
  14.       flag[thread_index].store(true);
  15.       victim.store(thread_index);
  16.       while(flag[another_thread].load() && victim.load() == thread_index) {};
  17.     }
  18.  
  19.     void Unlock(const size_t thread_index) {
  20.       flag[thread_index].store(false);
  21.     }
  22.   private:
  23.     std::atomic<bool> flag[2];
  24.     std::atomic<size_t> victim;
  25. };
  26.  
  27. class TournamentTreeLock {
  28.   public:
  29.     explicit TournamentTreeLock(const size_t num_threads) {
  30.       thread_num.store(num_threads);
  31.  
  32.       const size_t tree_size = 2*thread_num.load();
  33.       units = new PetersonLock[tree_size-thread_num.load()-1];
  34.       //current_lock = new std::atomic<int>[thread_num.load()];
  35.       //side = new std::atomic<bool>[thread_num.load()];
  36.  
  37.       for(size_t i = 0; i < thread_num.load(); i++) {
  38.         current_lock[i].store(-1);
  39.         side[i].store(0);
  40.       }
  41.     }
  42.  
  43.     void Lock(const size_t thread_index) {
  44.       while(current_lock[thread_index].load() != 0) { // Пока поток не захватил корень
  45.         const int current = current_lock[thread_index].load();
  46.         if(current == -1) { // если поток в листе
  47.           const size_t num = (thread_index+thread_num.load()-1) % 2; // 0, если  правый сын
  48.           side[thread_index].store(num);
  49.           size_t Parent = GetParent(thread_index+thread_num.load()-1);
  50.           units[Parent].Lock(num);
  51.           current_lock[thread_index].store(Parent);
  52.         } else {  // если поток в узле
  53.           const size_t num = (current) % 2;
  54.           side[thread_index].store(num);
  55.           units[GetParent(current)].Lock(num);
  56.           current_lock[thread_index].store(GetParent(current));
  57.         }
  58.       }
  59.     }
  60.  
  61.     void Unlock(size_t thread_index) {
  62.       units[current_lock[thread_index]].Unlock(side[thread_index]);
  63.       current_lock[thread_index].store(-1);
  64.     }
  65.  
  66.   private:
  67.   // Tree navigation
  68.  
  69.     size_t GetParent(size_t node_index) const {
  70.       if(node_index % 2 == 0) {
  71.         return (node_index-2)/2;
  72.       }
  73.       else return (node_index-1)/2;
  74.     }
  75.  
  76.     size_t GetLeftChild(size_t node_index) const {
  77.       return 2*node_index+1;
  78.     }
  79.  
  80.     size_t GetRightChild(size_t node_index) const {
  81.       return 2*node_index+2;
  82.     }
  83.  
  84.     size_t GetThreadLeaf(size_t thread_index) const {
  85.       return 0;
  86.     }
  87.  
  88.   private:
  89.     atomic<size_t> thread_num;
  90.     PetersonLock* units;
  91.     std::atomic<int> current_lock[1000];
  92.     std::atomic<bool> side[1000];
  93. };
  94.  
  95. } // namespace solutions
  96. } // namespace tpcc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement