diff --git a/index.html b/index.html
index 88048abf..3a42983d 100644
--- a/index.html
+++ b/index.html
@@ -282,7 +282,7 @@ function isOnline(lastStatus) {
Algo |
Hashrate |
- Hashrate 5m |
+ Hashrate 1m |
Hashrate 60m |
Hashrate Highest |
diff --git a/src/Mem.cpp b/src/Mem.cpp
index 4437c673..05a2f31b 100644
--- a/src/Mem.cpp
+++ b/src/Mem.cpp
@@ -30,58 +30,29 @@
#include "Options.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;
-uint8_t *Mem::m_memory = nullptr;
-
+bool Mem::m_doubleHash = false;
+int Mem::m_algo = 0;
+int Mem::m_flags = 0;
+int Mem::m_threads = 0;
+size_t Mem::m_memorySize = 0;
+uint8_t *Mem::m_memory = nullptr;
+int64_t Mem::m_doubleHashThreadMask = -1L;
cryptonight_ctx *Mem::create(int threadId)
{
-# ifndef XMRIG_NO_AEON
- if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) {
- return createLite(threadId);
+ size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
+
+ size_t offset = 0;
+ for (int i=0; i < threadId; i++) {
+ offset += sizeof(cryptonight_ctx);
+ offset += isDoubleHash(i) ? scratchPadSize*2 : scratchPadSize;
}
-# endif
- cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
+ auto* ctx = reinterpret_cast(&m_memory[offset]);
- const int ratio = m_doubleHash ? 2 : 1;
- ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)];
+ size_t memOffset = offset+sizeof(cryptonight_ctx);
+
+ ctx->memory = &m_memory[memOffset];
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 = MEMORY * (threadId + 1);
-
- ctx = reinterpret_cast(&m_memory[offset + MEMORY_LITE]);
- ctx->memory = &m_memory[offset];
- return ctx;
- }
-
- ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]);
- ctx->memory = &m_memory[MEMORY * (threadId + 1)];
-
- return ctx;
-}
-#endif
diff --git a/src/Mem.h b/src/Mem.h
index dcd3a970..1325907f 100644
--- a/src/Mem.h
+++ b/src/Mem.h
@@ -45,10 +45,9 @@ public:
static bool allocate(const Options* options);
static cryptonight_ctx *create(int threadId);
- static void *calloc(size_t num, size_t size);
static void release();
- static inline bool isDoubleHash() { return m_doubleHash; }
+ static inline bool isDoubleHash(int threadId) { return m_doubleHash && (m_doubleHashThreadMask == -1L || ((m_doubleHashThreadMask >> threadId) & 1)); }
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; }
@@ -59,12 +58,9 @@ private:
static int m_algo;
static int m_flags;
static int m_threads;
- static size_t m_offset;
+ static int64_t m_doubleHashThreadMask;
+ static size_t m_memorySize;
VAR_ALIGN(16, static uint8_t *m_memory);
-
-# ifndef XMRIG_NO_AEON
- static cryptonight_ctx *createLite(int threadId);
-# endif
};
diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp
index d48c2833..e119f720 100644
--- a/src/Mem_unix.cpp
+++ b/src/Mem_unix.cpp
@@ -38,12 +38,22 @@ bool Mem::allocate(const Options* options)
m_algo = options->algo();
m_threads = options->threads();
m_doubleHash = options->doubleHash();
+ m_doubleHashThreadMask = options->doubleHashThreadMask();
+ m_memorySize = 0;
- const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
- const size_t size = MEMORY * (m_threads * ratio + 1);
+ size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
+ for (int i=0; i < m_threads; i++) {
+ m_memorySize += sizeof(cryptonight_ctx);
+
+ if (isDoubleHash(i)) {
+ m_memorySize += scratchPadSize*2;
+ } else {
+ m_memorySize += scratchPadSize;
+ }
+ }
if (!options->hugePages()) {
- m_memory = static_cast(_mm_malloc(size, 16));
+ m_memory = static_cast(_mm_malloc(m_memorySize, 16));
return true;
}
@@ -54,20 +64,20 @@ bool Mem::allocate(const Options* options)
# elif defined(__FreeBSD__)
m_memory = static_cast(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
# else
- m_memory = static_cast(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
+ m_memory = static_cast(mmap(0, m_memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
# endif
if (m_memory == MAP_FAILED) {
- m_memory = static_cast(_mm_malloc(size, 16));
+ m_memory = static_cast(_mm_malloc(m_memorySize, 16));
return true;
}
m_flags |= HugepagesEnabled;
- if (madvise(m_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) {
+ if (madvise(m_memory, m_memorySize, MADV_RANDOM | MADV_WILLNEED) != 0) {
LOG_ERR("madvise failed");
}
- if (mlock(m_memory, size) == 0) {
+ if (mlock(m_memory, m_memorySize) == 0) {
m_flags |= Lock;
}
@@ -77,14 +87,12 @@ bool Mem::allocate(const Options* options)
void Mem::release()
{
- const int size = MEMORY * (m_threads + 1);
-
if (m_flags & HugepagesEnabled) {
if (m_flags & Lock) {
- munlock(m_memory, size);
+ munlock(m_memory, m_memorySize);
}
- munmap(m_memory, size);
+ munmap(m_memory, m_memorySize);
}
else {
_mm_free(m_memory);
diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp
index 9348c0dd..ad9744e9 100644
--- a/src/Mem_win.cpp
+++ b/src/Mem_win.cpp
@@ -149,12 +149,22 @@ bool Mem::allocate(const Options* options)
m_algo = options->algo();
m_threads = options->threads();
m_doubleHash = options->doubleHash();
+ m_doubleHashThreadMask = options->doubleHashThreadMask();
+ m_memorySize = 0;
- const int ratio = (m_doubleHash && m_algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1;
- const size_t size = MEMORY * (m_threads * ratio + 1);
+ size_t scratchPadSize = m_algo == Options::ALGO_CRYPTONIGHT ? MEMORY : MEMORY_LITE;
+ for (int i=0; i < m_threads; i++) {
+ m_memorySize += sizeof(cryptonight_ctx);
+
+ if (isDoubleHash(i)) {
+ m_memorySize += scratchPadSize*2;
+ } else {
+ m_memorySize += scratchPadSize;
+ }
+ }
if (!options->hugePages()) {
- m_memory = static_cast(_mm_malloc(size, 16));
+ m_memory = static_cast(_mm_malloc(m_memorySize, 16));
return true;
}
@@ -162,9 +172,9 @@ bool Mem::allocate(const Options* options)
m_flags |= HugepagesAvailable;
}
- m_memory = static_cast(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
+ m_memory = static_cast(VirtualAlloc(NULL, m_memorySize, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
if (!m_memory) {
- m_memory = static_cast(_mm_malloc(size, 16));
+ m_memory = static_cast(_mm_malloc(m_memorySize, 16));
}
else {
m_flags |= HugepagesEnabled;
diff --git a/src/Options.cpp b/src/Options.cpp
index 0a6909e9..61f2f3f3 100644
--- a/src/Options.cpp
+++ b/src/Options.cpp
@@ -70,6 +70,7 @@ Options:\n"
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
+ --doublehash-thread-mask for av=2/4 only, limits doublehash to given threads (mask), (default: all threads)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
@@ -158,6 +159,7 @@ static struct option const options[] = {
{ "cc-client-config-folder", 1, nullptr, 4009 },
{ "cc-custom-dashboard", 1, nullptr, 4010 },
{ "daemonized", 0, nullptr, 4011 },
+ { "doublehash-thread-mask", 1, nullptr, 4013 },
{ 0, 0, 0, 0 }
};
@@ -180,6 +182,7 @@ static struct option const config_options[] = {
{ "syslog", 0, nullptr, 'S' },
{ "threads", 1, nullptr, 't' },
{ "user-agent", 1, nullptr, 1008 },
+ { "doublehash-thread-mask", 1, nullptr, 4013 },
{ 0, 0, 0, 0 }
};
@@ -281,7 +284,8 @@ Options::Options(int argc, char **argv) :
m_threads(0),
m_ccUpdateInterval(10),
m_ccPort(0),
- m_affinity(-1L)
+ m_affinity(-1L),
+ m_doubleHashThreadMask(-1L)
{
m_pools.push_back(new Url());
@@ -528,9 +532,14 @@ bool Options::parseArg(int key, const char *arg)
break;
case 1020: { /* --cpu-affinity */
- const char *p = strstr(arg, "0x");
- return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
- }
+ const char *p = strstr(arg, "0x");
+ return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
+ }
+
+ case 4013: { /* --doublehash-thread-mask */
+ const char *p = strstr(arg, "0x");
+ return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
+ }
case 1008: /* --user-agent */
free(m_userAgent);
@@ -634,6 +643,7 @@ bool Options::parseArg(int key, uint64_t arg)
m_ccPort = (int) arg;
}
break;
+
case 4012: /* --cc-update-interval-s */
if (arg < 1) {
showUsage(1);
@@ -642,6 +652,12 @@ bool Options::parseArg(int key, uint64_t arg)
m_ccUpdateInterval = (int) arg;
break;
+
+ case 4013: /* --doublehash-thread-mask */
+ if (arg) {
+ m_doubleHashThreadMask = arg;
+ }
+ break;
default:
break;
}
diff --git a/src/Options.h b/src/Options.h
index ad0ab60f..5402af32 100644
--- a/src/Options.h
+++ b/src/Options.h
@@ -88,6 +88,8 @@ public:
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
inline int ccPort() const { return m_ccPort; }
inline int64_t affinity() const { return m_affinity; }
+ inline int64_t doubleHashThreadMask() const { return m_doubleHashThreadMask; }
+ inline void setColors(bool colors) { m_colors = colors; }
inline static void release() { delete m_self; }
@@ -155,6 +157,7 @@ private:
int m_ccUpdateInterval;
int m_ccPort;
int64_t m_affinity;
+ int64_t m_doubleHashThreadMask;
std::vector m_pools;
};
diff --git a/src/Summary.cpp b/src/Summary.cpp
index c47eec9c..503bb67e 100644
--- a/src/Summary.cpp
+++ b/src/Summary.cpp
@@ -91,21 +91,30 @@ static void print_cpu()
static void print_threads()
{
- char buf[32];
- if (Options::i()->affinity() != -1L) {
- snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
+ char dhtMaskBuf[64];
+ if (Options::i()->doubleHashThreadMask() != -1L) {
+ snprintf(dhtMaskBuf, 64, ", doubleHashThreadMask=0x%" PRIX64, Options::i()->doubleHashThreadMask());
}
else {
- buf[0] = '\0';
+ dhtMaskBuf[0] = '\0';
}
- Log::i()->text(Options::i()->colors() ? "\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",
+ char affBuf[32];
+ if (Options::i()->affinity() != -1L) {
+ snprintf(affBuf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity());
+ }
+ else {
+ affBuf[0] = '\0';
+ }
+
+ Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s%s",
Options::i()->threads(),
Options::i()->algoName(),
Options::i()->algoVariant(),
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
Options::i()->donateLevel(),
- buf);
+ affBuf,
+ dhtMaskBuf);
}
diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp
index 30c672bd..a61cf36b 100644
--- a/src/cc/CCClient.cpp
+++ b/src/cc/CCClient.cpp
@@ -77,7 +77,7 @@ CCClient::CCClient(Options* options, uv_async_t* async)
m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
- m_clientStatus.setDoubleHashMode(Mem::isDoubleHash());
+ m_clientStatus.setDoubleHashMode(m_options->doubleHash());
m_clientStatus.setVersion(Version::string());
m_clientStatus.setCpuBrand(Cpu::brand());
diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp
index c4e56678..e1c774f0 100644
--- a/src/crypto/CryptoNight.cpp
+++ b/src/crypto/CryptoNight.cpp
@@ -30,7 +30,8 @@
#include "Options.h"
-void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
+void (*cryptonight_hash_ctx_s)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
+void (*cryptonight_hash_ctx_d)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr;
static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) {
@@ -93,40 +94,43 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output,
#endif
-bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx)
+void CryptoNight::hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
{
- cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx);
-
- return *reinterpret_cast(result.result + 24) < job.target();
+ cryptonight_hash_ctx_s(input, size, output, ctx);
}
+void CryptoNight::hashDouble(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx)
+{
+ cryptonight_hash_ctx_d(input, size, output, ctx);
+}
bool CryptoNight::init(int algo, int variant)
{
- if (variant < 1 || variant > 4) {
+ if (variant < 1 || variant > 4)
+ {
return false;
}
-# ifndef XMRIG_NO_AEON
- const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
-# else
- const int index = variant - 1;
-# endif
+ int index = 0;
- cryptonight_hash_ctx = cryptonight_variations[index];
+ if (variant == 3 || variant == 4)
+ {
+ index = 4;
+ }
+
+ if (algo == Options::ALGO_CRYPTONIGHT_LITE) {
+ index += 4;
+ }
+
+ cryptonight_hash_ctx_s = cryptonight_variations[index];
+ cryptonight_hash_ctx_d = cryptonight_variations[index+1];
return selfTest(algo);
}
-
-void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx)
+bool CryptoNight::selfTest(int algo)
{
- cryptonight_hash_ctx(input, size, output, ctx);
-}
-
-
-bool CryptoNight::selfTest(int algo) {
- if (cryptonight_hash_ctx == nullptr) {
+ if (cryptonight_hash_ctx_d == nullptr) {
return false;
}
@@ -135,14 +139,22 @@ bool CryptoNight::selfTest(int algo) {
struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
- cryptonight_hash_ctx(test_input, 76, output, ctx);
+ cryptonight_hash_ctx_d(test_input, 76, output, ctx);
_mm_free(ctx->memory);
_mm_free(ctx);
-# ifndef XMRIG_NO_AEON
- return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
-# else
- return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0;
-# endif
+ bool resultSingle = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, 32) == 0;
+
+ ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16);
+ ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16);
+
+ cryptonight_hash_ctx_d(test_input, 76, output, ctx);
+
+ _mm_free(ctx->memory);
+ _mm_free(ctx);
+
+ bool resultDouble = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, 64) == 0;
+
+ return resultSingle && resultDouble;
}
diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h
index 64fc0fd1..f562b21c 100644
--- a/src/crypto/CryptoNight.h
+++ b/src/crypto/CryptoNight.h
@@ -50,9 +50,9 @@ class JobResult;
class CryptoNight
{
public:
- static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx);
+ static void hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
static bool init(int algo, int variant);
- static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx);
+ static void hashDouble(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx* ctx);
private:
static bool selfTest(int algo);
diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h
index b2985379..3da686a0 100644
--- a/src/crypto/CryptoNight_test.h
+++ b/src/crypto/CryptoNight_test.h
@@ -47,14 +47,12 @@ const static uint8_t test_output0[64] = {
};
-#ifndef XMRIG_NO_AEON
const static uint8_t test_output1[64] = {
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,
};
-#endif
#endif /* __CRYPTONIGHT_TEST_H__ */
diff --git a/src/log/ConsoleLog.cpp b/src/log/ConsoleLog.cpp
index ef8516eb..fbc988be 100644
--- a/src/log/ConsoleLog.cpp
+++ b/src/log/ConsoleLog.cpp
@@ -28,6 +28,8 @@
#include
#include
+#include "Options.h"
+
#ifdef WIN32
# include
# include
@@ -39,16 +41,18 @@
ConsoleLog::ConsoleLog(bool colors) :
- m_colors(colors),
- m_stream(nullptr)
+ m_colors(colors),
+ m_stream(nullptr)
{
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
+ Options::i()->setColors(false);
+ m_colors = false;
return;
}
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
m_uvBuf.base = m_buf;
- m_stream = reinterpret_cast(&m_tty);
+ m_stream = reinterpret_cast(&m_tty);
# ifdef WIN32
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
@@ -65,10 +69,6 @@ ConsoleLog::ConsoleLog(bool colors) :
void ConsoleLog::message(int level, const char* fmt, va_list args)
{
- if (!isWritable()) {
- return;
- }
-
time_t now = time(nullptr);
tm stime;
@@ -113,7 +113,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
m_colors ? color : "",
fmt,
m_colors ? Log::kCL_N : ""
- );
+ );
print(args);
}
@@ -121,10 +121,6 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
void ConsoleLog::text(const char* fmt, va_list args)
{
- if (!isWritable()) {
- return;
- }
-
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
print(args);
@@ -149,5 +145,10 @@ void ConsoleLog::print(va_list args)
return;
}
- uv_try_write(m_stream, &m_uvBuf, 1);
+ if (!isWritable()) {
+ fprintf(stdout, m_buf);
+ fflush(stdout);
+ } else {
+ uv_try_write(m_stream, &m_uvBuf, 1);
+ }
}
diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp
index 46d6f366..b8aa91ba 100644
--- a/src/workers/DoubleWorker.cpp
+++ b/src/workers/DoubleWorker.cpp
@@ -82,17 +82,18 @@ void DoubleWorker::start()
}
m_count += 2;
+
*Job::nonce(m_state->blob) = ++m_state->nonce1;
*Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2;
- CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx);
+ CryptoNight::hashDouble(m_state->blob, m_state->job.size(), m_hash, m_ctx);
if (*reinterpret_cast(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()));
+ Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff()), m_id);
}
if (*reinterpret_cast(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()));
+ Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff()), m_id);
}
std::this_thread::yield();
diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp
index ecb566f8..242936bf 100644
--- a/src/workers/SingleWorker.cpp
+++ b/src/workers/SingleWorker.cpp
@@ -60,8 +60,10 @@ void SingleWorker::start()
m_count++;
*m_job.nonce() = ++m_result.nonce;
- if (CryptoNight::hash(m_job, m_result, m_ctx)) {
- Workers::submit(m_result);
+ CryptoNight::hash(m_job.blob(), m_job.size(), m_result.result, m_ctx);
+
+ if (*reinterpret_cast(m_result.result + 24) < m_job.target()) {
+ Workers::submit(m_result, m_id);
}
std::this_thread::yield();
@@ -103,10 +105,10 @@ void SingleWorker::consumeJob()
m_result = m_job;
if (m_job.isNicehash()) {
- m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id);
+ m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id);
}
else {
- m_result.nonce = 0xffffffffU / m_threads * m_id;
+ m_result.nonce = 0xffffffffU / (m_threads * 2) * m_id;
}
}
diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp
index 81e073bc..3480e43c 100644
--- a/src/workers/Workers.cpp
+++ b/src/workers/Workers.cpp
@@ -140,7 +140,7 @@ void Workers::stop()
}
-void Workers::submit(const JobResult &result)
+void Workers::submit(const JobResult &result, int threadId)
{
uv_mutex_lock(&m_mutex);
m_queue.push_back(result);
@@ -153,7 +153,7 @@ void Workers::submit(const JobResult &result)
void Workers::onReady(void *arg)
{
auto handle = static_cast(arg);
- if (Mem::isDoubleHash()) {
+ if (Mem::isDoubleHash(handle->threadId())) {
handle->setWorker(new DoubleWorker(handle));
}
else {
diff --git a/src/workers/Workers.h b/src/workers/Workers.h
index e76d0a62..22a2b376 100644
--- a/src/workers/Workers.h
+++ b/src/workers/Workers.h
@@ -48,7 +48,7 @@ public:
static void setJob(const Job &job);
static void start(int64_t affinity, int priority);
static void stop();
- static void submit(const JobResult &result);
+ static void submit(const JobResult &result, int threadId);
static inline bool isEnabled() { return m_enabled; }
static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; }