Files
2020-09-01 16:32:26 +03:00

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