Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iostream>
- #include <atomic.hpp>
- #include <support.hpp>
- namespace tpcc {
- namespace solutions {
- class PetersonLock {
- public:
- void Lock(const size_t thread_index) {
- const size_t another_thread = 1 - thread_index;
- flag[thread_index].store(true);
- victim.store(thread_index);
- while(flag[another_thread].load() && victim.load() == thread_index) {};
- }
- void Unlock(const size_t thread_index) {
- flag[thread_index].store(false);
- }
- private:
- std::atomic<bool> flag[2];
- std::atomic<size_t> victim;
- };
- class TournamentTreeLock {
- public:
- explicit TournamentTreeLock(const size_t num_threads) {
- thread_num.store(num_threads);
- const size_t tree_size = 2*thread_num.load();
- units = new PetersonLock[tree_size-thread_num.load()-1];
- //current_lock = new std::atomic<int>[thread_num.load()];
- //side = new std::atomic<bool>[thread_num.load()];
- for(size_t i = 0; i < thread_num.load(); i++) {
- current_lock[i].store(-1);
- side[i].store(0);
- }
- }
- void Lock(const size_t thread_index) {
- while(current_lock[thread_index].load() != 0) { // Пока поток не захватил корень
- const int current = current_lock[thread_index].load();
- if(current == -1) { // если поток в листе
- const size_t num = (thread_index+thread_num.load()-1) % 2; // 0, если правый сын
- side[thread_index].store(num);
- size_t Parent = GetParent(thread_index+thread_num.load()-1);
- units[Parent].Lock(num);
- current_lock[thread_index].store(Parent);
- } else { // если поток в узле
- const size_t num = (current) % 2;
- side[thread_index].store(num);
- units[GetParent(current)].Lock(num);
- current_lock[thread_index].store(GetParent(current));
- }
- }
- }
- void Unlock(size_t thread_index) {
- units[current_lock[thread_index]].Unlock(side[thread_index]);
- current_lock[thread_index].store(-1);
- }
- private:
- // Tree navigation
- size_t GetParent(size_t node_index) const {
- if(node_index % 2 == 0) {
- return (node_index-2)/2;
- }
- else return (node_index-1)/2;
- }
- size_t GetLeftChild(size_t node_index) const {
- return 2*node_index+1;
- }
- size_t GetRightChild(size_t node_index) const {
- return 2*node_index+2;
- }
- size_t GetThreadLeaf(size_t thread_index) const {
- return 0;
- }
- private:
- atomic<size_t> thread_num;
- PetersonLock* units;
- std::atomic<int> current_lock[1000];
- std::atomic<bool> side[1000];
- };
- } // namespace solutions
- } // namespace tpcc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement