1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-10 17:12:46 -05:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Tony Butler
460ae15b85 Update/Improve API docs 2023-05-23 16:49:48 -06:00
Tony Butler
2e167031cc Cleanup API code 2023-05-23 16:49:48 -06:00
xmrig
02d45834e1 Merge pull request #3273 from SChernykh/dev
RandomX: fixed undefined behavior
2023-05-23 20:18:32 +07:00
SChernykh
1252a4710e RandomX: fixed undefined behavior
Using an inactive member of a `union` is an undefined behavior in C++
2023-05-23 14:40:12 +02:00
xmrig
5891f1f06b Merge pull request #3271 from SChernykh/opt_genprog
RandomX: optimized program generation
2023-05-22 05:25:32 +07:00
SChernykh
5dcbab7e3a RandomX: optimized program generation 2023-05-21 17:44:20 +02:00
xmrig
7b51e23aa0 Merge pull request #3254 from SChernykh/dev
Tweaked auto-tuning for Intel CPUs
2023-04-19 12:29:58 +07:00
SChernykh
7f7fc363e1 Tweaked auto-tuning for Intel CPUs
Alder Lake and newer CPUs have exclusive L3 cache and benefit from more threads until L3+L2 is filled.
2023-04-18 21:20:45 +02:00
XMRig
c4e1363148 #3245 Improved algorithm negotiation for donation rounds by sending extra information about current mining job. 2023-04-07 23:35:05 +07:00
XMRig
a2e9b3456d v6.19.3-dev 2023-04-04 00:34:54 +07:00
XMRig
4790318685 Merge branch 'master' into dev 2023-04-04 00:34:22 +07:00
20 changed files with 562 additions and 151 deletions

View File

@@ -4,7 +4,7 @@ If you want use HTTP API you need enable it (`"enabled": true,`) then choice `po
Offical HTTP client for API: http://workers.xmrig.info/ Offical HTTP client for API: http://workers.xmrig.info/
Example configuration: Example configuration, used in Curl examples below:
```json ```json
"api": { "api": {
@@ -12,11 +12,11 @@ Example configuration:
"worker-id": null, "worker-id": null,
}, },
"http": { "http": {
"enabled": false, "enabled": true,
"host": "127.0.0.1", "host": "127.0.0.1",
"port": 0, "port": 44444,
"access-token": null, "access-token": "SECRET",
"restricted": true "restricted": false
} }
``` ```
@@ -37,30 +37,78 @@ Versions before 2.15 was use another options for API https://github.com/xmrig/xm
## Endpoints ## Endpoints
### GET /1/summary ### APIVersion 2
Get miner summary information. [Example](api/1/summary.json). #### GET /2/summary
### GET /1/threads Get miner summary information. [Example](api/2/summary.json).
Get detailed information about miner threads. [Example](api/1/threads.json). #### GET /2/backends
Get detailed information about miner backends. [Example](api/2/backends.json).
### APIVersion 1 (deprecated)
#### GET /1/summary
Get miner summary information. Currently identical to `GET /2/summary`
#### GET /1/threads
**REMOVED** Get detailed information about miner threads. [Example](api/1/threads.json).
Functionally replaced by `GET /2/backends` which contains a `threads` item per backend.
### APIVersion 0 (deprecated)
#### GET /api.json
Get miner summary information. Currently identical to `GET /2/summary`
## Restricted endpoints ## 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`). 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 ### JSON-RPC Interface
Get current miner configuration. [Example](api/1/config.json). #### POST /json_rpc
Control miner with JSON-RPC. Methods: `pause`, `resume`, `stop`, `start`
### PUT /1/config Curl example:
```
curl -v --data "{\"method\":\"pause\",\"id\":1}" -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/json_rpc
```
### APIVersion 2
#### GET /2/config
Get current miner configuration. [Example](api/2/config.json).
#### PUT /2/config
Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner. Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner.
Curl example: 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 ...GET current config...
curl -v -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/2/config > config.json
...make changes...
vim config.json
...PUT changed config...
curl -v --data-binary @config.json -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/2/config
``` ```
### APIVersion 1 (deprecated)
#### GET /1/config
Get current miner configuration. Currently identical to `GET /2/config`
#### PUT /1/config
Update current miner configuration. Currently identical to `PUT /2/config`

78
doc/api/2/backends.json Normal file
View File

@@ -0,0 +1,78 @@
[
{
"type": "cpu",
"enabled": true,
"algo": "rx/0",
"profile": "rx",
"hw-aes": true,
"priority": -1,
"msr": true,
"asm": "intel",
"argon2-impl": "AVX2",
"hugepages": [6, 6],
"memory": 6291456,
"hashrate": [1235.78, 1228.89, null],
"threads": [
{
"intensity": 1,
"affinity": 0,
"av": 1,
"hashrate": [409.75, 406.58, null]
},
{
"intensity": 1,
"affinity": 2,
"av": 1,
"hashrate": [412.9, 411.33, null]
},
{
"intensity": 1,
"affinity": 4,
"av": 1,
"hashrate": [413.11, 410.98, null]
}
]
},
{
"type": "cuda",
"enabled": true,
"algo": "cn-heavy/xhv",
"profile": "cn-heavy/xhv",
"versions": {
"cuda-runtime": "11.6",
"cuda-driver": "11.6",
"plugin": "6.17.1-dev",
"nvml": "11.512.15",
"driver": "512.15"
},
"hashrate": [247.02, 247.34, null],
"threads": [
{
"index": 0,
"threads": 32,
"blocks": 38,
"bfactor": 6,
"bsleep": 25,
"affinity": -1,
"cclock": 0,
"mclock": 0,
"dataset_host": false,
"hashrate": [246.77, 247.26, null],
"name": "NVIDIA GeForce GTX 970",
"bus_id": "01:00.0",
"smx": 13,
"arch": 52,
"global_mem": 4294836224,
"clock": 1177,
"memory_clock": 3666,
"health": {
"temperature": 69,
"power": 161,
"clock": 1328,
"mem_clock": 3662,
"fan_speed": [100]
}
}
]
}
]

136
doc/api/2/config.json Normal file
View File

@@ -0,0 +1,136 @@
{
"api": {
"id": null,
"worker-id": null
},
"http": {
"enabled": true,
"host": "127.0.0.1",
"port": 44444,
"access-token": "SECRET",
"restricted": false
},
"autosave": true,
"background": false,
"colors": true,
"title": true,
"randomx": {
"init": -1,
"init-avx2": -1,
"mode": "auto",
"1gb-pages": true,
"rdmsr": true,
"wrmsr": true,
"cache_qos": false,
"numa": true,
"scratchpad_prefetch_mode": 1
},
"cpu": {
"enabled": true,
"huge-pages": true,
"huge-pages-jit": true,
"hw-aes": null,
"priority": null,
"memory-pool": true,
"yield": true,
"asm": true,
"argon2-impl": null,
"argon2": [0, 2, 4, 6, 5, 7],
"astrobwt/v2": [1, 2, 3, 4, 5, 6, 7],
"cn": [
[1, 0],
[1, 2],
[1, 4]
],
"cn-heavy": [
[1, 0],
[1, 2]
],
"cn-lite": [
[1, 0],
[1, 2],
[1, 4],
[1, 6],
[1, 5],
[1, 7]
],
"cn-pico": [
[2, 1],
[2, 2],
[2, 3],
[2, 4],
[2, 5],
[2, 6],
[2, 7]
],
"cn/2": [
[1, 0],
[1, 2],
[1, 4]
],
"cn/upx2": [
[2, 1],
[2, 2],
[2, 3],
[2, 4],
[2, 5],
[2, 6],
[2, 7]
],
"ghostrider": [
[8, 0],
[8, 2],
[8, 4]
],
"rx": [0, 2, 4],
"rx/arq": [1, 2, 3, 4, 5, 6, 7],
"rx/keva": [0, 2, 4, 6, 5, 7],
"rx/wow": [0, 2, 4, 6, 5, 7],
"cn-lite/0": false,
"cn/0": "cn"
},
"log-file": null,
"donate-level": 0,
"donate-over-proxy": 0,
"pools": [
{
"algo": null,
"coin": null,
"url": "some.pool:10064",
"user": "4blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahbl",
"pass": "x",
"rig-id": null,
"nicehash": false,
"keepalive": true,
"enabled": true,
"tls": false,
"wss": false,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
}
],
"retries": 5,
"retry-pause": 5,
"print-time": 64,
"syslog": false,
"tls": {
"enabled": false,
"protocols": null,
"cert": null,
"cert_key": null,
"ciphers": null,
"ciphersuites": null,
"dhparam": null
},
"dns": {
"ipv6": false,
"ttl": 30
},
"user-agent": null,
"verbose": 1,
"watch": true,
"pause-on-battery": false,
"pause-on-active": false
}

76
doc/api/2/summary.json Normal file
View File

@@ -0,0 +1,76 @@
{
"id": "51aca77da137cb62",
"worker_id": "tpad",
"uptime": 106,
"restricted": false,
"resources": {
"memory": {
"free": 4977348608,
"total": 16659546112,
"resident_set_memory": 16441344
},
"load_average": [3.4, 2.7, 2.44],
"hardware_concurrency": 8
},
"features": ["api", "asm", "http", "hwloc", "tls"],
"results": {
"diff_current": 37638,
"shares_good": 3,
"shares_total": 3,
"avg_time": 35,
"avg_time_ms": 35603,
"hashes_total": 165638,
"best": [358821, 344438, 73371, 0, 0, 0, 0, 0, 0, 0]
},
"algo": "rx/0",
"connection": {
"pool": "some.pool:20064",
"ip": "127.1.2.3",
"uptime": 106,
"uptime_ms": 106811,
"ping": 405,
"failures": 0,
"tls": "TLSv1.3",
"tls-fingerprint": null,
"algo": "rx/0",
"diff": 37638,
"accepted": 3,
"rejected": 0,
"avg_time": 35,
"avg_time_ms": 35603,
"hashes_total": 165638
},
"version": "6.17.1-dev",
"kind": "miner",
"ua": "XMRig/6.17.1-dev (Linux x86_64) libuv/1.43.0 gcc/9.4.0",
"cpu": {
"brand": "Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz",
"family": 6,
"model": 60,
"stepping": 3,
"proc_info": 198339,
"aes": true,
"avx2": true,
"x64": true,
"64_bit": true,
"l2": 1048576,
"l3": 6291456,
"cores": 4,
"threads": 8,
"packages": 1,
"nodes": 1,
"backend": "hwloc/2.7.0",
"msr": "intel",
"assembly": "intel",
"arch": "x86_64",
"flags": ["aes", "avx", "avx2", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "sse4.1", "popcnt"]
},
"donate_level": 0,
"paused": false,
"algorithms": ["cn/0", "cn/1", "cn/2", "cn/r", "cn/fast", "cn/half", "cn/xao", "cn/rto", "cn/rwz", "cn/zls", "cn/double", "cn/ccx", "cn-lite/1", "cn-heavy/0", "cn-heavy/tube", "cn-heavy/xhv", "cn-pico", "cn-pico/tlo", "cn/upx2", "rx/0", "rx/wow", "rx/arq", "rx/graft", "rx/sfx", "rx/keva", "argon2/chukwa", "argon2/chukwav2", "argon2/ninja", "astrobwt/v2", "ghostrider"],
"hashrate": {
"total": [1207.19, 1210.82, null],
"highest": 1316.85
},
"hugepages": [6, 6]
}

