diff --git a/CMakeLists.txt b/CMakeLists.txt index c22bf1764..15c1d35da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(HEADERS src/Mem.h src/net/Client.h src/net/Job.h + src/net/JobResult.h src/net/Network.h src/net/Url.h src/Options.h @@ -84,7 +85,7 @@ endif() add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -99,7 +100,7 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvari set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -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_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") +#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index b6273dc52..e19e66ca5 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -25,6 +25,8 @@ #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_p.h" #include "crypto/CryptoNight_test.h" +#include "net/Job.h" +#include "net/JobResult.h" #include "Options.h" @@ -91,6 +93,14 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output, #endif +bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) +{ + cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx); + + return *reinterpret_cast(result.result + 24) < job.target(); +} + + bool CryptoNight::init(int algo, int variant) { if (variant < 1 || variant > 4) { diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index ce1b7ba83..fbb2f9753 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -39,9 +39,14 @@ struct cryptonight_ctx { }; +class Job; +class JobResult; + + class CryptoNight { public: + static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); static bool init(int algo, int variant); private: diff --git a/src/net/JobResult.h b/src/net/JobResult.h new file mode 100644 index 000000000..ba067cdc2 --- /dev/null +++ b/src/net/JobResult.h @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __JOBRESULT_H__ +#define __JOBRESULT_H__ + + +#include + + +class JobResult +{ +public: + char jobId[64]; + int poolId; + uint32_t nonce; + uint8_t result[32]; +}; + +#endif /* __JOBRESULT_H__ */ diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 6e4d78ed0..76fea5883 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,9 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(int threadId, int64_t affinity, bool nicehash) : +Handle::Handle(int threadId, int threads, int64_t affinity, bool nicehash) : m_nicehash(nicehash), m_threadId(threadId), + m_threads(threads), m_affinity(affinity), m_worker(nullptr) { diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 59bd47931..a8ad84c19 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -35,17 +35,19 @@ class IWorker; class Handle { public: - Handle(int threadId, int64_t affinity, bool nicehash); + Handle(int threadId, int threads, int64_t affinity, bool nicehash); void start(void *(*callback) (void *)); inline bool nicehash() const { return m_nicehash; } inline int threadId() const { return m_threadId; } + inline int threads() const { return m_threads; } inline int64_t affinity() const { return m_affinity; } inline void setWorker(IWorker *worker) { m_worker = worker; } private: bool m_nicehash; int m_threadId; + int m_threads; int64_t m_affinity; IWorker *m_worker; pthread_t m_thread; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index eacab9411..c102029c4 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -24,10 +24,10 @@ #include #include -#include #include "Console.h" +#include "crypto/CryptoNight.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" @@ -35,7 +35,6 @@ SingleWorker::SingleWorker(Handle *handle) : Worker(handle) { - LOG_WARN("SingleWorker %d", pthread_self()); } @@ -44,7 +43,6 @@ void SingleWorker::start() while (true) { if (Workers::isPaused()) { do { - LOG_ERR("SLEEP WAIT FOR WORK"); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } while (Workers::isPaused()); @@ -53,9 +51,12 @@ void SingleWorker::start() } while (!Workers::isOutdated(m_sequence)) { - LOG_ERR("WORK %lld %lld", Workers::sequence(), m_sequence); + m_count++; + *m_job.nonce() = ++m_result.nonce; - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + if (CryptoNight::hash(m_job, m_result, m_ctx)) { + Workers::submit(m_result); + } sched_yield(); } @@ -71,5 +72,13 @@ void SingleWorker::consumeJob() m_job = Workers::job(); m_sequence = Workers::sequence(); - LOG_WARN("consumeJob"); + memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); + m_result.poolId = m_job.poolId(); + + if (m_nicehash) { + m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); + } + else { + m_result.nonce = 0xffffffffU / m_threads * m_id; + } } diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 9820172cb..6ba59468a 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -26,6 +26,7 @@ #include "net/Job.h" +#include "net/JobResult.h" #include "workers/Worker.h" @@ -43,6 +44,7 @@ private: void consumeJob(); Job m_job; + JobResult m_result; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 1756dbc16..d39ebdc32 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -30,13 +30,15 @@ Worker::Worker(Handle *handle) : m_nicehash(handle->nicehash()), - m_handle(handle), - m_id(handle->threadId()) + m_id(handle->threadId()), + m_threads(handle->threads()), + m_count(0), + m_sequence(0) { - m_handle->setWorker(this); + handle->setWorker(this); - if (Cpu::threads() > 1 && m_handle->affinity() != -1L) { - Cpu::setAffinity(m_id, m_handle->affinity()); + if (Cpu::threads() > 1 && handle->affinity() != -1L) { + Cpu::setAffinity(m_id, handle->affinity()); } m_ctx = Mem::create(m_id); diff --git a/src/workers/Worker.h b/src/workers/Worker.h index f62083d0b..35b55b908 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -44,8 +44,9 @@ public: protected: bool m_nicehash; cryptonight_ctx *m_ctx; - Handle *m_handle; int m_id; + int m_threads; + uint64_t m_count; uint64_t m_sequence; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 1916be72e..1f7b76c6a 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -21,16 +21,17 @@ * along with this program. If not, see . */ -#include "Console.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" Job Workers::m_job; +pthread_mutex_t Workers::m_mutex; pthread_rwlock_t Workers::m_rwlock; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; +std::list Workers::m_queue; std::vector Workers::m_workers; uv_async_t Workers::m_async; @@ -58,7 +59,8 @@ void Workers::setJob(const Job &job) void Workers::start(int threads, int64_t affinity, bool nicehash) { - LOG_NOTICE("start %d", pthread_self()); + pthread_mutex_init(&m_mutex, nullptr); + pthread_rwlock_init(&m_rwlock, nullptr); m_sequence = 0; m_paused = 1; @@ -66,15 +68,19 @@ void Workers::start(int threads, int64_t affinity, bool nicehash) uv_async_init(uv_default_loop(), &m_async, Workers::onResult); for (int i = 0; i < threads; ++i) { - Handle *handle = new Handle(i, affinity, nicehash); + Handle *handle = new Handle(i, threads, affinity, nicehash); m_workers.push_back(handle); handle->start(Workers::onReady); } } -void Workers::submit() +void Workers::submit(const JobResult &result) { + pthread_mutex_lock(&m_mutex); + m_queue.push_back(result); + pthread_mutex_unlock(&m_mutex); + uv_async_send(&m_async); } @@ -93,4 +99,12 @@ void *Workers::onReady(void *arg) void Workers::onResult(uv_async_t *handle) { + std::list results; + + pthread_mutex_lock(&m_mutex); + while (!m_queue.empty()) { + results.push_back(std::move(m_queue.front())); + m_queue.pop_front(); + } + pthread_mutex_unlock(&m_mutex); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 7d6328cad..68bc6f15f 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -26,12 +26,13 @@ #include +#include #include #include #include - #include "net/Job.h" +#include "net/JobResult.h" class Handle; @@ -43,7 +44,7 @@ public: static Job job(); static void setJob(const Job &job); static void start(int threads, int64_t affinity, bool nicehash); - static void submit(); + static void submit(const JobResult &result); 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; } @@ -55,9 +56,11 @@ private: static void onResult(uv_async_t *handle); static Job m_job; + static pthread_mutex_t m_mutex; static pthread_rwlock_t m_rwlock; static std::atomic m_paused; static std::atomic m_sequence; + static std::list m_queue; static std::vector m_workers; static uv_async_t m_async; };