mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-23 19:16:05 +00:00
Merge remote-tracking branch 'remotes/origin/feature-advanced-threads' into dev
This commit is contained in:
commit
9be897eb6b
79 changed files with 1738 additions and 1058 deletions
|
@ -14,15 +14,17 @@ include (cmake/cpu.cmake)
|
|||
set(HEADERS
|
||||
src/api/NetworkState.h
|
||||
src/App.h
|
||||
src/common/config/CommonConfig.h
|
||||
src/common/config/ConfigLoader.h
|
||||
src/common/config/ConfigWatcher.h
|
||||
src/common/Platform.h
|
||||
src/common/utils/c_str.h
|
||||
src/common/utils/mm_malloc.h
|
||||
src/common/xmrig.h
|
||||
src/Console.h
|
||||
src/core/CommonConfig.h
|
||||
src/core/Config.cpp
|
||||
src/core/ConfigLoader.cpp
|
||||
src/core/ConfigLoader.h
|
||||
src/core/ConfigLoader_platform.h
|
||||
src/core/ConfigWatcher.cpp
|
||||
src/core/Controller.h
|
||||
src/core/utils/c_str.h
|
||||
src/Cpu.h
|
||||
src/interfaces/IClientListener.h
|
||||
src/interfaces/IConfig.h
|
||||
|
@ -51,17 +53,14 @@ set(HEADERS
|
|||
src/net/strategies/FailoverStrategy.h
|
||||
src/net/strategies/SinglePoolStrategy.h
|
||||
src/net/SubmitResult.h
|
||||
src/Platform.h
|
||||
src/Summary.h
|
||||
src/version.h
|
||||
src/workers/CpuThread.h
|
||||
src/workers/DoubleWorker.h
|
||||
src/workers/Handle.h
|
||||
src/workers/Hashrate.h
|
||||
src/workers/SingleWorker.h
|
||||
src/workers/MultiWorker.h
|
||||
src/workers/Worker.h
|
||||
src/workers/Workers.h
|
||||
src/xmrig.h
|
||||
)
|
||||
|
||||
set(HEADERS_CRYPTO
|
||||
|
@ -89,11 +88,12 @@ endif()
|
|||
set(SOURCES
|
||||
src/api/NetworkState.cpp
|
||||
src/App.cpp
|
||||
src/common/config/CommonConfig.cpp
|
||||
src/common/config/ConfigLoader.cpp
|
||||
src/common/config/ConfigWatcher.cpp
|
||||
src/common/Platform.cpp
|
||||
src/Console.cpp
|
||||
src/core/CommonConfig.cpp
|
||||
src/core/Config.cpp
|
||||
src/core/ConfigLoader.cpp
|
||||
src/core/ConfigWatcher.cpp
|
||||
src/core/Controller.cpp
|
||||
src/log/ConsoleLog.cpp
|
||||
src/log/FileLog.cpp
|
||||
|
@ -107,13 +107,11 @@ set(SOURCES
|
|||
src/net/strategies/FailoverStrategy.cpp
|
||||
src/net/strategies/SinglePoolStrategy.cpp
|
||||
src/net/SubmitResult.cpp
|
||||
src/Platform.cpp
|
||||
src/Summary.cpp
|
||||
src/workers/CpuThread.cpp
|
||||
src/workers/DoubleWorker.cpp
|
||||
src/workers/Handle.cpp
|
||||
src/workers/Hashrate.cpp
|
||||
src/workers/SingleWorker.cpp
|
||||
src/workers/MultiWorker.cpp
|
||||
src/workers/Worker.cpp
|
||||
src/workers/Workers.cpp
|
||||
src/xmrig.cpp
|
||||
|
@ -131,9 +129,9 @@ if (WIN32)
|
|||
set(SOURCES_OS
|
||||
res/app.rc
|
||||
src/App_win.cpp
|
||||
src/common/Platform_win.cpp
|
||||
src/Cpu_win.cpp
|
||||
src/Mem_win.cpp
|
||||
src/Platform_win.cpp
|
||||
)
|
||||
|
||||
add_definitions(/DWIN32)
|
||||
|
@ -141,16 +139,16 @@ if (WIN32)
|
|||
elseif (APPLE)
|
||||
set(SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_mac.cpp
|
||||
src/Cpu_mac.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/Platform_mac.cpp
|
||||
)
|
||||
else()
|
||||
set(SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/common/Platform_unix.cpp
|
||||
src/Cpu_unix.cpp
|
||||
src/Mem_unix.cpp
|
||||
src/Platform_unix.cpp
|
||||
)
|
||||
|
||||
set(EXTRA_LIBS pthread rt)
|
||||
|
@ -215,14 +213,14 @@ if (WITH_HTTPD)
|
|||
set(HTTPD_SOURCES
|
||||
src/api/Api.h
|
||||
src/api/ApiRouter.h
|
||||
src/api/HttpBody.h
|
||||
src/api/Httpd.h
|
||||
src/api/HttpReply.h
|
||||
src/api/HttpRequest.h
|
||||
src/common/api/HttpBody.h
|
||||
src/common/api/Httpd.h
|
||||
src/common/api/HttpReply.h
|
||||
src/common/api/HttpRequest.h
|
||||
src/api/Api.cpp
|
||||
src/api/ApiRouter.cpp
|
||||
src/api/Httpd.cpp
|
||||
src/api/HttpRequest.cpp
|
||||
src/common/api/Httpd.cpp
|
||||
src/common/api/HttpRequest.cpp
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
|
||||
|
|
|
@ -13,10 +13,10 @@ endif()
|
|||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
|
||||
|
|
53
doc/API.md
Normal file
53
doc/API.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# HTTP API
|
||||
|
||||
If you want use API you need choice a port where is internal HTTP server will listen for incoming connections. API will not available if miner built without `libmicrohttpd`.
|
||||
|
||||
Example configuration:
|
||||
|
||||
```json
|
||||
"api": {
|
||||
"port": 44444,
|
||||
"access-token": "TOKEN",
|
||||
"worker-id": null,
|
||||
"ipv6": false,
|
||||
"restricted": false
|
||||
},
|
||||
```
|
||||
|
||||
* **port** Port for incoming connections `http://<miner ip>:<port>`.
|
||||
* **access-token** [Bearer](https://gist.github.com/xmrig/c75fdd1f8e0f3bac05500be2ab718f8e#file-api-html-L54) access token to secure access to API.
|
||||
* **worker-id** Optional worker name, if not set will be detected automatically.
|
||||
* **ipv6** Enable (`true`) or disable (`false`) IPv6 for API.
|
||||
* **restricted** Use `false` to allow remote configuration.
|
||||
|
||||
If you prefer use command line options instead of config file, you can use options: `--api-port`, `--api-access-token`, `--api-worker-id`, `--api-ipv6` and `api-no-restricted`.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### GET /1/summary
|
||||
|
||||
Get miner summary information. [Example](api/1/summary.json).
|
||||
|
||||
### GET /1/threads
|
||||
|
||||
Get detailed information about miner threads. [Example](api/1/threads.json).
|
||||
|
||||
|
||||
## Restricted endpoints
|
||||
|
||||
All API endpoints below allow access to sensitive information and remote configure miner. You should set `access-token` and allow unrestricted access (`"restricted": false`).
|
||||
|
||||
### GET /1/config
|
||||
|
||||
Get current miner configuration. [Example](api/1/config.json).
|
||||
|
||||
|
||||
### PUT /1/config
|
||||
|
||||
Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner.
|
||||
|
||||
Curl example:
|
||||
|
||||
```
|
||||
curl -v --data-binary @config.json -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/1/config
|
||||
```
|
63
doc/api/1/config.json
Normal file
63
doc/api/1/config.json
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"algo": "cryptonight",
|
||||
"api": {
|
||||
"port": 44444,
|
||||
"access-token": "TOKEN",
|
||||
"worker-id": null,
|
||||
"ipv6": false,
|
||||
"restricted": false
|
||||
},
|
||||
"av": 1,
|
||||
"background": false,
|
||||
"colors": true,
|
||||
"cpu-affinity": null,
|
||||
"cpu-priority": null,
|
||||
"donate-level": 5,
|
||||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"log-file": null,
|
||||
"max-cpu-usage": 75,
|
||||
"pools": [
|
||||
{
|
||||
"url": "pool.monero.hashvault.pro:3333",
|
||||
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
|
||||
"pass": "x",
|
||||
"keepalive": false,
|
||||
"nicehash": false,
|
||||
"variant": -1
|
||||
},
|
||||
{
|
||||
"url": "pool.supportxmr.com:3333",
|
||||
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
|
||||
"pass": "x",
|
||||
"keepalive": false,
|
||||
"nicehash": false,
|
||||
"variant": -1
|
||||
}
|
||||
],
|
||||
"print-time": 60,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"safe": false,
|
||||
"threads": [
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 0
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 1
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 2
|
||||
},
|
||||
{
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 3
|
||||
}
|
||||
],
|
||||
"user-agent": null,
|
||||
"syslog": false,
|
||||
"watch": false
|
||||
}
|
73
doc/api/1/summary.json
Normal file
73
doc/api/1/summary.json
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"id": "92f3104f9a2ee78c",
|
||||
"worker_id": "Ubuntu-1604-xenial-64-minimal",
|
||||
"version": "2.6.0-beta3",
|
||||
"kind": "cpu",
|
||||
"ua": "XMRig/2.6.0-beta3 (Linux x86_64) libuv/1.8.0 gcc/5.4.0",
|
||||
"cpu": {
|
||||
"brand": "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz",
|
||||
"aes": true,
|
||||
"x64": true,
|
||||
"sockets": 1
|
||||
},
|
||||
"algo": "cryptonight",
|
||||
"hugepages": true,
|
||||
"donate_level": 5,
|
||||
"hashrate": {
|
||||
"total": [
|
||||
296.24,
|
||||
296.23,
|
||||
295.97
|
||||
],
|
||||
"highest": 296.5,
|
||||
"threads": [
|
||||
[
|
||||
73.39,
|
||||
73.39,
|
||||
73.28
|
||||
],
|
||||
[
|
||||
74.72,
|
||||
74.72,
|
||||
74.71
|
||||
],
|
||||
[
|
||||
74.72,
|
||||
74.72,
|
||||
74.71
|
||||
],
|
||||
[
|
||||
73.39,
|
||||
73.39,
|
||||
73.27
|
||||
]
|
||||
]
|
||||
},
|
||||
"results": {
|
||||
"diff_current": 9990,
|
||||
"shares_good": 30,
|
||||
"shares_total": 30,
|
||||
"avg_time": 31,
|
||||
"hashes_total": 311833,
|
||||
"best": [
|
||||
278199,
|
||||
181923,
|
||||
103717,
|
||||
96632,
|
||||
56154,
|
||||
51580,
|
||||
45667,
|
||||
33159,
|
||||
29581,
|
||||
29514
|
||||
],
|
||||
"error_log": []
|
||||
},
|
||||
"connection": {
|
||||
"pool": "pool.monero.hashvault.pro:3333",
|
||||
"uptime": 953,
|
||||
"ping": 35,
|
||||
"failures": 0,
|
||||
"error_log": []
|
||||
}
|
||||
}
|
65
doc/api/1/threads.json
Normal file
65
doc/api/1/threads.json
Normal file
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"hugepages": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"memory": 8388608,
|
||||
"threads": [
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 0,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
73.39,
|
||||
73.4,
|
||||
73.28
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 1,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
74.72,
|
||||
74.72,
|
||||
74.7
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 2,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
74.71,
|
||||
74.72,
|
||||
74.7
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"algo": "cryptonight",
|
||||
"av": 1,
|
||||
"low_power_mode": 1,
|
||||
"affine_to_cpu": 3,
|
||||
"priority": -1,
|
||||
"soft_aes": false,
|
||||
"hashrate": [
|
||||
73.39,
|
||||
73.4,
|
||||
73.28
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
12
src/App.cpp
12
src/App.cpp
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "api/Api.h"
|
||||
#include "App.h"
|
||||
#include "common/Platform.h"
|
||||
#include "Console.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
@ -38,14 +39,13 @@
|
|||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "net/Network.h"
|
||||
#include "Platform.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include "api/Httpd.h"
|
||||
# include "common/api/Httpd.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -76,8 +76,6 @@ App::App(int argc, char **argv) :
|
|||
|
||||
App::~App()
|
||||
{
|
||||
Mem::release();
|
||||
|
||||
uv_tty_reset_mode();
|
||||
|
||||
delete m_console;
|
||||
|
@ -101,11 +99,7 @@ int App::exec()
|
|||
|
||||
background();
|
||||
|
||||
Mem::allocate(m_controller->config()->algorithm(),
|
||||
m_controller->config()->threadsCount(),
|
||||
m_controller->config()->isDoubleHash(),
|
||||
m_controller->config()->isHugePages()
|
||||
);
|
||||
Mem::init(m_controller->config()->isHugePages());
|
||||
|
||||
Summary::print(m_controller);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "App.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
|
@ -39,11 +38,6 @@ void App::background()
|
|||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
const int64_t affinity = m_controller->config()->affinity();
|
||||
if (affinity != -1L) {
|
||||
Cpu::setAffinity(-1, affinity);
|
||||
}
|
||||
|
||||
if (!m_controller->config()->isBackground()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -27,18 +27,12 @@
|
|||
|
||||
|
||||
#include "App.h"
|
||||
#include "Cpu.h"
|
||||
#include "core/Controller.h"
|
||||
#include "core/Config.h"
|
||||
|
||||
|
||||
void App::background()
|
||||
{
|
||||
const int64_t affinity = m_controller->config()->affinity();
|
||||
if (affinity != -1L) {
|
||||
Cpu::setAffinity(-1, affinity);
|
||||
}
|
||||
|
||||
if (!m_controller->config()->isBackground()) {
|
||||
return;
|
||||
}
|
||||
|
|
39
src/Cpu.cpp
39
src/Cpu.cpp
|
@ -26,26 +26,27 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "Cpu.h"
|
||||
|
||||
|
||||
bool Cpu::m_l2_exclusive = false;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
int Cpu::m_totalThreads = 0;
|
||||
bool Cpu::m_l2_exclusive = false;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
size_t Cpu::m_totalThreads = 0;
|
||||
|
||||
|
||||
int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage)
|
||||
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
|
||||
{
|
||||
if (m_totalThreads == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cache = 0;
|
||||
size_t cache = 0;
|
||||
if (m_l3_cache) {
|
||||
cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache;
|
||||
}
|
||||
|
@ -53,22 +54,14 @@ int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage)
|
|||
cache = m_l2_cache;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int size = 2048;
|
||||
|
||||
if (algo == xmrig::CRYPTONIGHT_LITE) {
|
||||
size = 1024;
|
||||
}
|
||||
else if (algo == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
size = 4096;
|
||||
}
|
||||
|
||||
if (doubleHash) {
|
||||
size *= 2;
|
||||
}
|
||||
size_t count = 0;
|
||||
|
||||
if (cache) {
|
||||
count = cache / size;
|
||||
|
||||
if (cache % size >= size / 2) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
count = m_totalThreads / 2;
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
class Cpu
|
||||
{
|
||||
public:
|
||||
|
@ -40,9 +37,8 @@ public:
|
|||
BMI2 = 4
|
||||
};
|
||||
|
||||
static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage);
|
||||
static size_t optimalThreadsCount(size_t size, int maxCpuUsage);
|
||||
static void init();
|
||||
static void setAffinity(int id, uint64_t mask);
|
||||
|
||||
static inline bool hasAES() { return (m_flags & AES) != 0; }
|
||||
static inline bool isX64() { return (m_flags & X86_64) != 0; }
|
||||
|
@ -63,7 +59,7 @@ private:
|
|||
static int m_l3_cache;
|
||||
static int m_sockets;
|
||||
static int m_totalCores;
|
||||
static int m_totalThreads;
|
||||
static size_t m_totalThreads;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.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>
|
||||
*
|
||||
* 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
|
||||
|
@ -28,16 +28,16 @@
|
|||
#include "Cpu.h"
|
||||
|
||||
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
int Cpu::m_totalThreads = 0;
|
||||
char Cpu::m_brand[64] = { 0 };
|
||||
int Cpu::m_flags = 0;
|
||||
int Cpu::m_l2_cache = 0;
|
||||
int Cpu::m_l3_cache = 0;
|
||||
int Cpu::m_sockets = 1;
|
||||
int Cpu::m_totalCores = 0;
|
||||
size_t Cpu::m_totalThreads = 0;
|
||||
|
||||
|
||||
int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage)
|
||||
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
|
||||
{
|
||||
return m_totalThreads;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 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
|
||||
|
@ -38,8 +38,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -52,28 +52,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
cpu_set_t set;
|
||||
CPU_ZERO(&set);
|
||||
|
||||
for (int i = 0; i < m_totalThreads; i++) {
|
||||
if (mask & (1UL << i)) {
|
||||
CPU_SET(i, &set);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == -1) {
|
||||
# ifndef __FreeBSD__
|
||||
sched_setaffinity(0, sizeof(&set), &set);
|
||||
# endif
|
||||
} else {
|
||||
# ifndef __ANDROID__
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
|
||||
# else
|
||||
sched_setaffinity(gettid(), sizeof(&set), &set);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,14 +39,3 @@ void Cpu::init()
|
|||
|
||||
initCommon();
|
||||
}
|
||||
|
||||
|
||||
void Cpu::setAffinity(int id, uint64_t mask)
|
||||
{
|
||||
if (id == -1) {
|
||||
SetProcessAffinityMask(GetCurrentProcess(), mask);
|
||||
}
|
||||
else {
|
||||
SetThreadAffinityMask(GetCurrentThread(), mask);
|
||||
}
|
||||
}
|
||||
|
|
79
src/Mem.cpp
79
src/Mem.cpp
|
@ -23,70 +23,49 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
bool Mem::m_doubleHash = false;
|
||||
int Mem::m_algo = 0;
|
||||
int Mem::m_flags = 0;
|
||||
int Mem::m_threads = 0;
|
||||
size_t Mem::m_offset = 0;
|
||||
size_t Mem::m_size = 0;
|
||||
alignas(16) uint8_t *Mem::m_memory = nullptr;
|
||||
bool Mem::m_enabled = true;
|
||||
int Mem::m_flags = 0;
|
||||
|
||||
|
||||
cryptonight_ctx *Mem::create(int threadId)
|
||||
|
||||
MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count)
|
||||
{
|
||||
using namespace xmrig;
|
||||
|
||||
MemInfo info;
|
||||
info.size = cn_select_memory(algorithm) * count;
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_algo == xmrig::CRYPTONIGHT_LITE) {
|
||||
return createLite(threadId);
|
||||
}
|
||||
info.size += info.size % cn_select_memory<CRYPTONIGHT>();
|
||||
# endif
|
||||
|
||||
const size_t size = m_algo == xmrig::CRYPTONIGHT_HEAVY ? xmrig::cn_select_memory<xmrig::CRYPTONIGHT_HEAVY>()
|
||||
: xmrig::cn_select_memory<xmrig::CRYPTONIGHT>();
|
||||
info.pages = info.size / cn_select_memory<CRYPTONIGHT>();
|
||||
|
||||
cryptonight_ctx *ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[size - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||
allocate(info, m_enabled);
|
||||
|
||||
const int ratio = m_doubleHash ? 2 : 1;
|
||||
ctx->memory = &m_memory[size * (threadId * ratio + 1)];
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
cryptonight_ctx *c = static_cast<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 4096));
|
||||
c->memory = info.memory + (i * cn_select_memory(algorithm));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *Mem::calloc(size_t num, size_t size)
|
||||
{
|
||||
void *mem = &m_memory[m_offset];
|
||||
m_offset += (num * size);
|
||||
|
||||
memset(mem, 0, num * size);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
cryptonight_ctx *Mem::createLite(int threadId) {
|
||||
cryptonight_ctx *ctx;
|
||||
|
||||
if (!m_doubleHash) {
|
||||
const size_t offset = MONERO_MEMORY * (threadId + 1);
|
||||
|
||||
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[offset + AEON_MEMORY]);
|
||||
ctx->memory = &m_memory[offset];
|
||||
return ctx;
|
||||
ctx[i] = c;
|
||||
}
|
||||
|
||||
ctx = reinterpret_cast<cryptonight_ctx *>(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
|
||||
ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)];
|
||||
|
||||
return ctx;
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info)
|
||||
{
|
||||
release(info);
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
_mm_free(ctx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
src/Mem.h
37
src/Mem.h
|
@ -30,12 +30,22 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "xmrig.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
struct cryptonight_ctx;
|
||||
|
||||
|
||||
struct MemInfo
|
||||
{
|
||||
alignas(16) uint8_t *memory;
|
||||
|
||||
size_t hugePages;
|
||||
size_t pages;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
class Mem
|
||||
{
|
||||
public:
|
||||
|
@ -45,29 +55,18 @@ public:
|
|||
Lock = 4
|
||||
};
|
||||
|
||||
static bool allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled);
|
||||
static cryptonight_ctx *create(int threadId);
|
||||
static void *calloc(size_t num, size_t size);
|
||||
static void release();
|
||||
static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count);
|
||||
static void init(bool enabled);
|
||||
static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info);
|
||||
|
||||
static inline bool isDoubleHash() { return m_doubleHash; }
|
||||
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
|
||||
static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; }
|
||||
static inline int flags() { return m_flags; }
|
||||
static inline int threads() { return m_threads; }
|
||||
|
||||
private:
|
||||
static bool m_doubleHash;
|
||||
static int m_algo;
|
||||
static int m_flags;
|
||||
static int m_threads;
|
||||
static size_t m_offset;
|
||||
static size_t m_size;
|
||||
alignas(16) static uint8_t *m_memory;
|
||||
static void allocate(MemInfo &info, bool enabled);
|
||||
static void release(MemInfo &info);
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
static cryptonight_ctx *createLite(int threadId);
|
||||
# endif
|
||||
static int m_flags;
|
||||
static bool m_enabled;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,75 +27,63 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled)
|
||||
void Mem::init(bool enabled)
|
||||
{
|
||||
m_algo = algo;
|
||||
m_threads = threads;
|
||||
m_doubleHash = doubleHash;
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
m_size = MONERO_MEMORY * (threads * ratio + 1);
|
||||
|
||||
if (algo == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
m_size *= 2;
|
||||
}
|
||||
void Mem::allocate(MemInfo &info, bool enabled)
|
||||
{
|
||||
info.hugePages = 0;
|
||||
|
||||
if (!enabled) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
}
|
||||
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
|
||||
|
||||
m_flags |= HugepagesAvailable;
|
||||
return;
|
||||
}
|
||||
|
||||
# if defined(__APPLE__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
|
||||
# elif defined(__FreeBSD__)
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
|
||||
# else
|
||||
m_memory = static_cast<uint8_t*>(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
|
||||
# endif
|
||||
if (m_memory == MAP_FAILED) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
|
||||
if (info.memory == MAP_FAILED) {
|
||||
return allocate(info, false);;
|
||||
}
|
||||
|
||||
m_flags |= HugepagesEnabled;
|
||||
info.hugePages = info.pages;
|
||||
|
||||
if (madvise(m_memory, m_size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
|
||||
LOG_ERR("madvise failed");
|
||||
}
|
||||
|
||||
if (mlock(m_memory, m_size) == 0) {
|
||||
if (mlock(info.memory, info.size) == 0) {
|
||||
m_flags |= Lock;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::release(MemInfo &info)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
if (info.hugePages) {
|
||||
if (m_flags & Lock) {
|
||||
munlock(m_memory, m_size);
|
||||
munlock(info.memory, info.size);
|
||||
}
|
||||
|
||||
munmap(m_memory, m_size);
|
||||
munmap(info.memory, info.size);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(info.memory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,16 +28,13 @@
|
|||
#include <ntsecapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
|
@ -145,46 +142,43 @@ static BOOL TrySetLockPagesPrivilege() {
|
|||
}
|
||||
|
||||
|
||||
bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled)
|
||||
void Mem::init(bool enabled)
|
||||
{
|
||||
m_algo = algo;
|
||||
m_threads = threads;
|
||||
m_doubleHash = doubleHash;
|
||||
m_enabled = enabled;
|
||||
|
||||
const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1;
|
||||
m_size = MONERO_MEMORY * (threads * ratio + 1);
|
||||
|
||||
if (algo == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
m_size *= 2;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TrySetLockPagesPrivilege()) {
|
||||
if (enabled && TrySetLockPagesPrivilege()) {
|
||||
m_flags |= HugepagesAvailable;
|
||||
}
|
||||
|
||||
m_memory = static_cast<uint8_t*>(VirtualAlloc(NULL, m_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (!m_memory) {
|
||||
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
|
||||
}
|
||||
else {
|
||||
m_flags |= HugepagesEnabled;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Mem::release()
|
||||
void Mem::allocate(MemInfo &info, bool enabled)
|
||||
{
|
||||
if (m_flags & HugepagesEnabled) {
|
||||
VirtualFree(m_memory, 0, MEM_RELEASE);
|
||||
info.hugePages = 0;
|
||||
|
||||
if (!enabled) {
|
||||
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
info.memory = static_cast<uint8_t*>(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
|
||||
if (info.memory) {
|
||||
info.hugePages = info.pages;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
allocate(info, false);
|
||||
}
|
||||
|
||||
|
||||
void Mem::release(MemInfo &info)
|
||||
{
|
||||
if (info.hugePages) {
|
||||
VirtualFree(info.memory, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_memory);
|
||||
_mm_free(info.memory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,14 +58,15 @@ static void print_versions(xmrig::Config *config)
|
|||
|
||||
|
||||
static void print_memory(xmrig::Config *config) {
|
||||
# ifdef _WIN32
|
||||
if (config->isColors()) {
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
|
||||
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
|
||||
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
|
||||
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s",
|
||||
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable");
|
||||
}
|
||||
else {
|
||||
Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled");
|
||||
Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable");
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,21 +93,30 @@ static void print_cpu(xmrig::Config *config)
|
|||
|
||||
static void print_threads(xmrig::Config *config)
|
||||
{
|
||||
char buf[32];
|
||||
if (config->affinity() != -1L) {
|
||||
snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity());
|
||||
if (config->threadsMode() != xmrig::Config::Advanced) {
|
||||
char buf[32];
|
||||
if (config->affinity() != -1L) {
|
||||
snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity());
|
||||
}
|
||||
else {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
|
||||
config->threadsCount(),
|
||||
config->algoName(),
|
||||
config->algoVariant(),
|
||||
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
config->donateLevel(),
|
||||
buf);
|
||||
}
|
||||
else {
|
||||
buf[0] = '\0';
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%",
|
||||
config->threadsCount(),
|
||||
config->algoName(),
|
||||
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
config->donateLevel());
|
||||
}
|
||||
|
||||
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
|
||||
config->threadsCount(),
|
||||
config->algoName(),
|
||||
config->algoVariant(),
|
||||
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "",
|
||||
config->donateLevel(),
|
||||
buf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
#include "api/Api.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
|
||||
|
||||
ApiRouter *Api::m_router = nullptr;
|
||||
|
@ -62,16 +62,6 @@ void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
|||
}
|
||||
|
||||
|
||||
void Api::tick(const Hashrate *hashrate)
|
||||
{
|
||||
if (!m_router) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_router->tick(hashrate);
|
||||
}
|
||||
|
||||
|
||||
void Api::tick(const NetworkState &network)
|
||||
{
|
||||
if (!m_router) {
|
||||
|
|
|
@ -47,7 +47,6 @@ public:
|
|||
static void release();
|
||||
|
||||
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
static void tick(const Hashrate *hashrate);
|
||||
static void tick(const NetworkState &results);
|
||||
|
||||
private:
|
||||
|
|
|
@ -33,20 +33,21 @@
|
|||
|
||||
|
||||
#include "api/ApiRouter.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "interfaces/IThread.h"
|
||||
#include "Mem.h"
|
||||
#include "net/Job.h"
|
||||
#include "Platform.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "version.h"
|
||||
#include "workers/Hashrate.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
|
@ -68,10 +69,6 @@ static inline double normalize(double d)
|
|||
ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
m_threads = controller->config()->threadsCount();
|
||||
m_hashrate = new double[m_threads * 3]();
|
||||
|
||||
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
|
||||
memset(m_workerId, 0, sizeof(m_workerId));
|
||||
|
||||
setWorkerId(controller->config()->apiWorkerId());
|
||||
|
@ -81,7 +78,6 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
|||
|
||||
ApiRouter::~ApiRouter()
|
||||
{
|
||||
delete [] m_hashrate;
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,21 +125,6 @@ void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
|||
}
|
||||
|
||||
|
||||
void ApiRouter::tick(const Hashrate *hashrate)
|
||||
{
|
||||
for (int i = 0; i < m_threads; ++i) {
|
||||
m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval);
|
||||
m_hashrate[i * 3 + 1] = hashrate->calc((size_t) i, Hashrate::MediumInterval);
|
||||
m_hashrate[i * 3 + 2] = hashrate->calc((size_t) i, Hashrate::LargeInterval);
|
||||
}
|
||||
|
||||
m_totalHashrate[0] = hashrate->calc(Hashrate::ShortInterval);
|
||||
m_totalHashrate[1] = hashrate->calc(Hashrate::MediumInterval);
|
||||
m_totalHashrate[2] = hashrate->calc(Hashrate::LargeInterval);
|
||||
m_highestHashrate = hashrate->highest();
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::tick(const NetworkState &network)
|
||||
{
|
||||
m_network = network;
|
||||
|
@ -225,21 +206,23 @@ void ApiRouter::getHashrate(rapidjson::Document &doc) const
|
|||
rapidjson::Value total(rapidjson::kArrayType);
|
||||
rapidjson::Value threads(rapidjson::kArrayType);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
total.PushBack(normalize(m_totalHashrate[i]), allocator);
|
||||
}
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
for (int i = 0; i < m_threads * 3; i += 3) {
|
||||
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
|
||||
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
|
||||
|
||||
for (size_t i = 0; i < Workers::threads(); i++) {
|
||||
rapidjson::Value thread(rapidjson::kArrayType);
|
||||
thread.PushBack(normalize(m_hashrate[i]), allocator);
|
||||
thread.PushBack(normalize(m_hashrate[i + 1]), allocator);
|
||||
thread.PushBack(normalize(m_hashrate[i + 2]), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||
|
||||
threads.PushBack(thread, allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
hashrate.AddMember("highest", normalize(m_highestHashrate), allocator);
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
|
||||
hashrate.AddMember("threads", threads, allocator);
|
||||
doc.AddMember("hashrate", hashrate, allocator);
|
||||
}
|
||||
|
@ -267,7 +250,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const
|
|||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
doc.AddMember("cpu", cpu, allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator);
|
||||
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
|
||||
doc.AddMember("hugepages", Workers::hugePages() > 0, allocator);
|
||||
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
|
||||
}
|
||||
|
||||
|
@ -298,13 +281,28 @@ void ApiRouter::getResults(rapidjson::Document &doc) const
|
|||
|
||||
void ApiRouter::getThreads(rapidjson::Document &doc) const
|
||||
{
|
||||
doc.SetArray();
|
||||
doc.SetObject();
|
||||
auto &allocator = doc.GetAllocator();
|
||||
const Hashrate *hr = Workers::hashrate();
|
||||
|
||||
Workers::threadsSummary(doc);
|
||||
|
||||
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
|
||||
rapidjson::Value list(rapidjson::kArrayType);
|
||||
|
||||
for (const xmrig::IThread *thread : threads) {
|
||||
doc.PushBack(thread->toAPI(doc), doc.GetAllocator());
|
||||
rapidjson::Value value = thread->toAPI(doc);
|
||||
|
||||
rapidjson::Value hashrate(rapidjson::kArrayType);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::ShortInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::MediumInterval)), allocator);
|
||||
hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::LargeInterval)), allocator);
|
||||
|
||||
value.AddMember("hashrate", hashrate, allocator);
|
||||
list.PushBack(value, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("threads", list, allocator);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ public:
|
|||
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
||||
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
|
||||
void tick(const Hashrate *hashrate);
|
||||
void tick(const NetworkState &results);
|
||||
|
||||
protected:
|
||||
|
@ -69,10 +68,6 @@ private:
|
|||
|
||||
char m_id[17];
|
||||
char m_workerId[128];
|
||||
double *m_hashrate;
|
||||
double m_highestHashrate;
|
||||
double m_totalHashrate[3];
|
||||
int m_threads;
|
||||
NetworkState m_network;
|
||||
xmrig::Controller *m_controller;
|
||||
};
|
||||
|
|
|
@ -29,16 +29,16 @@
|
|||
#include "Platform.h"
|
||||
|
||||
|
||||
char *Platform::m_defaultConfigName = nullptr;
|
||||
char *Platform::m_userAgent = nullptr;
|
||||
char Platform::m_defaultConfigName[520] = { 0 };
|
||||
xmrig::c_str Platform::m_userAgent;
|
||||
|
||||
|
||||
const char *Platform::defaultConfigName()
|
||||
{
|
||||
size_t size = 520;
|
||||
|
||||
if (m_defaultConfigName == nullptr) {
|
||||
m_defaultConfigName = new char[size];
|
||||
if (*m_defaultConfigName) {
|
||||
return m_defaultConfigName;
|
||||
}
|
||||
|
||||
if (uv_exepath(m_defaultConfigName, &size) < 0) {
|
||||
|
@ -58,5 +58,6 @@ const char *Platform::defaultConfigName()
|
|||
}
|
||||
}
|
||||
|
||||
*m_defaultConfigName = '\0';
|
||||
return nullptr;
|
||||
}
|
|
@ -25,20 +25,26 @@
|
|||
#define __PLATFORM_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/utils/c_str.h"
|
||||
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
static bool setThreadAffinity(uint64_t cpu_id);
|
||||
static const char *defaultConfigName();
|
||||
static void init(const char *userAgent);
|
||||
static void release();
|
||||
static void setProcessPriority(int priority);
|
||||
static void setThreadPriority(int priority);
|
||||
|
||||
static inline const char *userAgent() { return m_userAgent; }
|
||||
static inline const char *userAgent() { return m_userAgent.data(); }
|
||||
|
||||
private:
|
||||
static char *m_defaultConfigName;
|
||||
static char *m_userAgent;
|
||||
static char m_defaultConfigName[520];
|
||||
static xmrig::c_str m_userAgent;
|
||||
};
|
||||
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
|
@ -53,15 +55,24 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
thread_port_t mach_thread;
|
||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) };
|
||||
mach_thread = pthread_mach_thread_np(pthread_self());
|
||||
|
||||
return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +21,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <sys/types.h>
|
||||
# include <sys/param.h>
|
||||
# include <sys/cpuset.h>
|
||||
# include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -37,6 +45,11 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
typedef cpuset_t cpu_set_t;
|
||||
#endif
|
||||
|
||||
|
||||
static inline char *createUserAgent()
|
||||
{
|
||||
const size_t max = 160;
|
||||
|
@ -63,15 +76,28 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
cpu_set_t mn;
|
||||
CPU_ZERO(&mn);
|
||||
CPU_SET(cpu_id, &mn);
|
||||
|
||||
# ifndef __ANDROID__
|
||||
return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mn) == 0;
|
||||
# else
|
||||
return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,9 +27,11 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
# include "nvidia/cryptonight.h"
|
||||
#endif
|
||||
|
@ -82,16 +84,24 @@ static inline char *createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
|
||||
if (cpu_id >= 64) {
|
||||
LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63.");
|
||||
}
|
||||
|
||||
return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform::release()
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
delete [] m_defaultConfigName;
|
||||
delete [] m_userAgent;
|
||||
if (userAgent) {
|
||||
m_userAgent = userAgent;
|
||||
}
|
||||
else {
|
||||
m_userAgent = createUserAgent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +141,6 @@ void Platform::setProcessPriority(int priority)
|
|||
}
|
||||
|
||||
|
||||
|
||||
void Platform::setThreadPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
|
@ -25,9 +25,9 @@
|
|||
#include <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "api/HttpBody.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "common/api/HttpBody.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
|
||||
|
||||
#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "api/Httpd.h"
|
||||
#include "api/HttpReply.h"
|
||||
#include "api/HttpRequest.h"
|
||||
#include "common/api/Httpd.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
|
|
@ -29,14 +29,13 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "core/CommonConfig.h"
|
||||
#include "common/config/CommonConfig.h"
|
||||
#include "donate.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Pool.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
xmrig::CommonConfig::CommonConfig() :
|
||||
|
@ -206,12 +205,12 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
|
|||
case SyslogKey: /* --syslog */
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
case NicehashKey: /* --nicehash */
|
||||
case ApiIPv6Key: /* --api-ipv6 */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case ColorKey: /* --no-color */
|
||||
case WatchKey: /* --no-watch */
|
||||
case ApiRestrictedKey: /* --api-no-restricted */
|
||||
case ApiIPv6Key: /* --api-no-ipv6 */
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case DonateLevelKey: /* --donate-level */
|
|
@ -28,10 +28,10 @@
|
|||
#include <vector>
|
||||
|
||||
|
||||
#include "core/utils/c_str.h"
|
||||
#include "common/utils/c_str.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "interfaces/IConfig.h"
|
||||
#include "net/Pool.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
|
@ -32,14 +32,14 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/ConfigLoader_platform.h"
|
||||
#include "core/ConfigWatcher.h"
|
||||
#include "interfaces/IConfig.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "net/Pool.h"
|
||||
#include "Platform.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/filereadstream.h"
|
|
@ -25,9 +25,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/ConfigWatcher.h"
|
||||
#include "interfaces/IWatcherListener.h"
|
||||
#include "log/Log.h"
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "core/utils/c_str.h"
|
||||
#include "common/utils/c_str.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
|
@ -5,7 +5,6 @@
|
|||
* 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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
@ -22,35 +21,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SINGLEWORKER_H__
|
||||
#define __SINGLEWORKER_H__
|
||||
#ifndef __MM_MALLOC_PORTABLE_H__
|
||||
#define __MM_MALLOC_PORTABLE_H__
|
||||
|
||||
|
||||
#include "net/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "workers/Worker.h"
|
||||
#ifdef _WIN32
|
||||
# ifdef __GNUC__
|
||||
# include <mm_malloc.h>
|
||||
# else
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#else
|
||||
# if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
# else
|
||||
# include <mm_malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
class Handle;
|
||||
|
||||
|
||||
class SingleWorker : public Worker
|
||||
{
|
||||
public:
|
||||
SingleWorker(Handle *handle);
|
||||
|
||||
bool start() override;
|
||||
|
||||
private:
|
||||
bool resume(const Job &job);
|
||||
bool selfTest();
|
||||
void consumeJob();
|
||||
void save(const Job &job);
|
||||
|
||||
Job m_job;
|
||||
Job m_paused;
|
||||
JobResult m_result;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __SINGLEWORKER_H__ */
|
||||
#endif /* __MM_MALLOC_PORTABLE_H__ */
|
|
@ -64,6 +64,13 @@ enum Variant {
|
|||
};
|
||||
|
||||
|
||||
enum AesMode {
|
||||
AES_AUTO,
|
||||
AES_HW,
|
||||
AES_SOFT
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
|
@ -26,32 +26,29 @@
|
|||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "Cpu.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "net/Pool.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "workers/CpuThread.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
static char affinity_tmp[20] = { 0 };
|
||||
|
||||
|
||||
xmrig::Config::Config() : xmrig::CommonConfig(),
|
||||
m_aesMode(AES_AUTO),
|
||||
m_algoVariant(AV_AUTO),
|
||||
m_doubleHash(false),
|
||||
m_dryRun(false),
|
||||
m_hugePages(true),
|
||||
m_safe(false),
|
||||
m_maxCpuUsage(75),
|
||||
m_printTime(60),
|
||||
m_priority(-1),
|
||||
m_affinity(-1L),
|
||||
m_threadsCount(0)
|
||||
m_priority(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -69,53 +66,49 @@ bool xmrig::Config::reload(const char *json)
|
|||
|
||||
void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
doc.SetObject();
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator);
|
||||
doc.AddMember("algo", StringRef(algoName()), allocator);
|
||||
|
||||
rapidjson::Value api(rapidjson::kObjectType);
|
||||
Value api(kObjectType);
|
||||
api.AddMember("port", apiPort(), allocator);
|
||||
api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator);
|
||||
api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator);
|
||||
api.AddMember("ipv6", isApiIPv6(), allocator);
|
||||
api.AddMember("restricted", isApiRestricted(), allocator);
|
||||
doc.AddMember("api", api, allocator);
|
||||
|
||||
doc.AddMember("av", algoVariant(), allocator);
|
||||
doc.AddMember("background", isBackground(), allocator);
|
||||
|
||||
doc.AddMember("colors", isColors(), allocator);
|
||||
doc.AddMember("colors", isColors(), allocator);
|
||||
|
||||
if (affinity() != -1L) {
|
||||
snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity());
|
||||
doc.AddMember("cpu-affinity", rapidjson::StringRef(affinity_tmp), allocator);
|
||||
doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("cpu-affinity", rapidjson::kNullType, allocator);
|
||||
}
|
||||
|
||||
if (priority() != -1) {
|
||||
doc.AddMember("cpu-priority", priority(), allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("cpu-priority", rapidjson::kNullType, allocator);
|
||||
doc.AddMember("cpu-affinity", kNullType, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
doc.AddMember("donate-level", donateLevel(), allocator);
|
||||
doc.AddMember("huge-pages", isHugePages(), allocator);
|
||||
doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator);
|
||||
doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator);
|
||||
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
|
||||
|
||||
rapidjson::Value pools(rapidjson::kArrayType);
|
||||
Value pools(kArrayType);
|
||||
|
||||
for (const Pool &pool : m_pools) {
|
||||
rapidjson::Value obj(rapidjson::kObjectType);
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember("url", rapidjson::StringRef(pool.url()), allocator);
|
||||
obj.AddMember("user", rapidjson::StringRef(pool.user()), allocator);
|
||||
obj.AddMember("pass", rapidjson::StringRef(pool.password()), allocator);
|
||||
obj.AddMember("url", StringRef(pool.url()), allocator);
|
||||
obj.AddMember("user", StringRef(pool.user()), allocator);
|
||||
obj.AddMember("pass", StringRef(pool.password()), allocator);
|
||||
|
||||
if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) {
|
||||
obj.AddMember("keepalive", pool.keepAlive() > 0, allocator);
|
||||
|
@ -135,8 +128,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
|||
doc.AddMember("retries", retries(), allocator);
|
||||
doc.AddMember("retry-pause", retryPause(), allocator);
|
||||
doc.AddMember("safe", m_safe, allocator);
|
||||
doc.AddMember("threads", threadsCount(), allocator);
|
||||
doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
|
||||
|
||||
if (threadsMode() == Advanced) {
|
||||
Value threads(kArrayType);
|
||||
|
||||
for (const IThread *thread : m_threads.list) {
|
||||
threads.PushBack(thread->toConfig(doc), doc.GetAllocator());
|
||||
}
|
||||
|
||||
doc.AddMember("threads", threads, allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
doc.AddMember("syslog", isSyslog(), allocator);
|
||||
|
@ -158,23 +164,34 @@ bool xmrig::Config::adjust()
|
|||
return false;
|
||||
}
|
||||
|
||||
m_algoVariant = getAlgoVariant();
|
||||
if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) {
|
||||
m_doubleHash = true;
|
||||
if (!m_threads.cpu.empty()) {
|
||||
m_threads.mode = Advanced;
|
||||
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
|
||||
|
||||
for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, softAES));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_threadsCount) {
|
||||
m_threadsCount = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage);
|
||||
m_algoVariant = getAlgoVariant();
|
||||
m_threads.mode = m_threads.count ? Simple : Automatic;
|
||||
|
||||
const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm) / 1024;
|
||||
|
||||
if (!m_threads.count) {
|
||||
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
}
|
||||
else if (m_safe) {
|
||||
const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage);
|
||||
if (m_threadsCount > count) {
|
||||
m_threadsCount = count;
|
||||
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
if (m_threads.count > count) {
|
||||
m_threads.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_threadsCount; ++i) {
|
||||
m_threads.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_affinity, m_priority));
|
||||
for (size_t i = 0; i < m_threads.count; ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_threads.mask, m_priority));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -188,18 +205,22 @@ bool xmrig::Config::parseBoolean(int key, bool enable)
|
|||
}
|
||||
|
||||
switch (key) {
|
||||
case xmrig::IConfig::SafeKey: /* --safe */
|
||||
case IConfig::SafeKey: /* --safe */
|
||||
m_safe = enable;
|
||||
break;
|
||||
|
||||
case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */
|
||||
case IConfig::HugePagesKey: /* --no-huge-pages */
|
||||
m_hugePages = enable;
|
||||
break;
|
||||
|
||||
case xmrig::IConfig::DryRunKey: /* --dry-run */
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
m_dryRun = enable;
|
||||
break;
|
||||
|
||||
case IConfig::HardwareAESKey: /* hw-aes config only */
|
||||
m_aesMode = enable ? AES_HW : AES_SOFT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -229,7 +250,7 @@ bool xmrig::Config::parseString(int key, const char *arg)
|
|||
|
||||
case xmrig::IConfig::ThreadsKey: /* --threads */
|
||||
if (strncmp(arg, "all", 3) == 0) {
|
||||
m_threadsCount = Cpu::threads();
|
||||
m_threads.count = Cpu::threads();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -258,7 +279,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
|||
switch (key) {
|
||||
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */
|
||||
if (arg) {
|
||||
m_affinity = arg;
|
||||
m_threads.mask = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -272,6 +293,23 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
|||
|
||||
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
|
||||
{
|
||||
const rapidjson::Value &threads = doc["threads"];
|
||||
|
||||
if (threads.IsArray()) {
|
||||
for (const rapidjson::Value &value : threads.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.HasMember("low_power_mode")) {
|
||||
auto data = CpuThread::parse(value);
|
||||
|
||||
if (data.valid) {
|
||||
m_threads.cpu.push_back(std::move(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,7 +318,7 @@ bool xmrig::Config::parseInt(int key, int arg)
|
|||
switch (key) {
|
||||
case xmrig::IConfig::ThreadsKey: /* --threads */
|
||||
if (arg >= 0 && arg < 1024) {
|
||||
m_threadsCount = arg;
|
||||
m_threads.count = arg;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -29,9 +29,10 @@
|
|||
#include <vector>
|
||||
|
||||
|
||||
#include "core/CommonConfig.h"
|
||||
#include "common/config/CommonConfig.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
#include "xmrig.h"
|
||||
#include "workers/CpuThread.h"
|
||||
|
||||
|
||||
class Addr;
|
||||
|
@ -60,6 +61,13 @@ class IWatcherListener;
|
|||
class Config : public CommonConfig
|
||||
{
|
||||
public:
|
||||
enum ThreadsMode {
|
||||
Automatic,
|
||||
Simple,
|
||||
Advanced
|
||||
};
|
||||
|
||||
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
|
@ -67,15 +75,15 @@ public:
|
|||
|
||||
void getJSON(rapidjson::Document &doc) const override;
|
||||
|
||||
inline AesMode aesMode() const { return m_aesMode; }
|
||||
inline AlgoVariant algoVariant() const { return m_algoVariant; }
|
||||
inline bool isDoubleHash() const { return m_doubleHash; }
|
||||
inline bool isDryRun() const { return m_dryRun; }
|
||||
inline bool isHugePages() const { return m_hugePages; }
|
||||
inline const std::vector<IThread *> &threads() const { return m_threads; }
|
||||
inline int printTime() const { return m_printTime; }
|
||||
inline const std::vector<IThread *> &threads() const { return m_threads.list; }
|
||||
inline int priority() const { return m_priority; }
|
||||
inline int threadsCount() const { return m_threadsCount; }
|
||||
inline int64_t affinity() const { return m_affinity; }
|
||||
inline int threadsCount() const { return m_threads.list.size(); }
|
||||
inline int64_t affinity() const { return m_threads.mask; }
|
||||
inline ThreadsMode threadsMode() const { return m_threads.mode; }
|
||||
|
||||
static Config *load(int argc, char **argv, IWatcherListener *listener);
|
||||
|
||||
|
@ -94,17 +102,27 @@ private:
|
|||
AlgoVariant getAlgoVariantLite() const;
|
||||
# endif
|
||||
|
||||
|
||||
struct Threads
|
||||
{
|
||||
inline Threads() : mask(-1L), count(0), mode(Automatic) {}
|
||||
|
||||
int64_t mask;
|
||||
size_t count;
|
||||
std::vector<CpuThread::Data> cpu;
|
||||
std::vector<IThread *> list;
|
||||
ThreadsMode mode;
|
||||
};
|
||||
|
||||
|
||||
AesMode m_aesMode;
|
||||
AlgoVariant m_algoVariant;
|
||||
bool m_doubleHash;
|
||||
bool m_dryRun;
|
||||
bool m_hugePages;
|
||||
bool m_safe;
|
||||
int m_maxCpuUsage;
|
||||
int m_printTime;
|
||||
int m_priority;
|
||||
int64_t m_affinity;
|
||||
size_t m_threadsCount;
|
||||
std::vector<IThread *> m_threads;
|
||||
Threads m_threads;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ Options:\n\
|
|||
--api-port=N port for the miner API\n\
|
||||
--api-access-token=T access token for API\n\
|
||||
--api-worker-id=ID custom worker-id for API\n\
|
||||
--api-ipv6 enable IPv6 support for API\n\
|
||||
--api-no-restricted enable full remote access (only if API token set)\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
";
|
||||
|
@ -98,7 +100,7 @@ static struct option const options[] = {
|
|||
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
|
||||
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
|
||||
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
|
||||
{ "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
|
||||
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
|
||||
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
|
||||
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
|
||||
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
|
||||
|
@ -150,6 +152,7 @@ static struct option const config_options[] = {
|
|||
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
|
||||
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
|
||||
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
|
||||
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
#include <assert.h>
|
||||
|
||||
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/ConfigLoader.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Cpu.h"
|
||||
#include "interfaces/IControllerListener.h"
|
||||
|
@ -34,7 +35,6 @@
|
|||
#include "log/FileLog.h"
|
||||
#include "log/Log.h"
|
||||
#include "net/Network.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
|
@ -73,7 +73,6 @@ xmrig::Controller::Controller()
|
|||
xmrig::Controller::~Controller()
|
||||
{
|
||||
ConfigLoader::release();
|
||||
Platform::release();
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
|
|
|
@ -30,18 +30,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#define AEON_MEMORY 1048576
|
||||
#define AEON_MASK 0xFFFF0
|
||||
#define AEON_ITER 0x40000
|
||||
|
||||
#define MONERO_MEMORY 2097152
|
||||
#define MONERO_MASK 0x1FFFF0
|
||||
#define MONERO_ITER 0x80000
|
||||
|
||||
|
||||
struct cryptonight_ctx {
|
||||
alignas(16) uint8_t state0[200];
|
||||
alignas(16) uint8_t state1[200];
|
||||
alignas(16) uint8_t state[200];
|
||||
alignas(16) uint8_t* memory;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,13 +27,7 @@
|
|||
#define __CRYPTONIGHT_ARM_H__
|
||||
|
||||
|
||||
#if defined(XMRIG_ARM) && !defined(__clang__)
|
||||
# include "aligned_malloc.h"
|
||||
#else
|
||||
# include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/utils/mm_malloc.h"
|
||||
#include "crypto/CryptoNight.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "crypto/CryptoNight_monero.h"
|
||||
|
@ -79,6 +73,19 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_ARMv8
|
||||
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
|
||||
{
|
||||
alignas(16) const __m128i zero = { 0 };
|
||||
return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey );
|
||||
}
|
||||
#else
|
||||
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* this one was not implemented yet so here it is */
|
||||
static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a)
|
||||
{
|
||||
|
@ -161,19 +168,19 @@ static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, _
|
|||
*k0 = xout0;
|
||||
*k1 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x01>(&xout0, &xout2);
|
||||
*k2 = xout0;
|
||||
*k3 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x02>(&xout0, &xout2);
|
||||
*k4 = xout0;
|
||||
*k5 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x04>(&xout0, &xout2);
|
||||
*k6 = xout0;
|
||||
*k7 = xout2;
|
||||
|
||||
SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||
soft_aes_genkey_sub<0x08>(&xout0, &xout2);
|
||||
*k8 = xout0;
|
||||
*k9 = xout2;
|
||||
}
|
||||
|
@ -192,18 +199,16 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
|
|||
*x6 = soft_aesenc((uint32_t*)x6, key);
|
||||
*x7 = soft_aesenc((uint32_t*)x7, key);
|
||||
}
|
||||
# ifndef XMRIG_ARMv7
|
||||
else {
|
||||
*x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key));
|
||||
*x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key));
|
||||
*x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key));
|
||||
*x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key));
|
||||
*x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key));
|
||||
*x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key));
|
||||
*x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key));
|
||||
*x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key));
|
||||
*x0 = _mm_aesenc_si128(*x0, key);
|
||||
*x1 = _mm_aesenc_si128(*x1, key);
|
||||
*x2 = _mm_aesenc_si128(*x2, key);
|
||||
*x3 = _mm_aesenc_si128(*x3, key);
|
||||
*x4 = _mm_aesenc_si128(*x4, key);
|
||||
*x5 = _mm_aesenc_si128(*x5, key);
|
||||
*x6 = _mm_aesenc_si128(*x6, key);
|
||||
*x7 = _mm_aesenc_si128(*x7, key);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,10 +245,6 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
@ -253,30 +254,13 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xin0 ^= k9;
|
||||
xin1 ^= k9;
|
||||
xin2 ^= k9;
|
||||
xin3 ^= k9;
|
||||
xin4 ^= k9;
|
||||
xin5 ^= k9;
|
||||
xin6 ^= k9;
|
||||
xin7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) {
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
@ -286,20 +270,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xin0 ^= k9;
|
||||
xin1 ^= k9;
|
||||
xin2 ^= k9;
|
||||
xin3 ^= k9;
|
||||
xin4 ^= k9;
|
||||
xin5 ^= k9;
|
||||
xin6 ^= k9;
|
||||
xin7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||
|
||||
_mm_store_si128(output + i + 0, xin0);
|
||||
_mm_store_si128(output + i + 1, xin1);
|
||||
|
@ -341,10 +312,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
@ -354,20 +321,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xout0 ^= k9;
|
||||
xout1 ^= k9;
|
||||
xout2 ^= k9;
|
||||
xout3 ^= k9;
|
||||
xout4 ^= k9;
|
||||
xout5 ^= k9;
|
||||
xout6 ^= k9;
|
||||
xout7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
|
@ -385,10 +339,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
@ -398,29 +348,12 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xout0 ^= k9;
|
||||
xout1 ^= k9;
|
||||
xout2 ^= k9;
|
||||
xout3 ^= k9;
|
||||
xout4 ^= k9;
|
||||
xout5 ^= k9;
|
||||
xout6 ^= k9;
|
||||
xout7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
if (!SOFT_AES) {
|
||||
aes_round<SOFT_AES>(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
|
||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
@ -430,20 +363,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
aes_round<SOFT_AES>(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
aes_round<SOFT_AES>(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
if (!SOFT_AES) {
|
||||
xout0 ^= k9;
|
||||
xout1 ^= k9;
|
||||
xout2 ^= k9;
|
||||
xout3 ^= k9;
|
||||
xout4 ^= k9;
|
||||
xout5 ^= k9;
|
||||
xout6 ^= k9;
|
||||
xout7 ^= k9;
|
||||
}
|
||||
else {
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
}
|
||||
aes_round<SOFT_AES>(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||
|
||||
mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7);
|
||||
}
|
||||
|
@ -460,8 +380,23 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||
}
|
||||
|
||||
|
||||
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
|
||||
{
|
||||
mem_out[0] = EXTRACT64(tmp);
|
||||
|
||||
uint64_t vh = vgetq_lane_u64(tmp, 1);
|
||||
|
||||
uint8_t x = vh >> 24;
|
||||
static const uint16_t table = 0x7531;
|
||||
const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1;
|
||||
vh ^= ((table >> index) & 0x3) << 28;
|
||||
|
||||
mem_out[1] = vh;
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
|
@ -472,14 +407,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
|
@ -495,13 +430,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
}
|
||||
else {
|
||||
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
# endif
|
||||
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
|
||||
}
|
||||
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
idx0 = EXTRACT64(cx);
|
||||
bx0 = cx;
|
||||
|
||||
|
@ -532,15 +469,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
|
||||
|
||||
keccakf(h0, 24);
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
|
@ -551,16 +488,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input + size, (int) size, ctx->state1, 200);
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
keccak(input + size, (int) size, ctx[1]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
VARIANT1_INIT(1);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
const uint8_t* l1 = ctx->memory + MEM;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
const uint8_t* l1 = ctx[1]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
|
@ -586,16 +523,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
else {
|
||||
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
|
||||
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
|
||||
# ifndef XMRIG_ARMv7
|
||||
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
|
||||
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
|
||||
# endif
|
||||
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
|
||||
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
|
||||
}
|
||||
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
VARIANT1_1(&l0[idx0 & MASK]);
|
||||
VARIANT1_1(&l1[idx1 & MASK]);
|
||||
if (VARIANT > 0) {
|
||||
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
} else {
|
||||
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
|
||||
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
|
||||
};
|
||||
|
||||
idx0 = EXTRACT64(cx0);
|
||||
idx1 = EXTRACT64(cx1);
|
||||
|
@ -661,25 +599,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
keccakf(h0, 24);
|
||||
keccakf(h1, 24);
|
||||
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "xmrig.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
namespace xmrig
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
uint64_t tweak1_2_##part = 0; \
|
||||
if (VARIANT > 0) { \
|
||||
tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
|
||||
*(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24)); \
|
||||
*(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \
|
||||
}
|
||||
#else
|
||||
# define VARIANT1_INIT(part) \
|
||||
uint64_t tweak1_2_##part = 0; \
|
||||
if (VARIANT > 0) { \
|
||||
volatile const uint64_t a = *reinterpret_cast<const uint64_t*>(input + 35 + part * size); \
|
||||
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24); \
|
||||
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \
|
||||
tweak1_2_##part = a ^ b; \
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,62 +26,107 @@
|
|||
#define __CRYPTONIGHT_TEST_H__
|
||||
|
||||
|
||||
const static uint8_t test_input[152] = {
|
||||
const static uint8_t test_input[380] = {
|
||||
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
|
||||
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
|
||||
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
|
||||
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
|
||||
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
|
||||
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
|
||||
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
|
||||
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
|
||||
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
|
||||
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
|
||||
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
|
||||
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
|
||||
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
|
||||
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
|
||||
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01
|
||||
0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF,
|
||||
0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB,
|
||||
0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29,
|
||||
0x74, 0xB2, 0x70, 0xE7, 0x6D, 0xD2, 0x2A, 0x5F, 0x52, 0x04, 0x93, 0xE6, 0x18, 0x89, 0x40, 0xD8,
|
||||
0xC6, 0xE3, 0x90, 0x6E, 0xAA, 0x6A, 0xB7, 0xE2, 0x08, 0x7E, 0x78, 0x0E,
|
||||
0x01, 0x00, 0xEE, 0xB2, 0xD1, 0xD6, 0x05, 0xFF, 0x27, 0x7F, 0x26, 0xDB, 0xAA, 0xB2, 0xC9, 0x26,
|
||||
0x30, 0xC6, 0xCF, 0x11, 0x64, 0xEA, 0x6C, 0x8A, 0xE0, 0x98, 0x01, 0xF8, 0x75, 0x4B, 0x49, 0xAF,
|
||||
0x79, 0x70, 0xAE, 0xEE, 0xA7, 0x62, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x47, 0x8C, 0x63, 0xE7, 0xD8,
|
||||
0x40, 0x02, 0x3C, 0xDA, 0xEA, 0x92, 0x52, 0x53, 0xAC, 0xFD, 0xC7, 0x8A, 0x4C, 0x31, 0xB2, 0xF2,
|
||||
0xEC, 0x72, 0x7B, 0xFF, 0xCE, 0xC0, 0xE7, 0x12, 0xD4, 0xE9, 0x2A, 0x01,
|
||||
0x07, 0x07, 0xA9, 0xB7, 0xD1, 0xD6, 0x05, 0x3F, 0x0D, 0x5E, 0xFD, 0xC7, 0x03, 0xFC, 0xFC, 0xD2,
|
||||
0xCE, 0xBC, 0x44, 0xD8, 0xAB, 0x44, 0xA6, 0xA0, 0x3A, 0xE4, 0x4D, 0x8F, 0x15, 0xAF, 0x62, 0x17,
|
||||
0xD1, 0xE0, 0x92, 0x85, 0xE4, 0x73, 0xF9, 0x00, 0x00, 0x00, 0xA0, 0xFC, 0x09, 0xDE, 0xAB, 0xF5,
|
||||
0x8B, 0x6F, 0x1D, 0xCA, 0xA8, 0xBA, 0xAC, 0x74, 0xDD, 0x74, 0x19, 0xD5, 0xD6, 0x10, 0xEC, 0x38,
|
||||
0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04
|
||||
};
|
||||
|
||||
|
||||
const static uint8_t test_output_v0[64] = {
|
||||
const static uint8_t test_output_v0[160] = {
|
||||
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
|
||||
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
|
||||
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
|
||||
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
|
||||
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
|
||||
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00
|
||||
0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0,
|
||||
0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C,
|
||||
0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D,
|
||||
0x16, 0xE9, 0x28, 0x49, 0xA1, 0xFF, 0x85, 0x6F, 0x12, 0xBB, 0x7D, 0xAB, 0x11, 0x1C, 0xE7, 0xF7,
|
||||
0x2D, 0x9D, 0x19, 0xE4, 0xD2, 0x26, 0x44, 0x1E, 0xCD, 0x22, 0x08, 0x24, 0xA8, 0x97, 0x46, 0x62,
|
||||
0x04, 0x84, 0x90, 0x4A, 0xEE, 0x99, 0x14, 0xED, 0xB8, 0xC6, 0x0D, 0x37, 0xA1, 0x66, 0x17, 0xB0
|
||||
};
|
||||
|
||||
|
||||
// Monero v7
|
||||
const static uint8_t test_output_v1[64] = {
|
||||
0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D,
|
||||
0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22,
|
||||
const static uint8_t test_output_v1[160] = {
|
||||
0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9,
|
||||
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9
|
||||
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9,
|
||||
0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D,
|
||||
0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22,
|
||||
0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98,
|
||||
0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C,
|
||||
0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE,
|
||||
0x92, 0x2C, 0xD6, 0x0C, 0x46, 0x9D, 0x9B, 0xC2, 0x84, 0x52, 0x65, 0xF6, 0xBD, 0xFA, 0x0D, 0x74,
|
||||
0x00, 0x66, 0x10, 0x07, 0xF1, 0x19, 0x06, 0x3A, 0x6C, 0xFF, 0xEE, 0xB2, 0x40, 0xE5, 0x88, 0x2B,
|
||||
0x6C, 0xAB, 0x6B, 0x1D, 0x88, 0xB8, 0x44, 0x25, 0xF4, 0xEA, 0xB7, 0xEC, 0xBA, 0x12, 0x8A, 0x24
|
||||
};
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_AEON
|
||||
const static uint8_t test_output_v0_lite[64] = {
|
||||
const static uint8_t test_output_v0_lite[160] = {
|
||||
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
|
||||
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
|
||||
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
|
||||
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
|
||||
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
|
||||
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88
|
||||
0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E,
|
||||
0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18,
|
||||
0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37,
|
||||
0xA2, 0x5E, 0xE6, 0x96, 0xB5, 0x97, 0x33, 0x89, 0xE0, 0xA7, 0xC9, 0xDD, 0x4A, 0x7E, 0x9E, 0x53,
|
||||
0xBE, 0x91, 0x2B, 0xF5, 0xF5, 0xAF, 0xDD, 0x09, 0xA2, 0xF4, 0xA4, 0x56, 0xEB, 0x96, 0x22, 0xC9,
|
||||
0x94, 0xFB, 0x7B, 0x28, 0xC9, 0x97, 0x65, 0x04, 0xAC, 0x4F, 0x84, 0x71, 0xDA, 0x6E, 0xD8, 0xC5
|
||||
};
|
||||
|
||||
|
||||
// AEON v7
|
||||
const static uint8_t test_output_v1_lite[64] = {
|
||||
const static uint8_t test_output_v1_lite[160] = {
|
||||
0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22,
|
||||
0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41,
|
||||
0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45,
|
||||
0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F,
|
||||
0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22,
|
||||
0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41
|
||||
0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB,
|
||||
0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32,
|
||||
0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E,
|
||||
0x90, 0x22, 0x77, 0x5A, 0xAD, 0xA1, 0xE5, 0xB6, 0xFC, 0xCB, 0x39, 0x7E, 0x2B, 0x10, 0xEE, 0xB4,
|
||||
0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9,
|
||||
0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_SUMO
|
||||
const static uint8_t test_output_heavy[64] = {
|
||||
const static uint8_t test_output_heavy[160] = {
|
||||
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
|
||||
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
|
||||
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
|
||||
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
|
||||
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
|
||||
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2
|
||||
0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7,
|
||||
0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD,
|
||||
0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1,
|
||||
0x1F, 0xDB, 0xDA, 0x6B, 0xAC, 0xEC, 0x9F, 0x67, 0xF8, 0x27, 0x1D, 0xC7, 0xE6, 0x46, 0x42, 0xF9,
|
||||
0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51,
|
||||
0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -403,7 +403,7 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp)
|
|||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
|
@ -414,20 +414,20 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0)
|
||||
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->state0, (__m128i*) ctx->memory);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
|
||||
uint64_t al0 = h0[0] ^ h0[4];
|
||||
uint64_t ah0 = h0[1] ^ h0[5];
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
uint64_t idx0 = al0;
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx;
|
||||
|
@ -476,15 +476,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||
}
|
||||
}
|
||||
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
|
||||
|
||||
keccakf(h0, 24);
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
|
@ -495,16 +495,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
return;
|
||||
}
|
||||
|
||||
keccak(input, (int) size, ctx->state0, 200);
|
||||
keccak(input + size, (int) size, ctx->state1, 200);
|
||||
keccak(input, (int) size, ctx[0]->state, 200);
|
||||
keccak(input + size, (int) size, ctx[1]->state, 200);
|
||||
|
||||
VARIANT1_INIT(0);
|
||||
VARIANT1_INIT(1);
|
||||
|
||||
const uint8_t* l0 = ctx->memory;
|
||||
const uint8_t* l1 = ctx->memory + MEM;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state0);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state1);
|
||||
const uint8_t* l0 = ctx[0]->memory;
|
||||
const uint8_t* l1 = ctx[1]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
|
||||
|
@ -517,8 +517,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
|
||||
uint64_t idx0 = h0[0] ^ h0[4];
|
||||
uint64_t idx1 = h1[0] ^ h1[4];
|
||||
uint64_t idx0 = al0;
|
||||
uint64_t idx1 = al1;
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS; i++) {
|
||||
__m128i cx0, cx1;
|
||||
|
@ -606,26 +606,382 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||
keccakf(h0, 24);
|
||||
keccakf(h1, 24);
|
||||
|
||||
extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
|
||||
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32);
|
||||
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
|
||||
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
|
||||
}
|
||||
|
||||
|
||||
#define CN_STEP1(a, b, c, l, ptr, idx) \
|
||||
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
|
||||
c = _mm_load_si128(ptr);
|
||||
|
||||
|
||||
#define CN_STEP2(a, b, c, l, ptr, idx) \
|
||||
if (SOFT_AES) { \
|
||||
c = soft_aesenc(c, a); \
|
||||
} else { \
|
||||
c = _mm_aesenc_si128(c, a); \
|
||||
} \
|
||||
\
|
||||
b = _mm_xor_si128(b, c); \
|
||||
\
|
||||
if (VARIANT > 0) { \
|
||||
cryptonight_monero_tweak(reinterpret_cast<uint64_t*>(ptr), b); \
|
||||
} else { \
|
||||
_mm_store_si128(ptr, b); \
|
||||
}
|
||||
|
||||
|
||||
#define CN_STEP3(a, b, c, l, ptr, idx) \
|
||||
idx = EXTRACT64(c); \
|
||||
ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \
|
||||
b = _mm_load_si128(ptr);
|
||||
|
||||
|
||||
#define CN_STEP4(a, b, c, l, mc, ptr, idx) \
|
||||
lo = __umul128(idx, EXTRACT64(b), &hi); \
|
||||
a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \
|
||||
\
|
||||
if (VARIANT > 0) { \
|
||||
_mm_store_si128(ptr, _mm_xor_si128(a, mc)); \
|
||||
} else { \
|
||||
_mm_store_si128(ptr, a); \
|
||||
} \
|
||||
\
|
||||
a = _mm_xor_si128(a, b); \
|
||||
idx = EXTRACT64(a); \
|
||||
\
|
||||
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \
|
||||
int64_t n = ((int64_t*)&l[idx & MASK])[0]; \
|
||||
int32_t d = ((int32_t*)&l[idx & MASK])[2]; \
|
||||
int64_t q = n / (d | 0x5); \
|
||||
((int64_t*)&l[idx & MASK])[0] = n ^ q; \
|
||||
idx = d ^ q; \
|
||||
}
|
||||
|
||||
|
||||
#define CONST_INIT(ctx, n) \
|
||||
__m128i mc##n; \
|
||||
if (VARIANT > 0) { \
|
||||
mc##n = _mm_set_epi64x(*reinterpret_cast<const uint64_t*>(input + n * size + 35) ^ \
|
||||
*(reinterpret_cast<const uint64_t*>((ctx)->state) + 24), 0); \
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 3);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2;
|
||||
idx0 = EXTRACT64(ax0);
|
||||
idx1 = EXTRACT64(ax1);
|
||||
idx2 = EXTRACT64(ax2);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++) {
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
CONST_INIT(ctx[3], 3);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint8_t* l3 = ctx[3]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
|
||||
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx3 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2, idx3;
|
||||
idx0 = _mm_cvtsi128_si64(ax0);
|
||||
idx1 = _mm_cvtsi128_si64(ax1);
|
||||
idx2 = _mm_cvtsi128_si64(ax2);
|
||||
idx3 = _mm_cvtsi128_si64(ax3);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++)
|
||||
{
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2, *ptr3;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
|
||||
{
|
||||
}
|
||||
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
|
||||
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>();
|
||||
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
|
||||
|
||||
if (VARIANT > 0 && size < 43) {
|
||||
memset(output, 0, 32 * 5);
|
||||
return;
|
||||
}
|
||||
|
||||
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT>
|
||||
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx)
|
||||
{
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
keccak(input + size * i, static_cast<int>(size), ctx[i]->state, 200);
|
||||
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||
}
|
||||
|
||||
CONST_INIT(ctx[0], 0);
|
||||
CONST_INIT(ctx[1], 1);
|
||||
CONST_INIT(ctx[2], 2);
|
||||
CONST_INIT(ctx[3], 3);
|
||||
CONST_INIT(ctx[4], 4);
|
||||
|
||||
uint8_t* l0 = ctx[0]->memory;
|
||||
uint8_t* l1 = ctx[1]->memory;
|
||||
uint8_t* l2 = ctx[2]->memory;
|
||||
uint8_t* l3 = ctx[3]->memory;
|
||||
uint8_t* l4 = ctx[4]->memory;
|
||||
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
|
||||
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx[2]->state);
|
||||
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx[3]->state);
|
||||
uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx[4]->state);
|
||||
|
||||
__m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]);
|
||||
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
|
||||
__m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]);
|
||||
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
|
||||
__m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]);
|
||||
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
|
||||
__m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]);
|
||||
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
|
||||
__m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]);
|
||||
__m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]);
|
||||
__m128i cx0 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx1 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx2 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx3 = _mm_set_epi64x(0, 0);
|
||||
__m128i cx4 = _mm_set_epi64x(0, 0);
|
||||
|
||||
uint64_t idx0, idx1, idx2, idx3, idx4;
|
||||
idx0 = _mm_cvtsi128_si64(ax0);
|
||||
idx1 = _mm_cvtsi128_si64(ax1);
|
||||
idx2 = _mm_cvtsi128_si64(ax2);
|
||||
idx3 = _mm_cvtsi128_si64(ax3);
|
||||
idx4 = _mm_cvtsi128_si64(ax4);
|
||||
|
||||
for (size_t i = 0; i < ITERATIONS / 2; i++)
|
||||
{
|
||||
uint64_t hi, lo;
|
||||
__m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4;
|
||||
|
||||
// EVEN ROUND
|
||||
CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3);
|
||||
CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3);
|
||||
CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4);
|
||||
|
||||
// ODD ROUND
|
||||
CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0);
|
||||
CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1);
|
||||
CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2);
|
||||
CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3);
|
||||
CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4);
|
||||
|
||||
CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0);
|
||||
CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1);
|
||||
CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2);
|
||||
CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3);
|
||||
CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __CRYPTONIGHT_X86_H__ */
|
||||
|
|
|
@ -105,6 +105,23 @@ static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
|
|||
return _mm_xor_si128(out, key);
|
||||
}
|
||||
|
||||
static inline __m128i soft_aesenc(__m128i in, __m128i key)
|
||||
{
|
||||
uint32_t x0, x1, x2, x3;
|
||||
x0 = _mm_cvtsi128_si32(in);
|
||||
x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55));
|
||||
x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA));
|
||||
x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF));
|
||||
|
||||
__m128i out = _mm_set_epi32(
|
||||
(saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]),
|
||||
(saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]),
|
||||
(saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]),
|
||||
(saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24]));
|
||||
|
||||
return _mm_xor_si128(out, key);
|
||||
}
|
||||
|
||||
static inline uint32_t sub_word(uint32_t key)
|
||||
{
|
||||
return (saes_sbox[key >> 24 ] << 24) |
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
MaxCPUUsageKey = 1004,
|
||||
SafeKey = 1005,
|
||||
ThreadsKey = 't',
|
||||
HardwareAESKey = 1011,
|
||||
|
||||
// xmrig-proxy
|
||||
AccessLogFileKey = 'A',
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -43,14 +43,23 @@ public:
|
|||
CUDA
|
||||
};
|
||||
|
||||
enum Multiway {
|
||||
SingleWay = 1,
|
||||
DoubleWay,
|
||||
TripleWay,
|
||||
QuadWay,
|
||||
PentaWay
|
||||
};
|
||||
|
||||
virtual ~IThread() {}
|
||||
|
||||
virtual Algo algorithm() const = 0;
|
||||
virtual int multiway() const = 0;
|
||||
virtual int priority() const = 0;
|
||||
virtual int64_t affinity() const = 0;
|
||||
virtual size_t index() const = 0;
|
||||
virtual Type type() const = 0;
|
||||
virtual Algo algorithm() const = 0;
|
||||
virtual int priority() const = 0;
|
||||
virtual int64_t affinity() const = 0;
|
||||
virtual Multiway multiway() const = 0;
|
||||
virtual rapidjson::Value toConfig(rapidjson::Document &doc) const = 0;
|
||||
virtual size_t index() const = 0;
|
||||
virtual Type type() const = 0;
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0;
|
||||
|
|
|
@ -33,10 +33,11 @@ class IWorker
|
|||
public:
|
||||
virtual ~IWorker() {}
|
||||
|
||||
virtual bool start() = 0;
|
||||
virtual bool selfTest() = 0;
|
||||
virtual size_t id() const = 0;
|
||||
virtual uint64_t hashCount() const = 0;
|
||||
virtual uint64_t timestamp() const = 0;
|
||||
virtual void start() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.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>
|
||||
*
|
||||
* 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
|
||||
|
@ -38,6 +38,8 @@ Log *Log::m_self = nullptr;
|
|||
|
||||
void Log::message(Log::Level level, const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
@ -47,11 +49,15 @@ void Log::message(Log::Level level, const char* fmt, ...)
|
|||
backend->message(level, fmt, copy);
|
||||
va_end(copy);
|
||||
}
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
void Log::text(const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
@ -63,6 +69,8 @@ void Log::text(const char* fmt, ...)
|
|||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2017 XMRig <support@xmrig.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>
|
||||
*
|
||||
* 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
|
||||
|
@ -25,6 +25,7 @@
|
|||
#define __LOG_H__
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -54,20 +55,28 @@ public:
|
|||
constexpr static const char* kCL_GRAY = "\x1B[90m";
|
||||
# endif
|
||||
|
||||
static inline Log* i() { return m_self; }
|
||||
static inline Log* i() { assert(m_self != nullptr); return m_self; }
|
||||
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
|
||||
static inline void init() { if (!m_self) { m_self = new Log();} }
|
||||
static inline void release() { delete m_self; }
|
||||
static inline void init() { if (!m_self) { new Log(); } }
|
||||
static inline void release() { assert(m_self != nullptr); delete m_self; }
|
||||
|
||||
void message(Level level, const char* fmt, ...);
|
||||
void text(const char* fmt, ...);
|
||||
|
||||
private:
|
||||
inline Log() {}
|
||||
inline Log() {
|
||||
assert(m_self == nullptr);
|
||||
|
||||
uv_mutex_init(&m_mutex);
|
||||
|
||||
m_self = this;
|
||||
}
|
||||
|
||||
~Log();
|
||||
|
||||
static Log *m_self;
|
||||
std::vector<ILogBackend*> m_backends;
|
||||
uv_mutex_t m_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -209,6 +209,17 @@ void Job::toHex(const unsigned char* in, unsigned int len, char* out)
|
|||
}
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
char *Job::toHex(const unsigned char* in, unsigned int len)
|
||||
{
|
||||
char *out = new char[len * 2 + 1]();
|
||||
toHex(in, len, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Job::operator==(const Job &other) const
|
||||
{
|
||||
return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
#include "net/Id.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
class Job
|
||||
|
@ -69,6 +69,10 @@ public:
|
|||
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
|
||||
static void toHex(const unsigned char* in, unsigned int len, char* out);
|
||||
|
||||
# ifdef APP_DEBUG
|
||||
static char *toHex(const unsigned char* in, unsigned int len);
|
||||
# endif
|
||||
|
||||
bool operator==(const Job &other) const;
|
||||
bool operator!=(const Job &other) const;
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "core/utils/c_str.h"
|
||||
#include "xmrig.h"
|
||||
#include "common/utils/c_str.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
class Pool
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "common/Platform.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "Platform.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "common/Platform.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/FailoverStrategy.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "common/Platform.h"
|
||||
#include "interfaces/IStrategyListener.h"
|
||||
#include "net/Client.h"
|
||||
#include "net/strategies/SinglePoolStrategy.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) :
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
|
||||
#include "core/CommonConfig.h"
|
||||
#include "net/Pool.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "workers/CpuThread.h"
|
||||
|
||||
|
@ -54,6 +54,12 @@ xmrig::CpuThread::~CpuThread()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::CpuThread::isSoftAES(AlgoVariant av)
|
||||
{
|
||||
return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA;
|
||||
}
|
||||
|
||||
|
||||
xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant)
|
||||
{
|
||||
assert(variant == VARIANT_NONE || variant == VARIANT_V1);
|
||||
|
@ -138,42 +144,6 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A
|
|||
{
|
||||
assert(av > AV_AUTO && av < AV_MAX);
|
||||
|
||||
Multiway multiway = SingleWay;
|
||||
bool softAES = false;
|
||||
|
||||
switch (av) {
|
||||
case AV_SINGLE_SOFT:
|
||||
softAES = true;
|
||||
break;
|
||||
|
||||
case AV_DOUBLE_SOFT:
|
||||
softAES = true;
|
||||
case AV_DOUBLE:
|
||||
multiway = DoubleWay;
|
||||
break;
|
||||
|
||||
case AV_TRIPLE_SOFT:
|
||||
softAES = true;
|
||||
case AV_TRIPLE:
|
||||
multiway = TripleWay;
|
||||
break;
|
||||
|
||||
case AV_QUAD_SOFT:
|
||||
softAES = true;
|
||||
case AV_QUAD:
|
||||
multiway = QuadWay;
|
||||
break;
|
||||
|
||||
case AV_PENTA_SOFT:
|
||||
softAES = true;
|
||||
case AV_PENTA:
|
||||
multiway = PentaWay;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int64_t cpuId = -1L;
|
||||
|
||||
if (affinity != -1L) {
|
||||
|
@ -193,14 +163,92 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A
|
|||
}
|
||||
}
|
||||
|
||||
return new CpuThread(index, algorithm, av, multiway, cpuId, priority, softAES, false);
|
||||
return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false);
|
||||
}
|
||||
|
||||
|
||||
xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES)
|
||||
{
|
||||
int av = AV_AUTO;
|
||||
const Multiway multiway = data.multiway;
|
||||
|
||||
if (multiway <= DoubleWay) {
|
||||
av = softAES ? (multiway + 2) : multiway;
|
||||
}
|
||||
else {
|
||||
av = softAES ? (multiway + 5) : (multiway + 2);
|
||||
}
|
||||
|
||||
assert(av > AV_AUTO && av < AV_MAX);
|
||||
|
||||
return new CpuThread(index, algorithm, static_cast<AlgoVariant>(av), multiway, data.affinity, priority, softAES, false);
|
||||
}
|
||||
|
||||
|
||||
xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object)
|
||||
{
|
||||
Data data;
|
||||
|
||||
const auto &multiway = object["low_power_mode"];
|
||||
if (multiway.IsBool()) {
|
||||
data.multiway = multiway.IsTrue() ? DoubleWay : SingleWay;
|
||||
data.valid = true;
|
||||
}
|
||||
else if (multiway.IsUint()) {
|
||||
data.setMultiway(multiway.GetInt());
|
||||
}
|
||||
|
||||
if (!data.valid) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const auto &affinity = object["affine_to_cpu"];
|
||||
|
||||
if (affinity.IsUint64()) {
|
||||
data.affinity = affinity.GetInt64();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av)
|
||||
{
|
||||
switch (av) {
|
||||
case AV_SINGLE:
|
||||
case AV_SINGLE_SOFT:
|
||||
return SingleWay;
|
||||
|
||||
case AV_DOUBLE_SOFT:
|
||||
case AV_DOUBLE:
|
||||
return DoubleWay;
|
||||
|
||||
case AV_TRIPLE_SOFT:
|
||||
case AV_TRIPLE:
|
||||
return TripleWay;
|
||||
|
||||
case AV_QUAD_SOFT:
|
||||
case AV_QUAD:
|
||||
return QuadWay;
|
||||
|
||||
case AV_PENTA_SOFT:
|
||||
case AV_PENTA:
|
||||
return PentaWay;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SingleWay;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_API
|
||||
rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const
|
||||
{
|
||||
rapidjson::Value obj(rapidjson::kObjectType);
|
||||
using namespace rapidjson;
|
||||
|
||||
Value obj(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
obj.AddMember("type", "cpu", allocator);
|
||||
|
@ -214,3 +262,17 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const
|
|||
return obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
Value obj(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
obj.AddMember("low_power_mode", multiway(), allocator);
|
||||
obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#define __CPUTHREAD_H__
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
#include "interfaces/IThread.h"
|
||||
#include "xmrig.h"
|
||||
|
||||
|
||||
struct cryptonight_ctx;
|
||||
|
@ -38,37 +38,54 @@ namespace xmrig {
|
|||
class CpuThread : public IThread
|
||||
{
|
||||
public:
|
||||
enum Multiway {
|
||||
SingleWay = 1,
|
||||
DoubleWay,
|
||||
TripleWay,
|
||||
QuadWay,
|
||||
PentaWay
|
||||
struct Data
|
||||
{
|
||||
inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {}
|
||||
|
||||
inline void setMultiway(int value)
|
||||
{
|
||||
if (value >= SingleWay && value <= PentaWay) {
|
||||
multiway = static_cast<Multiway>(value);
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool valid;
|
||||
int64_t affinity;
|
||||
Multiway multiway;
|
||||
};
|
||||
|
||||
|
||||
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch);
|
||||
~CpuThread();
|
||||
|
||||
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
|
||||
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx);
|
||||
|
||||
static bool isSoftAES(AlgoVariant av);
|
||||
static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant);
|
||||
static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority);
|
||||
static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES);
|
||||
static Data parse(const rapidjson::Value &object);
|
||||
static Multiway multiway(AlgoVariant av);
|
||||
|
||||
inline bool isPrefetch() const { return m_prefetch; }
|
||||
inline bool isSoftAES() const { return m_softAES; }
|
||||
inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); }
|
||||
|
||||
inline Algo algorithm() const override { return m_algorithm; }
|
||||
inline int multiway() const override { return m_multiway; }
|
||||
inline int priority() const override { return m_priority; }
|
||||
inline int64_t affinity() const override { return m_affinity; }
|
||||
inline Multiway multiway() const override { return m_multiway; }
|
||||
inline size_t index() const override { return m_index; }
|
||||
inline Type type() const override { return CPU; }
|
||||
|
||||
protected:
|
||||
# ifndef XMRIG_NO_API
|
||||
rapidjson::Value toAPI(rapidjson::Document &doc) const override;
|
||||
# endif
|
||||
|
||||
rapidjson::Value toConfig(rapidjson::Document &doc) const override;
|
||||
|
||||
private:
|
||||
const Algo m_algorithm;
|
||||
const AlgoVariant m_av;
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
#include "workers/Handle.h"
|
||||
|
||||
|
||||
Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity) :
|
||||
m_affinity(affinity),
|
||||
Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) :
|
||||
m_worker(nullptr),
|
||||
m_totalThreads(totalThreads),
|
||||
m_totalWays(totalWays),
|
||||
m_offset(offset),
|
||||
m_config(config)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define __HANDLE_H__
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
@ -38,23 +39,21 @@ class IWorker;
|
|||
class Handle
|
||||
{
|
||||
public:
|
||||
Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity);
|
||||
Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays);
|
||||
void join();
|
||||
void start(void (*callback) (void *));
|
||||
|
||||
inline int64_t affinity() const { return m_affinity; }
|
||||
inline IWorker *worker() const { return m_worker; }
|
||||
inline size_t threadId() const { return m_config->index(); }
|
||||
inline size_t totalThreads() const { return m_totalThreads; }
|
||||
inline size_t totalWays() const { return m_totalWays; }
|
||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||
inline uint32_t offset() const { return m_offset; }
|
||||
inline void setWorker(IWorker *worker) { assert(worker != nullptr); m_worker = worker; }
|
||||
inline xmrig::IThread *config() const { return m_config; }
|
||||
|
||||
private:
|
||||
int64_t m_affinity;
|
||||
IWorker *m_worker;
|
||||
size_t m_totalThreads;
|
||||
size_t m_totalWays;
|
||||
uint32_t m_offset;
|
||||
uv_thread_t m_thread;
|
||||
xmrig::IThread *m_config;
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <chrono>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
@ -45,7 +46,7 @@ inline const char *format(double h, char* buf, size_t size)
|
|||
}
|
||||
|
||||
|
||||
Hashrate::Hashrate(int threads, xmrig::Controller *controller) :
|
||||
Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
|
||||
m_highest(0.0),
|
||||
m_threads(threads),
|
||||
m_controller(controller)
|
||||
|
@ -54,13 +55,10 @@ Hashrate::Hashrate(int threads, xmrig::Controller *controller) :
|
|||
m_timestamps = new uint64_t*[threads];
|
||||
m_top = new uint32_t[threads];
|
||||
|
||||
for (int i = 0; i < threads; i++) {
|
||||
m_counts[i] = new uint64_t[kBucketSize];
|
||||
m_timestamps[i] = new uint64_t[kBucketSize];
|
||||
m_top[i] = 0;
|
||||
|
||||
memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize);
|
||||
memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize);
|
||||
for (size_t i = 0; i < threads; i++) {
|
||||
m_counts[i] = new uint64_t[kBucketSize]();
|
||||
m_timestamps[i] = new uint64_t[kBucketSize]();
|
||||
m_top[i] = 0;
|
||||
}
|
||||
|
||||
const int printTime = controller->config()->printTime();
|
||||
|
@ -79,7 +77,7 @@ double Hashrate::calc(size_t ms) const
|
|||
double result = 0.0;
|
||||
double data;
|
||||
|
||||
for (int i = 0; i < m_threads; ++i) {
|
||||
for (size_t i = 0; i < m_threads; ++i) {
|
||||
data = calc(i, ms);
|
||||
if (isnormal(data)) {
|
||||
result += data;
|
||||
|
@ -92,6 +90,8 @@ double Hashrate::calc(size_t ms) const
|
|||
|
||||
double Hashrate::calc(size_t threadId, size_t ms) const
|
||||
{
|
||||
assert(threadId < m_threads);
|
||||
|
||||
using namespace std::chrono;
|
||||
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
LargeInterval = 900000
|
||||
};
|
||||
|
||||
Hashrate(int threads, xmrig::Controller *controller);
|
||||
Hashrate(size_t threads, xmrig::Controller *controller);
|
||||
double calc(size_t ms) const;
|
||||
double calc(size_t threadId, size_t ms) const;
|
||||
void add(size_t threadId, uint64_t count, uint64_t timestamp);
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
void updateHighest();
|
||||
|
||||
inline double highest() const { return m_highest; }
|
||||
inline int threads() const { return m_threads; }
|
||||
inline size_t threads() const { return m_threads; }
|
||||
|
||||
private:
|
||||
static void onReport(uv_timer_t *handle);
|
||||
|
@ -61,7 +61,7 @@ private:
|
|||
constexpr static size_t kBucketMask = kBucketSize - 1;
|
||||
|
||||
double m_highest;
|
||||
int m_threads;
|
||||
size_t m_threads;
|
||||
uint32_t* m_top;
|
||||
uint64_t** m_counts;
|
||||
uint64_t** m_timestamps;
|
||||
|
|
|
@ -28,46 +28,59 @@
|
|||
|
||||
#include "crypto/CryptoNight_test.h"
|
||||
#include "workers/CpuThread.h"
|
||||
#include "workers/DoubleWorker.h"
|
||||
#include "workers/MultiWorker.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
class DoubleWorker::State
|
||||
{
|
||||
public:
|
||||
inline State() :
|
||||
nonce1(0),
|
||||
nonce2(0)
|
||||
{}
|
||||
|
||||
Job job;
|
||||
uint32_t nonce1;
|
||||
uint32_t nonce2;
|
||||
uint8_t blob[84 * 2];
|
||||
};
|
||||
|
||||
|
||||
DoubleWorker::DoubleWorker(Handle *handle)
|
||||
template<size_t N>
|
||||
MultiWorker<N>::MultiWorker(Handle *handle)
|
||||
: Worker(handle)
|
||||
{
|
||||
m_state = new State();
|
||||
m_pausedState = new State();
|
||||
m_memory = Mem::create(m_ctx, m_thread->algorithm(), N);
|
||||
}
|
||||
|
||||
|
||||
DoubleWorker::~DoubleWorker()
|
||||
template<size_t N>
|
||||
MultiWorker<N>::~MultiWorker()
|
||||
{
|
||||
delete m_state;
|
||||
delete m_pausedState;
|
||||
Mem::release(m_ctx, N, m_memory);
|
||||
}
|
||||
|
||||
|
||||
bool DoubleWorker::start()
|
||||
template<size_t N>
|
||||
bool MultiWorker<N>::selfTest()
|
||||
{
|
||||
if (!selfTest()) {
|
||||
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, sizeof m_hash) == 0;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
void MultiWorker<N>::start()
|
||||
{
|
||||
while (Workers::sequence() > 0) {
|
||||
if (Workers::isPaused()) {
|
||||
do {
|
||||
|
@ -83,38 +96,35 @@ bool DoubleWorker::start()
|
|||
}
|
||||
|
||||
while (!Workers::isOutdated(m_sequence)) {
|
||||
if ((m_count & 0xF) == 0) {
|
||||
if ((m_count & 0x7) == 0) {
|
||||
storeStats();
|
||||
}
|
||||
|
||||
m_count += 2;
|
||||
*Job::nonce(m_state->blob) = ++m_state->nonce1;
|
||||
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
|
||||
m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx);
|
||||
|
||||
m_thread->fn(m_state->job.variant())(m_state->blob, m_state->job.size(), m_hash, m_ctx);
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) {
|
||||
Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff()));
|
||||
}
|
||||
|
||||
if (*reinterpret_cast<uint64_t*>(m_hash + 24) < m_state->job.target()) {
|
||||
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()));
|
||||
*nonce(i) += 1;
|
||||
}
|
||||
|
||||
if (*reinterpret_cast<uint64_t*>(m_hash + 32 + 24) < m_state->job.target()) {
|
||||
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff()));
|
||||
}
|
||||
m_count += N;
|
||||
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
consumeJob();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DoubleWorker::resume(const Job &job)
|
||||
template<size_t N>
|
||||
bool MultiWorker<N>::resume(const Job &job)
|
||||
{
|
||||
if (m_state->job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState->job.id()) {
|
||||
*m_state = *m_pausedState;
|
||||
if (m_state.job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState.job.id()) {
|
||||
m_state = m_pausedState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -122,41 +132,12 @@ bool DoubleWorker::resume(const Job &job)
|
|||
}
|
||||
|
||||
|
||||
bool DoubleWorker::selfTest()
|
||||
{
|
||||
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, 64) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
return memcmp(m_hash, test_output_v1, 64) == 0;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, 64) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx);
|
||||
|
||||
return memcmp(m_hash, test_output_v1_lite, 64) == 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, 64) == 0;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void DoubleWorker::consumeJob()
|
||||
template<size_t N>
|
||||
void MultiWorker<N>::consumeJob()
|
||||
{
|
||||
Job job = Workers::job();
|
||||
m_sequence = Workers::sequence();
|
||||
if (m_state->job == job) {
|
||||
if (m_state.job == job) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -166,24 +147,39 @@ void DoubleWorker::consumeJob()
|
|||
return;
|
||||
}
|
||||
|
||||
m_state->job = std::move(job);
|
||||
memcpy(m_state->blob, m_state->job.blob(), m_state->job.size());
|
||||
memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size());
|
||||
m_state.job = job;
|
||||
|
||||
if (m_state->job.isNicehash()) {
|
||||
m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id);
|
||||
m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalThreads));
|
||||
const size_t size = m_state.job.size();
|
||||
memcpy(m_state.blob, m_state.job.blob(), m_state.job.size());
|
||||
|
||||
if (N > 1) {
|
||||
for (size_t i = 1; i < N; ++i) {
|
||||
memcpy(m_state.blob + (i * size), m_state.blob, size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_state->nonce1 = 0xffffffffU / m_totalWays * m_id;
|
||||
m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalThreads);
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (m_state.job.isNicehash()) {
|
||||
*nonce(i) = (*nonce(i) & 0xff000000U) + (0xffffffU / m_totalWays * (m_offset + i));
|
||||
}
|
||||
else {
|
||||
*nonce(i) = 0xffffffffU / m_totalWays * (m_offset + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DoubleWorker::save(const Job &job)
|
||||
template<size_t N>
|
||||
void MultiWorker<N>::save(const Job &job)
|
||||
{
|
||||
if (job.poolId() == -1 && m_state->job.poolId() >= 0) {
|
||||
*m_pausedState = *m_state;
|
||||
if (job.poolId() == -1 && m_state.job.poolId() >= 0) {
|
||||
m_pausedState = m_state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template class MultiWorker<1>;
|
||||
template class MultiWorker<2>;
|
||||
template class MultiWorker<3>;
|
||||
template class MultiWorker<4>;
|
||||
template class MultiWorker<5>;
|
|
@ -22,10 +22,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __DOUBLEWORKER_H__
|
||||
#define __DOUBLEWORKER_H__
|
||||
#ifndef __MULTIWORKER_H__
|
||||
#define __MULTIWORKER_H__
|
||||
|
||||
|
||||
#include "Mem.h"
|
||||
#include "net/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "workers/Worker.h"
|
||||
|
@ -34,26 +35,39 @@
|
|||
class Handle;
|
||||
|
||||
|
||||
class DoubleWorker : public Worker
|
||||
template<size_t N>
|
||||
class MultiWorker : public Worker
|
||||
{
|
||||
public:
|
||||
DoubleWorker(Handle *handle);
|
||||
~DoubleWorker();
|
||||
MultiWorker(Handle *handle);
|
||||
~MultiWorker();
|
||||
|
||||
bool start() override;
|
||||
protected:
|
||||
bool selfTest() override;
|
||||
void start() override;
|
||||
|
||||
private:
|
||||
bool resume(const Job &job);
|
||||
bool selfTest();
|
||||
void consumeJob();
|
||||
void save(const Job &job);
|
||||
|
||||
class State;
|
||||
inline uint32_t *nonce(size_t index)
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(m_state.blob + (index * m_state.job.size()) + 39);
|
||||
}
|
||||
|
||||
uint8_t m_hash[64];
|
||||
State *m_state;
|
||||
State *m_pausedState;
|
||||
struct State
|
||||
{
|
||||
alignas(16) uint8_t blob[96 * N];
|
||||
Job job;
|
||||
};
|
||||
|
||||
|
||||
cryptonight_ctx *m_ctx[N];
|
||||
State m_pausedState;
|
||||
State m_state;
|
||||
uint8_t m_hash[N * 32];
|
||||
};
|
||||
|
||||
|
||||
#endif /* __SINGLEWORKER_H__ */
|
||||
#endif /* __MULTIWORKER_H__ */
|
|
@ -1,158 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* 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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2016-2018 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
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
#include "crypto/CryptoNight_test.h"
|
||||
#include "workers/CpuThread.h"
|
||||
#include "workers/SingleWorker.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
SingleWorker::SingleWorker(Handle *handle)
|
||||
: Worker(handle)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool SingleWorker::start()
|
||||
{
|
||||
if (!selfTest()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (Workers::sequence() > 0) {
|
||||
if (Workers::isPaused()) {
|
||||
do {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
}
|
||||
while (Workers::isPaused());
|
||||
|
||||
if (Workers::sequence() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
consumeJob();
|
||||
}
|
||||
|
||||
while (!Workers::isOutdated(m_sequence)) {
|
||||
if ((m_count & 0xF) == 0) {
|
||||
storeStats();
|
||||
}
|
||||
|
||||
m_count++;
|
||||
*m_job.nonce() = ++m_result.nonce;
|
||||
|
||||
m_thread->fn(m_job.variant())(m_job.blob(), m_job.size(), m_result.result, m_ctx);
|
||||
if (*reinterpret_cast<uint64_t*>(m_result.result + 24) < m_job.target()) {
|
||||
Workers::submit(m_result);
|
||||
}
|
||||
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
consumeJob();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SingleWorker::resume(const Job &job)
|
||||
{
|
||||
if (m_job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_paused.id()) {
|
||||
m_job = m_paused;
|
||||
m_result = m_job;
|
||||
m_result.nonce = *m_job.nonce();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SingleWorker::selfTest()
|
||||
{
|
||||
if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctx);
|
||||
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx);
|
||||
|
||||
return memcmp(m_result.result, test_output_v1, 32) == 0;
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) {
|
||||
m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx);
|
||||
|
||||
return memcmp(m_result.result, test_output_v1_lite, 32) == 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void SingleWorker::consumeJob()
|
||||
{
|
||||
Job job = Workers::job();
|
||||
m_sequence = Workers::sequence();
|
||||
if (m_job == job) {
|
||||
return;
|
||||
}
|
||||
|
||||
save(job);
|
||||
|
||||
if (resume(job)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_job = std::move(job);
|
||||
m_result = m_job;
|
||||
|
||||
if (m_job.isNicehash()) {
|
||||
m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_totalWays * m_id);
|
||||
}
|
||||
else {
|
||||
m_result.nonce = 0xffffffffU / m_totalWays * m_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SingleWorker::save(const Job &job)
|
||||
{
|
||||
if (job.poolId() == -1 && m_job.poolId() >= 0) {
|
||||
m_paused = m_job;
|
||||
}
|
||||
}
|
|
@ -24,9 +24,8 @@
|
|||
#include <chrono>
|
||||
|
||||
|
||||
#include "common/Platform.h"
|
||||
#include "Cpu.h"
|
||||
#include "Mem.h"
|
||||
#include "Platform.h"
|
||||
#include "workers/CpuThread.h"
|
||||
#include "workers/Handle.h"
|
||||
#include "workers/Worker.h"
|
||||
|
@ -34,25 +33,19 @@
|
|||
|
||||
Worker::Worker(Handle *handle) :
|
||||
m_id(handle->threadId()),
|
||||
m_totalThreads(handle->totalThreads()),
|
||||
m_totalWays(handle->totalWays()),
|
||||
m_offset(handle->offset()),
|
||||
m_hashCount(0),
|
||||
m_timestamp(0),
|
||||
m_count(0),
|
||||
m_sequence(0),
|
||||
m_thread(static_cast<xmrig::CpuThread *>(handle->config()))
|
||||
{
|
||||
if (Cpu::threads() > 1 && handle->affinity() != -1L) {
|
||||
Cpu::setAffinity(m_id, handle->affinity());
|
||||
if (Cpu::threads() > 1 && m_thread->affinity() != -1L) {
|
||||
Platform::setThreadAffinity(m_thread->affinity());
|
||||
}
|
||||
|
||||
Platform::setThreadPriority(handle->config()->priority());
|
||||
m_ctx = Mem::create(m_id);
|
||||
}
|
||||
|
||||
|
||||
Worker::~Worker()
|
||||
{
|
||||
Platform::setThreadPriority(m_thread->priority());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
|
||||
#include "interfaces/IWorker.h"
|
||||
#include "Mem.h"
|
||||
|
||||
|
||||
struct cryptonight_ctx;
|
||||
|
@ -45,8 +46,8 @@ class Worker : public IWorker
|
|||
{
|
||||
public:
|
||||
Worker(Handle *handle);
|
||||
~Worker();
|
||||
|
||||
inline const MemInfo &memory() const { return m_memory; }
|
||||
inline size_t id() const override { return m_id; }
|
||||
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
|
||||
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
|
||||
|
@ -54,10 +55,10 @@ public:
|
|||
protected:
|
||||
void storeStats();
|
||||
|
||||
cryptonight_ctx *m_ctx;
|
||||
size_t m_id;
|
||||
size_t m_totalThreads;
|
||||
size_t m_totalWays;
|
||||
const size_t m_id;
|
||||
const size_t m_totalWays;
|
||||
const uint32_t m_offset;
|
||||
MemInfo m_memory;
|
||||
std::atomic<uint64_t> m_hashCount;
|
||||
std::atomic<uint64_t> m_timestamp;
|
||||
uint64_t m_count;
|
||||
|
|
|
@ -28,23 +28,24 @@
|
|||
#include "api/Api.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "interfaces/IJobResultListener.h"
|
||||
#include "interfaces/IThread.h"
|
||||
#include "log/Log.h"
|
||||
#include "Mem.h"
|
||||
#include "workers/DoubleWorker.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "workers/Handle.h"
|
||||
#include "workers/Hashrate.h"
|
||||
#include "workers/SingleWorker.h"
|
||||
#include "workers/MultiWorker.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
#include "log/Log.h"
|
||||
|
||||
|
||||
bool Workers::m_active = false;
|
||||
bool Workers::m_enabled = true;
|
||||
Hashrate *Workers::m_hashrate = nullptr;
|
||||
IJobResultListener *Workers::m_listener = nullptr;
|
||||
Job Workers::m_job;
|
||||
Workers::LaunchStatus Workers::m_status;
|
||||
std::atomic<int> Workers::m_paused;
|
||||
std::atomic<uint64_t> Workers::m_sequence;
|
||||
std::list<JobResult> Workers::m_queue;
|
||||
|
@ -66,6 +67,26 @@ Job Workers::job()
|
|||
}
|
||||
|
||||
|
||||
size_t Workers::hugePages()
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
const size_t hugePages = m_status.hugePages;
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
return hugePages;
|
||||
}
|
||||
|
||||
|
||||
size_t Workers::threads()
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
const size_t threads = m_status.threads;
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
return threads;
|
||||
}
|
||||
|
||||
|
||||
void Workers::printHashrate(bool detail)
|
||||
{
|
||||
m_hashrate->print();
|
||||
|
@ -111,10 +132,12 @@ void Workers::setJob(const Job &job, bool donate)
|
|||
void Workers::start(xmrig::Controller *controller)
|
||||
{
|
||||
const std::vector<xmrig::IThread *> &threads = controller->config()->threads();
|
||||
m_status.algo = controller->config()->algorithm();
|
||||
m_status.colors = controller->config()->isHugePages();
|
||||
m_status.threads = threads.size();
|
||||
|
||||
size_t totalWays = 0;
|
||||
for (const xmrig::IThread *thread : threads) {
|
||||
totalWays += thread->multiway();
|
||||
m_status.ways += thread->multiway();
|
||||
}
|
||||
|
||||
m_hashrate = new Hashrate(threads.size(), controller);
|
||||
|
@ -129,8 +152,12 @@ void Workers::start(xmrig::Controller *controller)
|
|||
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, threads.size(), totalWays, controller->config()->affinity());
|
||||
Handle *handle = new Handle(thread, offset, m_status.ways);
|
||||
offset += thread->multiway();
|
||||
|
||||
m_workers.push_back(handle);
|
||||
handle->start(Workers::onReady);
|
||||
}
|
||||
|
@ -162,23 +189,66 @@ void Workers::submit(const JobResult &result)
|
|||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_API
|
||||
void Workers::threadsSummary(rapidjson::Document &doc)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
const uint64_t pages[2] = { m_status.hugePages, m_status.pages };
|
||||
const uint64_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo);
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
rapidjson::Value hugepages(rapidjson::kArrayType);
|
||||
hugepages.PushBack(pages[0], allocator);
|
||||
hugepages.PushBack(pages[1], allocator);
|
||||
|
||||
doc.AddMember("hugepages", hugepages, allocator);
|
||||
doc.AddMember("memory", memory, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Workers::onReady(void *arg)
|
||||
{
|
||||
auto handle = static_cast<Handle*>(arg);
|
||||
if (Mem::isDoubleHash()) {
|
||||
handle->setWorker(new DoubleWorker(handle));
|
||||
}
|
||||
else {
|
||||
handle->setWorker(new SingleWorker(handle));
|
||||
|
||||
IWorker *worker = nullptr;
|
||||
|
||||
switch (handle->config()->multiway()) {
|
||||
case 1:
|
||||
worker = new MultiWorker<1>(handle);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
worker = new MultiWorker<2>(handle);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
worker = new MultiWorker<3>(handle);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
worker = new MultiWorker<4>(handle);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
worker = new MultiWorker<5>(handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const bool rc = handle->worker()->start();
|
||||
handle->setWorker(worker);
|
||||
|
||||
if (!rc) {
|
||||
uv_mutex_lock(&m_mutex);
|
||||
if (!worker->selfTest()) {
|
||||
LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id());
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
start(worker);
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,8 +284,35 @@ void Workers::onTick(uv_timer_t *handle)
|
|||
if ((m_ticks++ & 0xF) == 0) {
|
||||
m_hashrate->updateHighest();
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
Api::tick(m_hashrate);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void Workers::start(IWorker *worker)
|
||||
{
|
||||
const Worker *w = static_cast<const Worker *>(worker);
|
||||
|
||||
uv_mutex_lock(&m_mutex);
|
||||
m_status.started++;
|
||||
m_status.pages += w->memory().pages;
|
||||
m_status.hugePages += w->memory().hugePages;
|
||||
|
||||
if (m_status.started == m_status.threads) {
|
||||
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) / 1048576;
|
||||
|
||||
if (m_status.colors) {
|
||||
LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB",
|
||||
m_status.threads, m_status.ways,
|
||||
(m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")),
|
||||
m_status.hugePages, m_status.pages, percent, memory);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB",
|
||||
m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, memory);
|
||||
}
|
||||
}
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
|
||||
worker->start();
|
||||
}
|
||||
|
|
|
@ -32,11 +32,13 @@
|
|||
|
||||
#include "net/Job.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Handle;
|
||||
class Hashrate;
|
||||
class IJobResultListener;
|
||||
class IWorker;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -48,6 +50,8 @@ class Workers
|
|||
{
|
||||
public:
|
||||
static Job job();
|
||||
static size_t hugePages();
|
||||
static size_t threads();
|
||||
static void printHashrate(bool detail);
|
||||
static void setEnabled(bool enabled);
|
||||
static void setJob(const Job &job, bool donate);
|
||||
|
@ -58,20 +62,49 @@ public:
|
|||
static inline bool isEnabled() { return m_enabled; }
|
||||
static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; }
|
||||
static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; }
|
||||
static inline Hashrate *hashrate() { return m_hashrate; }
|
||||
static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); }
|
||||
static inline void pause() { m_active = false; m_paused = 1; m_sequence++; }
|
||||
static inline void setListener(IJobResultListener *listener) { m_listener = listener; }
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
static void threadsSummary(rapidjson::Document &doc);
|
||||
# endif
|
||||
|
||||
private:
|
||||
static void onReady(void *arg);
|
||||
static void onResult(uv_async_t *handle);
|
||||
static void onTick(uv_timer_t *handle);
|
||||
static void start(IWorker *worker);
|
||||
|
||||
class LaunchStatus
|
||||
{
|
||||
public:
|
||||
inline LaunchStatus() :
|
||||
colors(true),
|
||||
hugePages(0),
|
||||
pages(0),
|
||||
started(0),
|
||||
threads(0),
|
||||
ways(0),
|
||||
algo(xmrig::CRYPTONIGHT)
|
||||
{}
|
||||
|
||||
bool colors;
|
||||
size_t hugePages;
|
||||
size_t pages;
|
||||
size_t started;
|
||||
size_t threads;
|
||||
size_t ways;
|
||||
xmrig::Algo algo;
|
||||
};
|
||||
|
||||
static bool m_active;
|
||||
static bool m_enabled;
|
||||
static Hashrate *m_hashrate;
|
||||
static IJobResultListener *m_listener;
|
||||
static Job m_job;
|
||||
static LaunchStatus m_status;
|
||||
static std::atomic<int> m_paused;
|
||||
static std::atomic<uint64_t> m_sequence;
|
||||
static std::list<JobResult> m_queue;
|
||||
|
|
Loading…
Reference in a new issue