64 lines
1.5 KiB
C++
64 lines
1.5 KiB
C++
#ifndef MULTITHREAD_EXPERIMENTS_BLOCK_H
|
|
#define MULTITHREAD_EXPERIMENTS_BLOCK_H
|
|
|
|
#include <pivector.h>
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <cmath>
|
|
|
|
namespace sm {
|
|
|
|
struct block {
|
|
PIVector<block*> input_blocks;
|
|
PIVector<block*> 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
|