#ifndef MULTITHREAD_EXPERIMENTS_BLOCK_H #define MULTITHREAD_EXPERIMENTS_BLOCK_H #include #include #include #include namespace sm { struct block { PIVector input_blocks; PIVector output_blocks; std::atomic_flag barrier = ATOMIC_FLAG_INIT; const int is_calc_idx; const std::chrono::microseconds calc_time; static std::chrono::microseconds random_time() { float val = powf(rand() % 1000 / 1000.f, 20.f) * 30.f * 1000.f; // std::cout << int(val) << std::endl; return std::chrono::microseconds(int(val)); } explicit block(const int is_calc_idx) : is_calc_idx(is_calc_idx), calc_time(random_time()) {} void calc() { std::this_thread::sleep_for(calc_time); } void unlock(int locks_count = -1) { if (locks_count == -1) locks_count = this->input_blocks.size(); for (int i = 0; i < locks_count; ++i) { this->input_blocks[i]->barrier.clear(std::memory_order_release); } this->barrier.clear(std::memory_order_release); } bool try_lock() { if (this->barrier.test_and_set(std::memory_order_acquire)) return false; int locks_count = 0; for (auto & input_block : this->input_blocks) { if (input_block->barrier.test_and_set(std::memory_order_acquire)) break; locks_count++; } if (locks_count == this->input_blocks.size()) { return true; } else { unlock(locks_count); return false; } } }; struct time_report { double calc_time_ms; double sync_time_ms; }; } #endif //MULTITHREAD_EXPERIMENTS_BLOCK_H