138 lines
4.5 KiB
C++
138 lines
4.5 KiB
C++
|
|
/*************************************************************************
|
|
*
|
|
* This file is part of the ACT library
|
|
*
|
|
* Copyright (c) 2024 Fabian Posch
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
**************************************************************************
|
|
*/
|
|
|
|
#ifndef __TASK_INTERFACE__
|
|
#define __TASK_INTERFACE__
|
|
|
|
#include <queue>
|
|
#include <unordered_map>
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
#include <vector>
|
|
#include "agent_artifact.hpp"
|
|
|
|
/**
|
|
* If you want to use this interface for different types, you only need to change it here.
|
|
* This can be any type, as long as it publicly derives form pl::Artifact.
|
|
*/
|
|
using InputType = DBSimConfigArtifact;
|
|
using OutputType = DBSimOutputArtifact;
|
|
|
|
class TaskInterface {
|
|
|
|
public:
|
|
|
|
TaskInterface(size_t buffer_size);
|
|
~TaskInterface();
|
|
|
|
void wait_for_fresh();
|
|
void wait_for_finished();
|
|
void wait_for_buffer_consume();
|
|
void wait_for_cleanup_ready();
|
|
void wait_for_download_halt();
|
|
|
|
void notify_cleanup_ready();
|
|
void notify_workers_program_halt();
|
|
void notify_download_halt();
|
|
|
|
void push_fresh(std::unique_ptr<InputType> task);
|
|
void push_fresh(std::vector<std::unique_ptr<InputType>>& tasks);
|
|
std::unique_ptr<InputType> pop_fresh(bool& empty);
|
|
void push_finished(std::unique_ptr<OutputType> task);
|
|
std::unique_ptr<OutputType> pop_finished(bool& empty);
|
|
size_t get_buffer_space();
|
|
|
|
/*
|
|
* Store a design entry locally
|
|
*/
|
|
bool increment_design(const db::uuid_t& id);
|
|
void decrement_design(const db::uuid_t& id);
|
|
std::string get_design(const db::uuid_t& id);
|
|
void store_design(const db::uuid_t&, std::string& design);
|
|
|
|
/*
|
|
* Store a reference run locally
|
|
*/
|
|
bool increment_reference(const db::uuid_t& id);
|
|
void decrement_reference(const db::uuid_t& id);
|
|
std::shared_ptr<pl::SimOutputArtifact> get_reference(const db::uuid_t& id);
|
|
void store_reference(const db::uuid_t&, std::shared_ptr<pl::SimOutputArtifact> reference_run);
|
|
|
|
bool running() { return this->running_.load(std::memory_order_relaxed); };
|
|
bool is_stop_immediate() { return this->immediate_stop.load(std::memory_order_relaxed); };
|
|
void stop();
|
|
void stop_immediately() { this->immediate_stop.store(true, std::memory_order_relaxed); };
|
|
|
|
bool fresh_queue_empty();
|
|
bool finished_queue_empty();
|
|
|
|
private:
|
|
|
|
size_t buffer_size;
|
|
|
|
std::queue<std::unique_ptr<InputType>> fresh_queue;
|
|
std::queue<std::unique_ptr<OutputType>> finished_queue;
|
|
|
|
volatile std::atomic_bool running_ = std::atomic_bool(true);
|
|
volatile std::atomic_bool immediate_stop;
|
|
|
|
std::unordered_map<db::uuid_t, std::pair<size_t, std::string>> designs;
|
|
std::unordered_map<db::uuid_t, std::pair<size_t, std::shared_ptr<pl::SimOutputArtifact>>> references;
|
|
|
|
////// Mutexes //////
|
|
|
|
// access to task queues
|
|
std::mutex fresh_queue_mutex, finished_queue_mutex;
|
|
|
|
// design map access
|
|
std::mutex designs_mutex;
|
|
|
|
// reference map access
|
|
std::mutex references_mutex;
|
|
|
|
// notify upload thread that the finished queue is ready for cleanup
|
|
std::atomic_bool cleanup_ready;
|
|
std::mutex cleanup_ready_mutex;
|
|
std::condition_variable cleanup_ready_condition;
|
|
|
|
// inform the worker threads that there is data in the fresh task queue
|
|
std::mutex fresh_queue_empty_mutex;
|
|
std::condition_variable fresh_queue_empty_condition;
|
|
|
|
// inform the upload thread that there is data in the fresh task queue
|
|
std::mutex finished_queue_empty_mutex;
|
|
std::condition_variable finished_queue_empty_condition;
|
|
|
|
// inform the download thread that data was consumed
|
|
std::mutex fresh_queue_full_mutex;
|
|
std::condition_variable fresh_queue_full_condition;
|
|
|
|
// inform the main thread that the program is ending
|
|
std::mutex download_halt_mutex;
|
|
std::condition_variable download_halt_condition;
|
|
};
|
|
|
|
#endif
|