View File

@@ -298,8 +298,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
cores.reserve(m_cores); cores.reserve(m_cores);
findByType(cache, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); }); findByType(cache, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); });
const bool L3_exclusive = isCacheExclusive(cache);
# ifdef XMRIG_ALGO_GHOSTRIDER # ifdef XMRIG_ALGO_GHOSTRIDER
if ((algorithm == Algorithm::GHOSTRIDER_RTM) && (PUs > cores.size()) && (PUs < cores.size() * 2)) { if ((algorithm == Algorithm::GHOSTRIDER_RTM) && L3_exclusive && (PUs > cores.size()) && (PUs < cores.size() * 2)) {
// Don't use E-cores on Alder Lake // Don't use E-cores on Alder Lake
cores.erase(std::remove_if(cores.begin(), cores.end(), [](hwloc_obj_t c) { return hwloc_bitmap_weight(c->cpuset) == 1; }), cores.end()); cores.erase(std::remove_if(cores.begin(), cores.end(), [](hwloc_obj_t c) { return hwloc_bitmap_weight(c->cpuset) == 1; }), cores.end());
@@ -311,7 +313,6 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
# endif # endif
size_t L3 = cache->attr->cache.size; size_t L3 = cache->attr->cache.size;
const bool L3_exclusive = isCacheExclusive(cache);
size_t L2 = 0; size_t L2 = 0;
int L2_associativity = 0; int L2_associativity = 0;
size_t extra = 0; size_t extra = 0;
@@ -349,6 +350,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
} }
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
if ((algorithm.family() == Algorithm::RANDOM_X) && L3_exclusive && (PUs > cores.size()) && (PUs < cores.size() * 2)) {
// Use all L3+L2 on latest Intel CPUs with P-cores, E-cores and exclusive L3 cache
cacheHashes = (L3 + L2) / scratchpad;
}
if (extra == 0 && algorithm.l2() > 0) { if (extra == 0 && algorithm.l2() > 0) {
cacheHashes = std::min<size_t>(std::max<size_t>(L2 / algorithm.l2(), cores.size()), cacheHashes); cacheHashes = std::min<size_t>(std::max<size_t>(L2 / algorithm.l2(), cores.size()), cacheHashes);
} }

View File

@@ -52,6 +52,8 @@ public:
enum RequestType { enum RequestType {
REQ_UNKNOWN, REQ_UNKNOWN,
REQ_SUMMARY, REQ_SUMMARY,
REQ_BACKENDS,
REQ_CONFIG,
REQ_JSON_RPC REQ_JSON_RPC
}; };

View File

@@ -60,7 +60,7 @@ protected:
inline Source source() const override { return m_source; } inline Source source() const override { return m_source; }
inline void done(int) override { m_state = STATE_DONE; } inline void done(int) override { m_state = STATE_DONE; }
int m_version = 1; int m_version = 0;
RequestType m_type = REQ_UNKNOWN; RequestType m_type = REQ_UNKNOWN;
State m_state = STATE_NEW; State m_state = STATE_NEW;
String m_rpcMethod; String m_rpcMethod;

View File

@@ -67,10 +67,33 @@ xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
m_res(req.id()), m_res(req.id()),
m_url(req.url.c_str()) m_url(req.url.c_str())
{ {
if (method() == METHOD_GET) { if (url().size() > 4 && memcmp(url().data(), "/", 1) == 0 && memcmp(url().data()+2, "/", 1) == 0) {
if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") { if (memcmp(url().data(), "/2/", 3) == 0) {
m_type = REQ_SUMMARY; m_version = 2;
} else if (memcmp(url().data(), "/1/", 3) == 0) {
m_version = 1;
} }
switch (url().size()) {
case 9:
if (memcmp(url().data()+3, "config", 6) == 0) {
m_type = REQ_CONFIG;
}
break;
case 10:
if (memcmp(url().data()+3, "summary", 7) == 0) {
m_type = REQ_SUMMARY;
}
break;
case 11:
if (memcmp(url().data()+3, "backends", 8) == 0) {
m_type = REQ_BACKENDS;
}
break;
}
}
if (url() == "/api.json") {
m_type = REQ_SUMMARY;
} }
if (method() == METHOD_POST && url() == "/json_rpc") { if (method() == METHOD_POST && url() == "/json_rpc") {
@@ -94,12 +117,6 @@ xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
return; return;
} }
if (url().size() > 4) {
if (memcmp(url().data(), "/2/", 3) == 0) {
m_version = 2;
}
}
} }

View File

