diff options
-rw-r--r-- | xmrstak/backend/amd/minethd.cpp | 2 | ||||
-rw-r--r-- | xmrstak/backend/cpu/minethd.cpp | 75 | ||||
-rw-r--r-- | xmrstak/backend/cpu/minethd.hpp | 8 | ||||
-rw-r--r-- | xmrstak/backend/nvidia/minethd.cpp | 2 | ||||
-rw-r--r-- | xmrstak/misc/environment.hpp | 41 |
5 files changed, 50 insertions, 78 deletions
diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index 84f0055..5ca10d3 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -65,7 +65,7 @@ __declspec(dllexport) #endif std::vector<iBackend*>* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, environment& env) { - environment::inst() = env; + environment::inst(&env); return amd::minethd::thread_starter(threadOffset, pWork); } } // extern "C" diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index 8a65a3b..eb395a5 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -50,22 +50,8 @@ #include <thread> #include <bitset> - #ifdef _WIN32 #include <windows.h> - -namespace xmrstak -{ -namespace cpu -{ -void minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) -{ - SetThreadAffinityMask(h, 1ULL << cpu_id); -} - -} // namespace cpu -} // namespace xmrstak - #else #include <pthread.h> @@ -75,44 +61,37 @@ void minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id #define SYSCTL_CORE_COUNT "machdep.cpu.core_count" #elif defined(__FreeBSD__) #include <pthread_np.h> -#endif +#endif //__APPLE__ + +#endif //_WIN32 namespace xmrstak { namespace cpu { -void minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) +bool minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) { -#if defined(__APPLE__) +#if defined(_WIN32) + return SetThreadAffinityMask(h, 1ULL << cpu_id) != 0; +#elif defined(__APPLE__) thread_port_t mach_thread; thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) }; mach_thread = pthread_mach_thread_np(h); - thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1); + return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS; #elif defined(__FreeBSD__) cpuset_t mn; CPU_ZERO(&mn); CPU_SET(cpu_id, &mn); - pthread_setaffinity_np(h, sizeof(cpuset_t), &mn); + return pthread_setaffinity_np(h, sizeof(cpuset_t), &mn) == 0; #else cpu_set_t mn; CPU_ZERO(&mn); CPU_SET(cpu_id, &mn); - pthread_setaffinity_np(h, sizeof(cpu_set_t), &mn); + return pthread_setaffinity_np(h, sizeof(cpu_set_t), &mn) == 0; #endif } -} // namespace cpu -} // namespace xmrstak - -#endif // _WIN32 - - -namespace xmrstak -{ -namespace cpu -{ - minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity) { oWork = pWork; @@ -122,11 +101,17 @@ minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefet bNoPrefetch = no_prefetch; this->affinity = affinity; - std::lock_guard<std::mutex> lock(work_thd_mtx); + std::future<void> order_guard = order_fix.get_future(); + if(double_work) oWorkThd = std::thread(&minethd::double_work_main, this); else oWorkThd = std::thread(&minethd::work_main, this); + + order_guard.wait(); + + if(!thd_setaffinity(oWorkThd.native_handle(), affinity)) + printer::inst()->print_msg(L1, "WARNING setting affinity failed."); } cryptonight_ctx* minethd::minethd_alloc_ctx() @@ -279,7 +264,13 @@ std::vector<iBackend*> minethd::thread_starter(uint32_t threadOffset, miner_work pvThreads.push_back(thd); if(cfg.iCpuAff >= 0) + { +#if defined(__APPLE__) + printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); +#endif + printer::inst()->print_msg(L1, "Starting %s thread, affinity: %d.", cfg.bDoubleMode ? "double" : "single", (int)cfg.iCpuAff); + } else printer::inst()->print_msg(L1, "Starting %s thread, no affinity.", cfg.bDoubleMode ? "double" : "single"); } @@ -315,24 +306,12 @@ minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch) return func_table[digit.to_ulong()]; } -void minethd::pin_thd_affinity() -{ - //Lock is needed because we need to use oWorkThd - std::lock_guard<std::mutex> lock(work_thd_mtx); - - // pin memory to NUMA node - bindMemoryToNUMANode(affinity); - -#if defined(__APPLE__) - printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); -#endif - thd_setaffinity(oWorkThd.native_handle(), affinity); -} - void minethd::work_main() { if(affinity >= 0) //-1 means no affinity - pin_thd_affinity(); + bindMemoryToNUMANode(affinity); + + order_fix.set_value(); cn_hash_fun hash_fun; cryptonight_ctx* ctx; @@ -429,7 +408,7 @@ uint32_t* minethd::prep_double_work(uint8_t bDoubleWorkBlob[sizeof(miner_work::b void minethd::double_work_main() { if(affinity >= 0) //-1 means no affinity - pin_thd_affinity(); + bindMemoryToNUMANode(affinity); cn_hash_fun_dbl hash_fun; cryptonight_ctx* ctx0; diff --git a/xmrstak/backend/cpu/minethd.hpp b/xmrstak/backend/cpu/minethd.hpp index 58d378e..5ffd44e 100644 --- a/xmrstak/backend/cpu/minethd.hpp +++ b/xmrstak/backend/cpu/minethd.hpp @@ -8,7 +8,7 @@ #include <thread> #include <vector> #include <atomic> -#include <mutex> +#include <future> namespace xmrstak { @@ -24,7 +24,7 @@ public: typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); static cn_hash_fun func_selector(bool bHaveAes, bool bNoPrefetch); - static void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id); + static bool thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id); static cryptonight_ctx* minethd_alloc_ctx(); @@ -45,9 +45,7 @@ private: static miner_work oGlobalWork; miner_work oWork; - void pin_thd_affinity(); - // Held by the creating context to prevent a race cond with oWorkThd = std::thread(...) - std::mutex work_thd_mtx; + std::promise<void> order_fix; std::thread oWorkThd; int64_t affinity; diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index a4aa519..fcd01cd 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -112,7 +112,7 @@ __declspec(dllexport) #endif std::vector<iBackend*>* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, environment& env) { - environment::inst() = env; + environment::inst(&env); return nvidia::minethd::thread_starter(threadOffset, pWork); } } // extern "C" diff --git a/xmrstak/misc/environment.hpp b/xmrstak/misc/environment.hpp index 85375b0..99c2db8 100644 --- a/xmrstak/misc/environment.hpp +++ b/xmrstak/misc/environment.hpp @@ -12,35 +12,30 @@ struct params; struct environment { - - static environment& inst() - { - static environment env; - return env; - } - - environment& operator=(const environment& env) + static inline environment& inst(environment* init = nullptr) { - this->pPrinter = env.pPrinter; - this->pglobalStates = env.pglobalStates; - this->pJconfConfig = env.pJconfConfig; - this->pExecutor = env.pExecutor; - this->pParams = env.pParams; - return *this; - } + static environment* env = nullptr; + if(env == nullptr) + { + if(init == nullptr) + env = new environment; + else + env = init; + } - environment() : pPrinter(nullptr), pglobalStates(nullptr) - { + return *env; } + environment() + { + } - printer* pPrinter; - globalStates* pglobalStates; - jconf* pJconfConfig; - executor* pExecutor; - params* pParams; - + printer* pPrinter = nullptr; + globalStates* pglobalStates = nullptr; + jconf* pJconfConfig = nullptr; + executor* pExecutor = nullptr; + params* pParams = nullptr; }; } // namepsace xmrstak |