summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xmrstak/backend/amd/minethd.cpp2
-rw-r--r--xmrstak/backend/cpu/minethd.cpp75
-rw-r--r--xmrstak/backend/cpu/minethd.hpp8
-rw-r--r--xmrstak/backend/nvidia/minethd.cpp2
-rw-r--r--xmrstak/misc/environment.hpp41
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
OpenPOWER on IntegriCloud