some thoughts about scheduling

This commit is contained in:
Blue 2024-01-02 22:11:56 -03:00
parent 26114aad5f
commit 544db92b6e
Signed by: blue
GPG key ID: 9B203B252A63EE38
11 changed files with 123 additions and 23 deletions

View file

@ -6,6 +6,7 @@ set(HEADERS
job.h
route.h
scheduler.h
function.h
)
set(SOURCES
@ -13,6 +14,7 @@ set(SOURCES
job.cpp
route.cpp
scheduler.cpp
function.cpp
)
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})

12
taskmanager/function.cpp Normal file
View file

@ -0,0 +1,12 @@
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "function.h"
TM::Function::Function (const std::function<void()>& fn):
fn(fn)
{}
void TM::Function::execute () {
fn();
}

20
taskmanager/function.h Normal file
View file

@ -0,0 +1,20 @@
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "functional"
#include "job.h"
namespace TM {
class Function : public Job {
public:
Function(const std::function<void()>& fn);
void execute () override;
private:
std::function<void()> fn;
};
}

View file

@ -4,8 +4,8 @@
#include "scheduler.h"
TM::Scheduler::Scheduler (std::weak_ptr<Manager> manager):
manager(manager),
queue(),
manager(manager),
mutex(),
cond(),
thread(nullptr),
@ -56,19 +56,21 @@ void TM::Scheduler::loop () {
break;
}
Task task = queue.top().second;
queue.pop();
Record task = queue.pop();
lock.unlock();
task();
std::shared_ptr<Manager> mngr = manager.lock();
if (mngr)
mngr->schedule(std::move(task.second));
lock.lock();
}
}
}
void TM::Scheduler::schedule (Task task, Delay delay) {
void TM::Scheduler::schedule (const std::function<void()>& task, Delay delay) {
std::unique_lock lock(mutex);
Time time = std::chrono::steady_clock::now() + delay;
queue.emplace(time, task);
queue.emplace(time, std::make_unique<Function>(task));
lock.unlock();
cond.notify_one();

View file

@ -5,41 +5,41 @@
#include <memory>
#include <thread>
#include <queue>
#include <chrono>
#include <functional>
#include <mutex>
#include <condition_variable>
#include "manager.h"
#include "function.h"
#include "utils/helpers.h"
namespace TM {
class Scheduler {
public:
using Delay = std::chrono::milliseconds;
using Task = std::function<void()>;
Scheduler (std::weak_ptr<Manager> manager);
~Scheduler ();
void start();
void stop();
void schedule(Task task, Delay delay);
void schedule(const std::function<void()>& task, Delay delay);
private:
void loop();
private:
using Task = std::unique_ptr<Function>;
using Time = std::chrono::time_point<std::chrono::steady_clock>;
using Record = std::pair<Time, Task>;
std::weak_ptr<Manager> manager;
std::priority_queue<
PriorityQueue<
Record,
std::vector<Record>,
FirstGreater<Record>
> queue;
std::weak_ptr<Manager> manager;
std::mutex mutex;
std::condition_variable cond;
std::unique_ptr<std::thread> thread;