/* XMRig * Copyright 2010 Jeff Garzik * Copyright 2012-2014 pooler * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett * Copyright 2018-2019 SChernykh * Copyright 2016-2019 XMRig , * * 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 3 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, see . */ #include "backend/common/Hashrate.h" #include "backend/common/interfaces/IBackend.h" #include "backend/common/Workers.h" #include "backend/cpu/CpuWorker.h" #include "base/io/log/Log.h" namespace xmrig { class WorkersPrivate { public: inline WorkersPrivate() { } inline ~WorkersPrivate() { delete hashrate; } Hashrate *hashrate = nullptr; IBackend *backend = nullptr; }; } // namespace xmrig template xmrig::Workers::Workers() : d_ptr(new WorkersPrivate()) { } template xmrig::Workers::~Workers() { delete d_ptr; } template const xmrig::Hashrate *xmrig::Workers::hashrate() const { return d_ptr->hashrate; } template void xmrig::Workers::setBackend(IBackend *backend) { d_ptr->backend = backend; } template void xmrig::Workers::start(const std::vector &data) { for (const T &item : data) { m_workers.push_back(new Thread(d_ptr->backend, m_workers.size(), item)); } d_ptr->hashrate = new Hashrate(m_workers.size()); for (Thread *worker : m_workers) { worker->start(Workers::onReady); } } template void xmrig::Workers::stop() { Nonce::stop(T::backend()); for (Thread *worker : m_workers) { delete worker; } m_workers.clear(); Nonce::touch(T::backend()); delete d_ptr->hashrate; d_ptr->hashrate = nullptr; } template void xmrig::Workers::tick(uint64_t) { if (!d_ptr->hashrate) { return; } for (Thread *handle : m_workers) { if (!handle->worker()) { return; } d_ptr->hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); } d_ptr->hashrate->updateHighest(); } template xmrig::IWorker *xmrig::Workers::create(Thread *) { return nullptr; } template void xmrig::Workers::onReady(void *arg) { Thread *handle = static_cast* >(arg); IWorker *worker = create(handle); if (!worker || !worker->selfTest()) { LOG_ERR("thread %zu error: \"hash self-test failed\".", worker->id()); return; } handle->setWorker(worker); handle->backend()->start(worker); } namespace xmrig { template<> xmrig::IWorker *xmrig::Workers::create(Thread *handle) { const int intensity = handle->config().intensity; # if defined(XMRIG_ALGO_RANDOMX) || defined(XMRIG_ALGO_CN_GPU) if (intensity > handle->config().algorithm.maxIntensity()) { LOG_WARN("CPU thread %zu warning: \"intensity %d not supported for %s algorithm\".", handle->index(), handle->config().intensity, handle->config().algorithm.shortName()); return new CpuWorker<1>(handle->index(), handle->config()); } # endif switch (intensity) { case 1: return new CpuWorker<1>(handle->index(), handle->config()); case 2: return new CpuWorker<2>(handle->index(), handle->config()); case 3: return new CpuWorker<3>(handle->index(), handle->config()); case 4: return new CpuWorker<4>(handle->index(), handle->config()); case 5: return new CpuWorker<5>(handle->index(), handle->config()); } return nullptr; } template class Workers; #ifdef XMRIG_FEATURE_OPENCL template<> xmrig::IWorker *xmrig::Workers::create(Thread *handle) { return nullptr; } template class Workers; #endif } // namespace xmrig