@@ -45,13 +45,6 @@
#ifdef XMRIG_FEATURE_API #ifdef XMRIG_FEATURE_API
# include "base/api/Api.h" # include "base/api/Api.h"
# include "base/api/interfaces/IApiRequest.h" # include "base/api/interfaces/IApiRequest.h"
namespace xmrig {
static const char *kConfigPathV1 = "/1/config";
static const char *kConfigPathV2 = "/2/config";
} // namespace xmrig
#endif #endif
@@ -317,7 +310,7 @@ void xmrig::Base::onFileChanged(const String &fileName)
void xmrig::Base::onRequest(IApiRequest &request) void xmrig::Base::onRequest(IApiRequest &request)
{ {
if (request.method() == IApiRequest::METHOD_GET) { if (request.method() == IApiRequest::METHOD_GET) {
if (request.url() == kConfigPathV1 || request.url() == kConfigPathV2) { if (request.type() == IApiRequest::REQ_CONFIG) {
if (request.isRestricted()) { if (request.isRestricted()) {
return request.done(403); return request.done(403);
} }
@@ -327,7 +320,7 @@ void xmrig::Base::onRequest(IApiRequest &request)
} }
} }
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) { else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
if (request.url() == kConfigPathV1 || request.url() == kConfigPathV2) { if (request.type() == IApiRequest::REQ_CONFIG) {
request.accept(); request.accept();
if (!reload(request.json())) { if (!reload(request.json())) {

View File

@@ -689,7 +689,7 @@ void xmrig::Miner::onRequest(IApiRequest &request)
d_ptr->getMiner(request.reply(), request.doc(), request.version()); d_ptr->getMiner(request.reply(), request.doc(), request.version());
d_ptr->getHashrate(request.reply(), request.doc(), request.version()); d_ptr->getHashrate(request.reply(), request.doc(), request.version());
} }
else if (request.url() == "/2/backends") { else if (request.type() == IApiRequest::REQ_BACKENDS && request.version() == 2) {
request.accept(); request.accept();
d_ptr->getBackends(request.reply(), request.doc()); d_ptr->getBackends(request.reply(), request.doc());
@@ -711,6 +711,12 @@ void xmrig::Miner::onRequest(IApiRequest &request)
stop(); stop();
} }
else if (request.rpcMethod() == "start") {
request.accept();
const auto config = d_ptr->controller->config();
onConfigChanged(config, config);
}
} }
for (IBackend *backend : d_ptr->backends) { for (IBackend *backend : d_ptr->backends) {

View File

@@ -7,8 +7,8 @@
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 tevador <tevador@gmail.com> * Copyright 2018-2019 tevador <tevador@gmail.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
#define XMRIG_KP_HASH_H #define XMRIG_KP_HASH_H
#include <stdint.h> #include <cstdint>
namespace xmrig namespace xmrig
@@ -43,16 +43,16 @@ class KPHash
public: public:
static constexpr uint32_t EPOCH_LENGTH = 7500; static constexpr uint32_t EPOCH_LENGTH = 7500;
static constexpr uint32_t PERIOD_LENGTH = 3; static constexpr uint32_t PERIOD_LENGTH = 3;
static constexpr int CNT_CACHE = 11; static constexpr int CNT_CACHE = 11;
static constexpr int CNT_MATH = 18; static constexpr int CNT_MATH = 18;
static constexpr uint32_t REGS = 32; static constexpr uint32_t REGS = 32;
static constexpr uint32_t LANES = 16; static constexpr uint32_t LANES = 16;
static void calculate(const KPCache& light_cache, uint32_t block_height, const uint8_t (&header_hash)[32], uint64_t nonce, uint32_t (&output)[8], uint32_t (&mix_hash)[8]); static void calculate(const KPCache& light_cache, uint32_t block_height, const uint8_t (&header_hash)[32], uint64_t nonce, uint32_t (&output)[8], uint32_t (&mix_hash)[8]);
}; };
} /* namespace xmrig */ } // namespace xmrig
#endif /* XMRIG_KP_HASH_H */ #endif // XMRIG_KP_HASH_H

View File

