1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-24 13:32:46 -05:00

Draft merge

This commit is contained in:
MoneroOcean
2019-06-18 11:17:00 -07:00
217 changed files with 13224 additions and 4105 deletions

View File

@@ -25,8 +25,8 @@
#include <assert.h>
#include "base/io/log/Log.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "crypto/Asm.h"
#include "Mem.h"
#include "rapidjson/document.h"
@@ -90,31 +90,31 @@ static void patchCode(T dst, U src, const uint32_t iterations, const uint32_t ma
}
extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx *ctx0, cryptonight_ctx *ctx1);
extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx **ctx);
extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx **ctx);
xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ivybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ryzen_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_bulldozer_asm = nullptr;
xmrig::CpuThread::cn_mainloop_double_fun cn_half_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ryzen_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm = nullptr;
xmrig::CpuThread::cn_mainloop_double_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ivybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ryzen_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_bulldozer_asm = nullptr;
xmrig::CpuThread::cn_mainloop_double_fun cn_zls_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ivybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ryzen_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_bulldozer_asm = nullptr;
xmrig::CpuThread::cn_mainloop_double_fun cn_double_double_mainloop_sandybridge_asm = nullptr;
xmrig::CpuThread::cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm = nullptr;
void xmrig::CpuThread::patchAsmVariants()
@@ -125,22 +125,22 @@ void xmrig::CpuThread::patchAsmVariants()
cn_half_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x0000);
cn_half_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x1000);
cn_half_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x2000);
cn_half_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_double_fun> (base + 0x3000);
cn_half_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x3000);
cn_trtl_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x4000);
cn_trtl_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x5000);
cn_trtl_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x6000);
cn_trtl_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_double_fun> (base + 0x7000);
cn_trtl_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x7000);
cn_zls_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x8000);
cn_zls_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x9000);
cn_zls_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xA000);
cn_zls_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_double_fun> (base + 0xB000);
cn_zls_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xB000);
cn_double_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xC000);
cn_double_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xD000);
cn_double_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xE000);
cn_double_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_double_fun> (base + 0xF000);
cn_double_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xF000);
patchCode(cn_half_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK);
patchCode(cn_half_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK);
@@ -390,6 +390,8 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_DOUBLE>,
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_DOUBLE>,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# ifndef XMRIG_NO_AEON
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
@@ -428,6 +430,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
@@ -446,6 +449,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# endif
# ifndef XMRIG_NO_SUMO
@@ -498,6 +502,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
@@ -516,6 +521,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# endif
# ifndef XMRIG_NO_CN_PICO
@@ -547,6 +553,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# else
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
@@ -565,6 +572,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RX_WOW
# endif
};
@@ -706,7 +714,7 @@ void xmrig::CpuThread::print() const
#endif
#ifndef XMRIG_NO_API
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const
{
using namespace rapidjson;

View File

@@ -61,8 +61,7 @@ public:
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly);
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx, uint64_t height);
typedef void (*cn_mainloop_fun)(cryptonight_ctx *ctx);
typedef void (*cn_mainloop_double_fun)(cryptonight_ctx *ctx1, cryptonight_ctx *ctx2);
typedef void (*cn_mainloop_fun)(cryptonight_ctx **ctx);
# ifndef XMRIG_NO_ASM
static void patchAsmVariants();
@@ -91,7 +90,7 @@ protected:
void print() const override;
# endif
# ifndef XMRIG_NO_API
# ifdef XMRIG_FEATURE_API
rapidjson::Value toAPI(rapidjson::Document &doc) const override;
# endif

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@@ -29,8 +30,9 @@
#include <stdio.h>
#include "common/log/Log.h"
#include "core/Config.h"
#include "base/io/log/Log.h"
#include "base/tools/Handle.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "workers/Hashrate.h"
@@ -48,18 +50,19 @@ inline static const char *format(double h, char *buf, size_t size)
Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
m_highest(0.0),
m_threads(0),
m_controller(controller)
m_threads(threads),
m_timer(nullptr)
{
set_threads(threads);
const int printTime = controller->config()->printTime();
if (printTime > 0) {
uv_timer_init(uv_default_loop(), &m_timer);
m_timer.data = this;
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
m_timer->data = this;
uv_timer_start(&m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000);
uv_timer_start(m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000);
}
}
@@ -175,8 +178,7 @@ void Hashrate::print() const
char num3[8] = { 0 };
char num4[8] = { 0 };
LOG_INFO(m_controller->config()->isColors() ? WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s")
: "speed 10s/60s/15m %s %s %s H/s max %s H/s",
LOG_INFO(WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s"),
format(calc(ShortInterval), num1, sizeof(num1)),
format(calc(MediumInterval), num2, sizeof(num2)),
format(calc(LargeInterval), num3, sizeof(num3)),
@@ -187,7 +189,8 @@ void Hashrate::print() const
void Hashrate::stop()
{
uv_timer_stop(&m_timer);
xmrig::Handle::close(m_timer);
m_timer = nullptr;
}

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HASHRATE_H__
#define __HASHRATE_H__
#ifndef XMRIG_HASHRATE_H
#define XMRIG_HASHRATE_H
#include <stdint.h>
@@ -68,9 +69,8 @@ private:
uint32_t* m_top;
uint64_t** m_counts;
uint64_t** m_timestamps;
uv_timer_t m_timer;
xmrig::Controller *m_controller;
uv_timer_t *m_timer;
};
#endif /* __HASHRATE_H__ */
#endif /* XMRIG_HASHRATE_H */

View File

@@ -28,17 +28,22 @@
#include "crypto/CryptoNight_test.h"
#include "common/log/Log.h"
#include "workers/CpuThread.h"
#include "workers/MultiWorker.h"
#include "workers/Workers.h"
template<size_t N>
MultiWorker<N>::MultiWorker(Handle *handle)
MultiWorker<N>::MultiWorker(ThreadHandle *handle)
: Worker(handle)
{
m_memory = Mem::create(m_ctx, m_thread->algorithm(), N);
const int flags = RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT;
m_rx_vm = randomx_create_vm(static_cast<randomx_flags>(flags), nullptr, Workers::getDataset());
if (!m_rx_vm) {
m_rx_vm = randomx_create_vm(static_cast<randomx_flags>(flags - RANDOMX_FLAG_LARGE_PAGES), nullptr, Workers::getDataset());
}
}
@@ -46,6 +51,7 @@ template<size_t N>
MultiWorker<N>::~MultiWorker()
{
Mem::release(m_ctx, N, m_memory);
randomx_destroy_vm(m_rx_vm);
}
@@ -127,7 +133,14 @@ void MultiWorker<N>::start()
storeStats();
}
m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height());
const xmrig::Variant v = m_state.job.algorithm().variant();
if (v == xmrig::VARIANT_RX_WOW) {
Workers::updateDataset(m_state.job.seed_hash(), m_totalWays);
randomx_calculate_hash(m_rx_vm, m_state.blob, m_state.job.size(), m_hash);
}
else {
m_thread->fn(v)(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height());
}
for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) {

View File

@@ -27,10 +27,11 @@
#define XMRIG_MULTIWORKER_H
#include "common/net/Job.h"
#include "base/net/stratum/Job.h"
#include "Mem.h"
#include "net/JobResult.h"
#include "workers/Worker.h"
#include "randomwow.h"
class Handle;
@@ -40,7 +41,7 @@ template<size_t N>
class MultiWorker : public Worker
{
public:
MultiWorker(Handle *handle);
MultiWorker(ThreadHandle *handle);
~MultiWorker();
protected:
@@ -70,6 +71,8 @@ private:
State m_pausedState;
State m_state;
uint8_t m_hash[N * 32];
randomx_vm* m_rx_vm;
};

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@@ -22,11 +23,10 @@
*/
#include "workers/Handle.h"
#include "interfaces/IWorker.h"
#include "workers/ThreadHandle.h"
Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
ThreadHandle::ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
m_worker(nullptr),
m_totalWays(totalWays),
m_offset(offset),
@@ -34,15 +34,15 @@ Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
{
}
Handle::~Handle() { if (m_worker) delete m_worker; }
ThreadHandle::~ThreadHandle() { if (m_worker) delete m_worker; }
void Handle::join()
void ThreadHandle::join()
{
uv_thread_join(&m_thread);
}
void Handle::start(void (*callback) (void *))
void ThreadHandle::start(void (*callback) (void *))
{
uv_thread_create(&m_thread, callback, this);
}

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HANDLE_H__
#define __HANDLE_H__
#ifndef XMRIG_THREADHANDLE_H
#define XMRIG_THREADHANDLE_H
#include <assert.h>
@@ -36,11 +37,11 @@
class IWorker;
class Handle
class ThreadHandle
{
public:
Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays);
~Handle();
ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays);
~ThreadHandle();
void join();
void start(void (*callback) (void *));
@@ -60,4 +61,4 @@ private:
};
#endif /* __HANDLE_H__ */
#endif /* XMRIG_THREADHANDLE_H */

