From 0a905a0c33a1ae93174212b94dfdec946ebfaceb Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Wed, 19 Oct 2022 11:36:27 -0300 Subject: feat Create workers --- src/core.cpp | 17 ++++++++++++++++ src/core.hpp | 6 ++++++ src/job_queue.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/job_queue.hpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++ src/worker.cpp | 34 +++++++++++++++++++++++++++++++ src/worker.hpp | 33 ++++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+) create mode 100644 src/job_queue.cpp create mode 100644 src/job_queue.hpp create mode 100644 src/worker.cpp create mode 100644 src/worker.hpp diff --git a/src/core.cpp b/src/core.cpp index 1efaedc..3a78af2 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -68,6 +68,22 @@ vk_debug_callback( } #endif +void +load_threads(void *obj) +{ + auto num_threads{std::thread::hardware_concurrency() - 1}; + for(auto i{0}; i < num_threads; i++) + cg_core.threads.emplace_back( + cg_core.workers.emplace_back(&cg_core.job_queue)); +} + +void +unload_threads(void *obj) +{ + cg_core.job_queue.stop(); + for(auto &t: cg_core.threads) t.join(); +} + void load_mruby_symbols(void *obj) { @@ -636,6 +652,7 @@ load_mruby_interface(void *obj) } const CommandChain cg_sCore::loader{ + {&load_threads, &unload_threads}, {&load_mruby_symbols, nullptr}, {&load_game, nullptr}, {&load_sdl, &unload_sdl}, diff --git a/src/core.hpp b/src/core.hpp index 5a1556a..0830a49 100644 --- a/src/core.hpp +++ b/src/core.hpp @@ -41,7 +41,9 @@ #include #include "command.hpp" +#include "job_queue.hpp" #include "log.hpp" +#include "worker.hpp" #include "vk/device.hpp" #include "vk/graphics_pipeline_3d_layout.hpp" @@ -64,6 +66,10 @@ struct cg_sCore Log::Logger log; + JobQueue job_queue; + std::vector workers; + std::vector threads; + mrb_state *mrb; std::string game_file; diff --git a/src/job_queue.cpp b/src/job_queue.cpp new file mode 100644 index 0000000..49bf34f --- /dev/null +++ b/src/job_queue.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "job_queue.hpp" + +#include + +JobQueue::JobQueue(): + jobs{}, + _stop{false} +{ +} + +void +JobQueue::stop() +{ + using namespace std::chrono_literals; + + while(!this->jobs.empty()) std::this_thread::sleep_for(1000ms); + this->_stop = true; + this->condition.notify_all(); +} + +void +JobQueue::push(Job job) +{ + std::unique_lock lock{this->access}; + this->jobs.push_back(job); + this->condition.notify_one(); +} + +Job +JobQueue::pop() +{ + std::unique_lock lock{this->access}; + this->condition.wait(lock, [this]{ + return !this->jobs.empty() || this->_stop;}); + if(!this->jobs.empty()) + { + auto job{std::move(this->jobs.front())}; + this->jobs.pop_front(); + return job; + } + else + { + return Job{nullptr}; + } +} diff --git a/src/job_queue.hpp b/src/job_queue.hpp new file mode 100644 index 0000000..2a7735b --- /dev/null +++ b/src/job_queue.hpp @@ -0,0 +1,52 @@ +/* + * Copyright 2022 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CANDY_GEAR_JOB_QUEUE_H +#define CANDY_GEAR_JOB_QUEUE_H 1 + +#include +#include +#include +#include +#include + +class Worker; + +typedef std::function Job; + +class JobQueue +{ + friend Worker; + + std::mutex access; + std::condition_variable condition; + std::atomic _stop; + std::deque jobs; + + Job + pop(); + +public: + JobQueue(); + + void + stop(); + + void + push(Job job); +}; + +#endif /* CANDY_GEAR_JOB_QUEUE_H */ diff --git a/src/worker.cpp b/src/worker.cpp new file mode 100644 index 0000000..bcf654e --- /dev/null +++ b/src/worker.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2022 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "worker.hpp" + +#include + +Worker::Worker(JobQueue *job_queue): + job_queue{job_queue} +{ +} + +void +Worker::operator()() +{ + while(!this->job_queue->_stop) + { + auto job{this->job_queue->pop()}; + if(job) job(); + } +} diff --git a/src/worker.hpp b/src/worker.hpp new file mode 100644 index 0000000..449e1b0 --- /dev/null +++ b/src/worker.hpp @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CANDY_GEAR_WORKER_H +#define CANDY_GEAR_WORKER_H 1 + +#include "job_queue.hpp" + +class Worker +{ + JobQueue *job_queue; + +public: + Worker(JobQueue *job_queue); + + void + operator()(); +}; + +#endif /* CANDY_GEAR_WORKER_H */ -- cgit v1.2.3