@@ -34,6 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "base/tools/Chrono.h" #include "base/tools/Chrono.h"
#include "crypto/randomx/randomx.h" #include "crypto/randomx/randomx.h"
#include "crypto/randomx/soft_aes.h" #include "crypto/randomx/soft_aes.h"
#include "crypto/randomx/instruction.hpp"
#include "crypto/randomx/common.hpp"
#include "crypto/rx/Profiler.h" #include "crypto/rx/Profiler.h"
#define AES_HASH_1R_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d #define AES_HASH_1R_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d
@@ -165,6 +167,9 @@ void fillAes1Rx4(void *state, size_t outputSize, void *buffer) {
template void fillAes1Rx4<true>(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4<true>(void *state, size_t outputSize, void *buffer);
template void fillAes1Rx4<false>(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4<false>(void *state, size_t outputSize, void *buffer);
static constexpr randomx::Instruction inst{ 0xFF, 7, 7, 0xFF, 0xFFFFFFFFU };
alignas(16) static const randomx::Instruction inst_mask[2] = { inst, inst };
template<int softAes> template<int softAes>
void fillAes4Rx4(void *state, size_t outputSize, void *buffer) { void fillAes4Rx4(void *state, size_t outputSize, void *buffer) {
const uint8_t* outptr = (uint8_t*)buffer; const uint8_t* outptr = (uint8_t*)buffer;
@@ -187,32 +192,42 @@ void fillAes4Rx4(void *state, size_t outputSize, void *buffer) {
state2 = rx_load_vec_i128((rx_vec_i128*)state + 2); state2 = rx_load_vec_i128((rx_vec_i128*)state + 2);
state3 = rx_load_vec_i128((rx_vec_i128*)state + 3); state3 = rx_load_vec_i128((rx_vec_i128*)state + 3);
while (outptr < outputEnd) { #define TRANSFORM do { \
state0 = aesdec<softAes>(state0, key0); state0 = aesdec<softAes>(state0, key0); \
state1 = aesenc<softAes>(state1, key0); state1 = aesenc<softAes>(state1, key0); \
state2 = aesdec<softAes>(state2, key4); state2 = aesdec<softAes>(state2, key4); \
state3 = aesenc<softAes>(state3, key4); state3 = aesenc<softAes>(state3, key4); \
state0 = aesdec<softAes>(state0, key1); \
state0 = aesdec<softAes>(state0, key1); state1 = aesenc<softAes>(state1, key1); \
state1 = aesenc<softAes>(state1, key1); state2 = aesdec<softAes>(state2, key5); \
state2 = aesdec<softAes>(state2, key5); state3 = aesenc<softAes>(state3, key5); \
state3 = aesenc<softAes>(state3, key5); state0 = aesdec<softAes>(state0, key2); \
state1 = aesenc<softAes>(state1, key2); \
state0 = aesdec<softAes>(state0, key2); state2 = aesdec<softAes>(state2, key6); \
state1 = aesenc<softAes>(state1, key2); state3 = aesenc<softAes>(state3, key6); \
state2 = aesdec<softAes>(state2, key6); state0 = aesdec<softAes>(state0, key3); \
state3 = aesenc<softAes>(state3, key6); state1 = aesenc<softAes>(state1, key3); \
state2 = aesdec<softAes>(state2, key7); \
state0 = aesdec<softAes>(state0, key3); state3 = aesenc<softAes>(state3, key7); \
state1 = aesenc<softAes>(state1, key3); } while (0)
state2 = aesdec<softAes>(state2, key7);
state3 = aesenc<softAes>(state3, key7);
for (int i = 0; i < 2; ++i, outptr += 64) {
TRANSFORM;
rx_store_vec_i128((rx_vec_i128*)outptr + 0, state0); rx_store_vec_i128((rx_vec_i128*)outptr + 0, state0);
rx_store_vec_i128((rx_vec_i128*)outptr + 1, state1); rx_store_vec_i128((rx_vec_i128*)outptr + 1, state1);
rx_store_vec_i128((rx_vec_i128*)outptr + 2, state2); rx_store_vec_i128((rx_vec_i128*)outptr + 2, state2);
rx_store_vec_i128((rx_vec_i128*)outptr + 3, state3); rx_store_vec_i128((rx_vec_i128*)outptr + 3, state3);
}
static_assert(sizeof(inst_mask) == sizeof(rx_vec_i128), "Incorrect inst_mask size");
const rx_vec_i128 mask = *reinterpret_cast<const rx_vec_i128*>(inst_mask);
while (outptr < outputEnd) {
TRANSFORM;
rx_store_vec_i128((rx_vec_i128*)outptr + 0, rx_and_vec_i128(state0, mask));
rx_store_vec_i128((rx_vec_i128*)outptr + 1, rx_and_vec_i128(state1, mask));
rx_store_vec_i128((rx_vec_i128*)outptr + 2, rx_and_vec_i128(state2, mask));
rx_store_vec_i128((rx_vec_i128*)outptr + 3, rx_and_vec_i128(state3, mask));
outptr += 64; outptr += 64;
} }
} }

View File

@@ -126,6 +126,7 @@ FORCE_INLINE rx_vec_f128 rx_set1_vec_f128(uint64_t x) {
#define rx_xor_vec_f128 _mm_xor_pd #define rx_xor_vec_f128 _mm_xor_pd
#define rx_and_vec_f128 _mm_and_pd #define rx_and_vec_f128 _mm_and_pd
#define rx_and_vec_i128 _mm_and_si128
#define rx_or_vec_f128 _mm_or_pd #define rx_or_vec_f128 _mm_or_pd
#ifdef __AES__ #ifdef __AES__
@@ -278,6 +279,10 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
return (rx_vec_f128)vec_and(a,b); return (rx_vec_f128)vec_and(a,b);
} }
FORCE_INLINE rx_vec_i128 rx_and_vec_i128(rx_vec_i128 a, rx_vec_i128 b) {
return (rx_vec_i128)vec_and(a, b);
}
FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
return (rx_vec_f128)vec_or(a,b); return (rx_vec_f128)vec_or(a,b);
} }
@@ -444,6 +449,8 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
return vreinterpretq_f64_u8(vandq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b))); return vreinterpretq_f64_u8(vandq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b)));
} }
#define rx_and_vec_i128 vandq_u8
FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
return vreinterpretq_f64_u8(vorrq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b))); return vreinterpretq_f64_u8(vorrq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b)));
} }
@@ -635,6 +642,13 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
return x; return x;
} }
FORCE_INLINE rx_vec_i128 rx_and_vec_i128(rx_vec_i128 a, rx_vec_i128 b) {
rx_vec_i128 x;
x.u64[0] = a.u64[0] & b.u64[0];
x.u64[1] = a.u64[1] & b.u64[1];
return x;
}
FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) {
rx_vec_f128 x; rx_vec_f128 x;
x.i.u64[0] = a.i.u64[0] | b.i.u64[0]; x.i.u64[0] = a.i.u64[0] | b.i.u64[0];

View File

@@ -144,8 +144,6 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
for (uint32_t i = 0; i < program.getSize(); ++i) for (uint32_t i = 0; i < program.getSize(); ++i)
{ {
Instruction& instr = program(i); Instruction& instr = program(i);
instr.src %= RegistersCount;
instr.dst %= RegistersCount;
(this->*engine[instr.opcode])(instr, codePos); (this->*engine[instr.opcode])(instr, codePos);
} }
@@ -204,8 +202,6 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
for (uint32_t i = 0; i < program.getSize(); ++i) for (uint32_t i = 0; i < program.getSize(); ++i)
{ {
Instruction& instr = program(i); Instruction& instr = program(i);
instr.src %= RegistersCount;
instr.dst %= RegistersCount;
(this->*engine[instr.opcode])(instr, codePos); (this->*engine[instr.opcode])(instr, codePos);
} }

View File

@@ -312,11 +312,19 @@ namespace randomx {
freePagedMemory(allocatedCode, allocatedSize); freePagedMemory(allocatedCode, allocatedSize);
} }
template<size_t N>
static FORCE_INLINE void prefetch_data(const void* data) {
rx_prefetch_nta(data);
prefetch_data<N - 1>(reinterpret_cast<const char*>(data) + 64);
}
template<> FORCE_INLINE void prefetch_data<0>(const void*) {}
template<typename T> static FORCE_INLINE void prefetch_data(const T& data) { prefetch_data<(sizeof(T) + 63) / 64>(&data); }
void JitCompilerX86::prepare() { void JitCompilerX86::prepare() {
for (size_t i = 0; i < sizeof(engine); i += 64) prefetch_data(engine);
rx_prefetch_nta((const char*)(&engine) + i); prefetch_data(RandomX_CurrentConfig);
for (size_t i = 0; i < sizeof(RandomX_CurrentConfig); i += 64)
rx_prefetch_nta((const char*)(&RandomX_CurrentConfig) + i);
} }
void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) { void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) {
@@ -748,7 +756,7 @@ namespace randomx {
template void JitCompilerX86::genAddressReg<true>(const Instruction& instr, const uint32_t src, uint8_t* code, uint32_t& codePos); template void JitCompilerX86::genAddressReg<true>(const Instruction& instr, const uint32_t src, uint8_t* code, uint32_t& codePos);
FORCE_INLINE void JitCompilerX86::genAddressRegDst(const Instruction& instr, uint8_t* code, uint32_t& codePos) { FORCE_INLINE void JitCompilerX86::genAddressRegDst(const Instruction& instr, uint8_t* code, uint32_t& codePos) {
const uint32_t dst = static_cast<uint32_t>(instr.dst % RegistersCount) << 16; const uint32_t dst = static_cast<uint32_t>(instr.dst) << 16;
*(uint32_t*)(code + codePos) = 0x24808d41 + dst; *(uint32_t*)(code + codePos) = 0x24808d41 + dst;
codePos += (dst == (RegisterNeedsSib << 16)) ? 4 : 3; codePos += (dst == (RegisterNeedsSib << 16)) ? 4 : 3;
@@ -768,8 +776,8 @@ namespace randomx {
uint32_t pos = codePos; uint32_t pos = codePos;
uint8_t* const p = code + pos; uint8_t* const p = code + pos;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
const uint32_t sib = (instr.getModShift() << 6) | ((instr.src % RegistersCount) << 3) | dst; const uint32_t sib = (instr.getModShift() << 6) | (instr.src << 3) | dst;
uint32_t k = 0x048d4f + (dst << 19); uint32_t k = 0x048d4f + (dst << 19);
if (dst == RegisterNeedsDisplacement) if (dst == RegisterNeedsDisplacement)
@@ -788,8 +796,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -809,8 +817,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
if (src != dst) { if (src != dst) {
*(uint32_t*)(p + pos) = 0xc02b4d + (dst << 19) + (src << 16); *(uint32_t*)(p + pos) = 0xc02b4d + (dst << 19) + (src << 16);
@@ -830,8 +838,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -851,8 +859,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
if (src != dst) { if (src != dst) {
emit32(0xc0af0f4d + ((dst * 8 + src) << 24), p, pos); emit32(0xc0af0f4d + ((dst * 8 + src) << 24), p, pos);
@@ -871,8 +879,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -892,8 +900,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
*(uint32_t*)(p + pos) = 0xc08b49 + (dst << 16); *(uint32_t*)(p + pos) = 0xc08b49 + (dst << 16);
*(uint32_t*)(p + pos + 3) = 0xe0f749 + (src << 16); *(uint32_t*)(p + pos + 3) = 0xe0f749 + (src << 16);
@@ -908,8 +916,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
*(uint32_t*)(p + pos) = 0xC4D08B49 + (dst << 16); *(uint32_t*)(p + pos) = 0xC4D08B49 + (dst << 16);
*(uint32_t*)(p + pos + 4) = 0xC0F6FB42 + (dst << 27) + (src << 24); *(uint32_t*)(p + pos + 4) = 0xC0F6FB42 + (dst << 27) + (src << 24);
@@ -923,8 +931,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<false>(instr, src, p, pos); genAddressReg<false>(instr, src, p, pos);
@@ -947,8 +955,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<false>(instr, src, p, pos); genAddressReg<false>(instr, src, p, pos);
@@ -970,8 +978,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
*(uint64_t*)(p + pos) = 0x8b4ce8f749c08b49ull + (dst << 16) + (src << 40); *(uint64_t*)(p + pos) = 0x8b4ce8f749c08b49ull + (dst << 16) + (src << 40);
pos += 8; pos += 8;
@@ -985,8 +993,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<false>(instr, src, p, pos); genAddressReg<false>(instr, src, p, pos);
@@ -1011,7 +1019,7 @@ namespace randomx {
uint64_t divisor = instr.getImm32(); uint64_t divisor = instr.getImm32();
if (!isZeroOrPowerOf2(divisor)) { if (!isZeroOrPowerOf2(divisor)) {
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
const uint64_t reciprocal = randomx_reciprocal_fast(divisor); const uint64_t reciprocal = randomx_reciprocal_fast(divisor);
if (imul_rcp_storage_used < 16) { if (imul_rcp_storage_used < 16) {
@@ -1040,7 +1048,7 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
*(uint32_t*)(p + pos) = 0xd8f749 + (dst << 16); *(uint32_t*)(p + pos) = 0xd8f749 + (dst << 16);
pos += 3; pos += 3;
@@ -1052,8 +1060,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
*(uint32_t*)(p + pos) = 0xc0334d + (((dst << 3) + src) << 16); *(uint32_t*)(p + pos) = 0xc0334d + (((dst << 3) + src) << 16);
@@ -1073,8 +1081,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -1094,8 +1102,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
*(uint64_t*)(p + pos) = 0xc8d349c88b41ull + (src << 16) + (dst << 40); *(uint64_t*)(p + pos) = 0xc8d349c88b41ull + (src << 16) + (dst << 40);
@@ -1115,8 +1123,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
if (src != dst) { if (src != dst) {
*(uint64_t*)(p + pos) = 0xc0d349c88b41ull + (src << 16) + (dst << 40); *(uint64_t*)(p + pos) = 0xc0d349c88b41ull + (src << 16) + (dst << 40);
@@ -1136,8 +1144,8 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegistersCount; const uint32_t dst = instr.dst;
if (src != dst) { if (src != dst) {
*(uint32_t*)(p + pos) = 0xc0874d + (((dst << 3) + src) << 16); *(uint32_t*)(p + pos) = 0xc0874d + (((dst << 3) + src) << 16);
@@ -1153,7 +1161,7 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const uint64_t dst = instr.dst % RegistersCount; const uint64_t dst = instr.dst;
*(uint64_t*)(p + pos) = 0x01c0c60f66ull + (((dst << 3) + dst) << 24); *(uint64_t*)(p + pos) = 0x01c0c60f66ull + (((dst << 3) + dst) << 24);
pos += 5; pos += 5;
@@ -1182,7 +1190,7 @@ namespace randomx {
prevFPOperation = pos; prevFPOperation = pos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegisterCountFlt; const uint32_t dst = instr.dst % RegisterCountFlt;
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -1214,7 +1222,7 @@ namespace randomx {
prevFPOperation = pos; prevFPOperation = pos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint32_t dst = instr.dst % RegisterCountFlt; const uint32_t dst = instr.dst % RegisterCountFlt;
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -1257,7 +1265,7 @@ namespace randomx {
prevFPOperation = pos; prevFPOperation = pos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
const uint64_t dst = instr.dst % RegisterCountFlt; const uint64_t dst = instr.dst % RegisterCountFlt;
genAddressReg<true>(instr, src, p, pos); genAddressReg<true>(instr, src, p, pos);
@@ -1307,7 +1315,7 @@ namespace randomx {
uint32_t pos = codePos; uint32_t pos = codePos;
prevCFROUND = pos; prevCFROUND = pos;
const uint32_t src = instr.src % RegistersCount; const uint32_t src = instr.src;
*(uint32_t*)(p + pos) = 0x00C08B49 + (src << 16); *(uint32_t*)(p + pos) = 0x00C08B49 + (src << 16);
const int rotate = (static_cast<int>(instr.getImm32() & 63) - 2) & 63; const int rotate = (static_cast<int>(instr.getImm32() & 63) - 2) & 63;
@@ -1343,7 +1351,7 @@ namespace randomx {
uint32_t pos = codePos; uint32_t pos = codePos;
prevCFROUND = pos; prevCFROUND = pos;
const uint64_t src = instr.src % RegistersCount; const uint64_t src = instr.src;
const uint64_t rotate = (static_cast<int>(instr.getImm32() & 63) - 2) & 63; const uint64_t rotate = (static_cast<int>(instr.getImm32() & 63) - 2) & 63;
*(uint64_t*)(p + pos) = 0xC0F0FBC3C4ULL | (src << 32) | (rotate << 40); *(uint64_t*)(p + pos) = 0xC0F0FBC3C4ULL | (src << 32) | (rotate << 40);
@@ -1367,7 +1375,7 @@ namespace randomx {
uint8_t* const p = code; uint8_t* const p = code;
uint32_t pos = codePos; uint32_t pos = codePos;
const int reg = instr.dst % RegistersCount; const int reg = instr.dst;
int32_t jmp_offset = registerUsage[reg]; int32_t jmp_offset = registerUsage[reg];
// if it jumps over the previous FP instruction that uses rounding, treat it as if FP instruction happened now // if it jumps over the previous FP instruction that uses rounding, treat it as if FP instruction happened now
@@ -1426,7 +1434,7 @@ namespace randomx {
uint32_t pos = codePos; uint32_t pos = codePos;
genAddressRegDst(instr, p, pos); genAddressRegDst(instr, p, pos);
emit32(0x0604894c + (static_cast<uint32_t>(instr.src % RegistersCount) << 19), p, pos); emit32(0x0604894c + (static_cast<uint32_t>(instr.src) << 19), p, pos);
codePos = pos; codePos = pos;
} }

View File

@@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2019 Howard Chu <https://github.com/hyc> * Copyright (c) 2019 Howard Chu <https://github.com/hyc>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -292,8 +292,7 @@ void xmrig::Network::setJob(IClient *client, const Job &job, bool donate)
} }
if (!donate && m_donate) { if (!donate && m_donate) {
m_donate->setAlgo(job.algorithm()); static_cast<DonateStrategy *>(m_donate)->update(client, job);
m_donate->setProxy(client->pool().proxy());
} }
m_controller->miner()->setJob(job, donate); m_controller->miner()->setJob(job, donate);

View File

@@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2019 Howard Chu <https://github.com/hyc> * Copyright (c) 2019 Howard Chu <https://github.com/hyc>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -89,7 +89,7 @@ private:
}; };
} /* namespace xmrig */ } // namespace xmrig
#endif /* XMRIG_NETWORK_H */ #endif // XMRIG_NETWORK_H

View File

@@ -1,6 +1,6 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ static const char *kDonateHost = "donate.v2.xmrig.com";
static const char *kDonateHostTls = "donate.ssl.xmrig.com"; static const char *kDonateHostTls = "donate.ssl.xmrig.com";
#endif #endif
} /* namespace xmrig */ } // namespace xmrig
xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) : xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) :
@@ -98,6 +98,17 @@ xmrig::DonateStrategy::~DonateStrategy()
} }
void xmrig::DonateStrategy::update(IClient *client, const Job &job)
{
setAlgo(job.algorithm());
setProxy(client->pool().proxy());
m_diff = job.diff();
m_height = job.height();
m_seed = job.seed();
}
int64_t xmrig::DonateStrategy::submit(const JobResult &result) int64_t xmrig::DonateStrategy::submit(const JobResult &result)
{ {
return m_proxy ? m_proxy->submit(result) : m_strategy->submit(result); return m_proxy ? m_proxy->submit(result) : m_strategy->submit(result);
@@ -199,13 +210,13 @@ void xmrig::DonateStrategy::onLogin(IClient *, rapidjson::Document &doc, rapidjs
params.AddMember("url", m_pools[0].url().toJSON(), allocator); params.AddMember("url", m_pools[0].url().toJSON(), allocator);
# endif # endif
setAlgorithms(doc, params); setParams(doc, params);
} }
void xmrig::DonateStrategy::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value &params) void xmrig::DonateStrategy::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value &params)
{ {
setAlgorithms(doc, params); setParams(doc, params);
} }
@@ -270,12 +281,20 @@ void xmrig::DonateStrategy::idle(double min, double max)
} }
void xmrig::DonateStrategy::setAlgorithms(rapidjson::Document &doc, rapidjson::Value &params) void xmrig::DonateStrategy::setJob(IClient *client, const Job &job, const rapidjson::Value &params)
{
if (isActive()) {
m_listener->onJob(this, client, job, params);
}
}
void xmrig::DonateStrategy::setParams(rapidjson::Document &doc, rapidjson::Value &params)
{ {
using namespace rapidjson; using namespace rapidjson;
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
auto algorithms = m_controller->miner()->algorithms();
Algorithms algorithms = m_controller->miner()->algorithms();
const size_t index = static_cast<size_t>(std::distance(algorithms.begin(), std::find(algorithms.begin(), algorithms.end(), m_algorithm))); const size_t index = static_cast<size_t>(std::distance(algorithms.begin(), std::find(algorithms.begin(), algorithms.end(), m_algorithm)));
if (index > 0 && index < algorithms.size()) { if (index > 0 && index < algorithms.size()) {
std::swap(algorithms[0], algorithms[index]); std::swap(algorithms[0], algorithms[index]);
@@ -287,14 +306,12 @@ void xmrig::DonateStrategy::setAlgorithms(rapidjson::Document &doc, rapidjson::V
algo.PushBack(StringRef(a.name()), allocator); algo.PushBack(StringRef(a.name()), allocator);
} }
params.AddMember("algo", algo, allocator); params.AddMember("algo", algo, allocator);
} params.AddMember("diff", m_diff, allocator);
params.AddMember("height", m_height, allocator);
if (!m_seed.empty()) {
void xmrig::DonateStrategy::setJob(IClient *client, const Job &job, const rapidjson::Value &params) params.AddMember("seed_hash", Cvt::toHex(m_seed, doc), allocator);
{
if (isActive()) {
m_listener->onJob(this, client, job, params);
} }
} }

View File

@@ -1,6 +1,6 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -20,15 +20,12 @@
#define XMRIG_DONATESTRATEGY_H #define XMRIG_DONATESTRATEGY_H
#include <vector>
#include "base/kernel/interfaces/IClientListener.h" #include "base/kernel/interfaces/IClientListener.h"
#include "base/kernel/interfaces/IStrategy.h" #include "base/kernel/interfaces/IStrategy.h"
#include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/interfaces/ITimerListener.h" #include "base/kernel/interfaces/ITimerListener.h"
#include "base/net/stratum/Pool.h" #include "base/net/stratum/Pool.h"
#include "base/tools/Object.h" #include "base/tools/Buffer.h"
namespace xmrig { namespace xmrig {
@@ -36,7 +33,6 @@ namespace xmrig {
class Client; class Client;
class Controller; class Controller;
class IStrategyListener;
class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener
@@ -47,6 +43,8 @@ public:
DonateStrategy(Controller *controller, IStrategyListener *listener); DonateStrategy(Controller *controller, IStrategyListener *listener);
~DonateStrategy() override; ~DonateStrategy() override;
void update(IClient *client, const Job &job);
protected: protected:
inline bool isActive() const override { return state() == STATE_ACTIVE; } inline bool isActive() const override { return state() == STATE_ACTIVE; }
inline IClient *client() const override { return m_proxy ? m_proxy : m_strategy->client(); } inline IClient *client() const override { return m_proxy ? m_proxy : m_strategy->client(); }
@@ -88,13 +86,14 @@ private:
IClient *createProxy(); IClient *createProxy();
void idle(double min, double max); void idle(double min, double max);
void setAlgorithms(rapidjson::Document &doc, rapidjson::Value &params);
void setJob(IClient *client, const Job &job, const rapidjson::Value &params); void setJob(IClient *client, const Job &job, const rapidjson::Value &params);
void setParams(rapidjson::Document &doc, rapidjson::Value &params);
void setResult(IClient *client, const SubmitResult &result, const char *error); void setResult(IClient *client, const SubmitResult &result, const char *error);
void setState(State state); void setState(State state);
Algorithm m_algorithm; Algorithm m_algorithm;
bool m_tls = false; bool m_tls = false;
Buffer m_seed;
char m_userId[65] = { 0 }; char m_userId[65] = { 0 };
const uint64_t m_donateTime; const uint64_t m_donateTime;
const uint64_t m_idleTime; const uint64_t m_idleTime;
@@ -105,12 +104,14 @@ private:
State m_state = STATE_NEW; State m_state = STATE_NEW;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
Timer *m_timer = nullptr; Timer *m_timer = nullptr;
uint64_t m_diff = 0;
uint64_t m_height = 0;
uint64_t m_now = 0; uint64_t m_now = 0;
uint64_t m_timestamp = 0; uint64_t m_timestamp = 0;
}; };
} /* namespace xmrig */ } // namespace xmrig
#endif /* XMRIG_DONATESTRATEGY_H */ #endif // XMRIG_DONATESTRATEGY_H

View File

@@ -22,7 +22,7 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig miner" #define APP_DESC "XMRig miner"
#define APP_VERSION "6.19.2" #define APP_VERSION "6.19.3-dev"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com"
@@ -30,7 +30,7 @@
#define APP_VER_MAJOR 6 #define APP_VER_MAJOR 6
#define APP_VER_MINOR 19 #define APP_VER_MINOR 19
#define APP_VER_PATCH 2 #define APP_VER_PATCH 3
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1930) # if (_MSC_VER >= 1930)