View File

@@ -27,11 +27,11 @@
#include "common/cpu/Cpu.h"
#include "common/Platform.h"
#include "workers/CpuThread.h"
#include "workers/Handle.h"
#include "workers/ThreadHandle.h"
#include "workers/Worker.h"
Worker::Worker(Handle *handle) :
Worker::Worker(ThreadHandle *handle) :
m_id(handle->threadId()),
m_totalWays(handle->totalWays()),
m_offset(handle->offset()),

View File

@@ -33,7 +33,7 @@
#include "Mem.h"
class Handle;
class ThreadHandle;
namespace xmrig {
@@ -44,7 +44,7 @@ namespace xmrig {
class Worker : public IWorker
{
public:
Worker(Handle *handle);
Worker(ThreadHandle *handle);
inline const MemInfo &memory() const { return m_memory; }
inline size_t id() const override { return m_id; }

View File

@@ -30,17 +30,18 @@
#include "api/Api.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "base/io/log/Log.h"
#include "base/tools/Handle.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/CryptoNight_constants.h"
#include "interfaces/IJobResultListener.h"
#include "interfaces/IThread.h"
#include "Mem.h"
#include "rapidjson/document.h"
#include "workers/Handle.h"
#include "workers/Hashrate.h"
#include "workers/MultiWorker.h"
#include "workers/ThreadHandle.h"
#include "workers/Workers.h"
@@ -53,13 +54,18 @@ Workers::LaunchStatus Workers::m_status;
std::atomic<int> Workers::m_paused;
std::atomic<uint64_t> Workers::m_sequence;
std::list<xmrig::JobResult> Workers::m_queue;
std::vector<Handle*> Workers::m_workers;
std::vector<ThreadHandle*> Workers::m_workers;
uint64_t Workers::m_ticks = 0;
uv_async_t Workers::m_async;
uv_async_t *Workers::m_async = nullptr;
uv_mutex_t Workers::m_mutex;
uv_rwlock_t Workers::m_rwlock;
uv_timer_t Workers::m_timer;
uv_timer_t *Workers::m_timer = nullptr;
xmrig::Controller *Workers::m_controller = nullptr;
uv_rwlock_t Workers::m_rx_dataset_lock;
randomx_cache *Workers::m_rx_cache = nullptr;
randomx_dataset *Workers::m_rx_dataset = nullptr;
uint8_t Workers::m_rx_seed_hash[32] = {};
std::atomic<uint32_t> Workers::m_rx_dataset_init_thread_counter = {};
xmrig::Job Workers::job()
@@ -100,16 +106,15 @@ void Workers::printHashrate(bool detail)
}
if (detail) {
const bool isColors = m_controller->config()->isColors();
char num1[8] = { 0 };
char num2[8] = { 0 };
char num3[8] = { 0 };
Log::i()->text("%s| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |", isColors ? "\x1B[1;37m" : "");
xmrig::Log::print(WHITE_BOLD_S "| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |");
size_t i = 0;
for (const xmrig::IThread *thread : m_controller->config()->threads()) {
Log::i()->text("| %6zu | %8" PRId64 " | %7s | %7s | %7s |",
xmrig::Log::print("| %6zu | %8" PRId64 " | %7s | %7s | %7s |",
thread->index(),
thread->affinity(),
Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1),
@@ -179,7 +184,6 @@ void Workers::start(xmrig::Controller *controller)
const std::vector<xmrig::IThread *> &threads = controller->config()->threads();
m_status.algo = controller->config()->algorithm().algo();
m_status.colors = controller->config()->isColors();
m_status.threads = threads.size();
for (const xmrig::IThread *thread : threads) {
@@ -190,25 +194,27 @@ void Workers::start(xmrig::Controller *controller)
uv_mutex_init(&m_mutex);
uv_rwlock_init(&m_rwlock);
uv_rwlock_init(&m_rx_dataset_lock);
m_sequence = 1;
m_paused = 1;
uv_async_init(uv_default_loop(), &m_async, Workers::onResult);
uv_timer_init(uv_default_loop(), &m_timer);
uv_timer_start(&m_timer, Workers::onTick, 500, 500);
m_async = new uv_async_t;
uv_async_init(uv_default_loop(), m_async, Workers::onResult);
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
uv_timer_start(m_timer, Workers::onTick, 500, 500);
uint32_t offset = 0;
for (xmrig::IThread *thread : threads) {
Handle *handle = new Handle(thread, offset, m_status.ways);
ThreadHandle *handle = new ThreadHandle(thread, offset, m_status.ways);
offset += thread->multiway();
m_workers.push_back(handle);
handle->start(Workers::onReady);
}
controller->save();
}
void Workers::soft_stop() // stop current workers leaving uv stuff intact (used in switch_algo)
@@ -273,10 +279,10 @@ void Workers::switch_algo(const xmrig::Algorithm& algorithm)
void Workers::stop()
{
uv_timer_stop(&m_timer);
xmrig::Handle::close(m_timer);
xmrig::Handle::close(m_async);
m_hashrate->stop();
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), nullptr);
m_paused = 0;
m_sequence = 0;
@@ -292,11 +298,11 @@ void Workers::submit(const xmrig::JobResult &result)
m_queue.push_back(result);
uv_mutex_unlock(&m_mutex);
uv_async_send(&m_async);
uv_async_send(m_async);
}
#ifndef XMRIG_NO_API
#ifdef XMRIG_FEATURE_API
void Workers::threadsSummary(rapidjson::Document &doc)
{
uv_mutex_lock(&m_mutex);
@@ -318,7 +324,7 @@ void Workers::threadsSummary(rapidjson::Document &doc)
void Workers::onReady(void *arg)
{
auto handle = static_cast<Handle*>(arg);
auto handle = static_cast<ThreadHandle*>(arg);
IWorker *worker = nullptr;
@@ -359,7 +365,7 @@ void Workers::onReady(void *arg)
}
void Workers::onResult(uv_async_t *handle)
void Workers::onResult(uv_async_t *)
{
std::list<xmrig::JobResult> results;
@@ -378,9 +384,9 @@ void Workers::onResult(uv_async_t *handle)
}
void Workers::onTick(uv_timer_t *handle)
void Workers::onTick(uv_timer_t *)
{
for (Handle *handle : m_workers) {
for (ThreadHandle *handle : m_workers) {
if (!handle->worker()) {
return;
}
@@ -407,19 +413,71 @@ void Workers::start(IWorker *worker)
const double percent = (double) m_status.hugePages / m_status.pages * 100.0;
const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1024;
if (m_status.colors) {
LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "",
m_status.threads, m_status.ways,
(m_status.hugePages == m_status.pages ? "\x1B[1;32m" : (m_status.hugePages == 0 ? "\x1B[1;31m" : "\x1B[1;33m")),
m_status.hugePages, m_status.pages, percent, memory);
}
else {
LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %1.0f%% memory %zu KB",
m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, memory);
}
LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "",
m_status.threads, m_status.ways,
(m_status.hugePages == m_status.pages ? GREEN_BOLD_S : (m_status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
m_status.hugePages, m_status.pages, percent, memory);
}
uv_mutex_unlock(&m_mutex);
worker->start();
}
void Workers::updateDataset(const uint8_t* seed_hash, const uint32_t num_threads)
{
// Check if we need to update cache and dataset
if (memcmp(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash)) == 0)
return;
const uint32_t thread_id = m_rx_dataset_init_thread_counter++;
LOG_NOTICE("Thread %u started updating RandomX dataset", thread_id);
// Wait for all threads to get here
do {
std::this_thread::yield();
} while (m_rx_dataset_init_thread_counter.load() != num_threads);
// One of the threads updates cache
uv_rwlock_wrlock(&m_rx_dataset_lock);
if (memcmp(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash)) != 0) {
memcpy(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash));
randomx_init_cache(m_rx_cache, m_rx_seed_hash, sizeof(m_rx_seed_hash));
}
uv_rwlock_wrunlock(&m_rx_dataset_lock);
// All threads update dataset
const uint32_t a = (randomx_dataset_item_count() * thread_id) / num_threads;
const uint32_t b = (randomx_dataset_item_count() * (thread_id + 1)) / num_threads;
randomx_init_dataset(m_rx_dataset, m_rx_cache, a, b - a);
LOG_NOTICE("Thread %u finished updating RandomX dataset", thread_id);
// Wait for all threads to complete
--m_rx_dataset_init_thread_counter;
do {
std::this_thread::yield();
} while (m_rx_dataset_init_thread_counter.load() != 0);
}
randomx_dataset* Workers::getDataset()
{
if (m_rx_dataset)
return m_rx_dataset;
uv_rwlock_wrlock(&m_rx_dataset_lock);
if (!m_rx_dataset) {
randomx_dataset* dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
if (!dataset) {
dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
}
m_rx_cache = randomx_alloc_cache(static_cast<randomx_flags>(RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES));
if (!m_rx_cache) {
m_rx_cache = randomx_alloc_cache(RANDOMX_FLAG_JIT);
}
m_rx_dataset = dataset;
}
uv_rwlock_wrunlock(&m_rx_dataset_lock);
return m_rx_dataset;
}

View File

@@ -32,14 +32,15 @@
#include <uv.h>
#include <vector>
#include "common/net/Job.h"
#include "base/net/stratum/Job.h"
#include "net/JobResult.h"
#include "rapidjson/fwd.h"
#include "randomwow.h"
class Handle;
class Hashrate;
class IWorker;
class ThreadHandle;
namespace xmrig {
@@ -71,10 +72,13 @@ public:
static inline void pause() { m_active = false; m_paused = 1; m_sequence++; }
static inline void setListener(xmrig::IJobResultListener *listener) { m_listener = listener; }
# ifndef XMRIG_NO_API
# ifdef XMRIG_FEATURE_API
static void threadsSummary(rapidjson::Document &doc);
# endif
static void updateDataset(const uint8_t* seed_hash, uint32_t num_threads);
static randomx_dataset* getDataset();
private:
static void onReady(void *arg);
static void onResult(uv_async_t *handle);
@@ -86,7 +90,6 @@ private:
{
public:
inline LaunchStatus() :
colors(true),
hugePages(0),
pages(0),
started(0),
@@ -95,7 +98,6 @@ private:
algo(xmrig::CRYPTONIGHT)
{}
bool colors;
size_t hugePages;
size_t pages;
size_t started;
@@ -113,13 +115,19 @@ private:
static std::atomic<int> m_paused;
static std::atomic<uint64_t> m_sequence;
static std::list<xmrig::JobResult> m_queue;
static std::vector<Handle*> m_workers;
static std::vector<ThreadHandle*> m_workers;
static uint64_t m_ticks;
static uv_async_t m_async;
static uv_async_t *m_async;
static uv_mutex_t m_mutex;
static uv_rwlock_t m_rwlock;
static uv_timer_t m_timer;
static uv_timer_t *m_timer;
static xmrig::Controller *m_controller;
static uv_rwlock_t m_rx_dataset_lock;
static randomx_cache *m_rx_cache;
static randomx_dataset *m_rx_dataset;
static uint8_t m_rx_seed_hash[32];
static std::atomic<uint32_t> m_rx_dataset_init_thread_counter;
};