Skip to content
Snippets Groups Projects
Commit 0f96f51c authored by psychocrypt's avatar psychocrypt
Browse files

use read write locks to secure job updates

user read write locks to be sure that no job is consumend during the job update
parent 0aa7498e
No related branches found
No related tags found
No related merge requests found
......@@ -35,17 +35,17 @@ namespace xmrstak
void globalStates::consume_work( miner_work& threadWork, uint64_t& currentJobId)
{
jobLock.rdlock();
jobLock.ReadLock();
threadWork = oGlobalWork;
currentJobId = iGlobalJobNo.load(std::memory_order_relaxed);
jobLock.unlock();
jobLock.UnLock();
}
void globalStates::switch_work(miner_work& pWork, pool_data& dat)
{
jobLock.wrlock();
jobLock.WriteLock();
// this notifies all threads that the job has changed
iGlobalJobNo++;
......@@ -62,7 +62,7 @@ void globalStates::switch_work(miner_work& pWork, pool_data& dat)
dat.iSavedNonce = iGlobalNonce.exchange(dat.iSavedNonce, std::memory_order_relaxed);
oGlobalWork = pWork;
jobLock.unlock();
jobLock.UnLock();
}
} // namespace xmrstak
......@@ -4,68 +4,13 @@
#include "xmrstak/misc/environment.hpp"
#include "xmrstak/misc/console.hpp"
#include "xmrstak/backend/pool_data.hpp"
#include "xmrstak/cpputil/read_write_lock.h"
#include <atomic>
#include <condition_variable>
namespace xmrstak
{
class RWLock {
public:
RWLock() : _status(0), _waiting_readers(0), _waiting_writers(0) {}
RWLock(const RWLock&) = delete;
RWLock(RWLock&&) = delete;
RWLock& operator = (const RWLock&) = delete;
RWLock& operator = (RWLock&&) = delete;
void rdlock() {
std::unique_lock<std::mutex> lck(_mtx);
_waiting_readers += 1;
_read_cv.wait(lck, [&]() { return _waiting_writers == 0 && _status >= 0; });
_waiting_readers -= 1;
_status += 1;
}
void wrlock() {
std::unique_lock<std::mutex> lck(_mtx);
_waiting_writers += 1;
_write_cv.wait(lck, [&]() { return _status == 0; });
_waiting_writers -= 1;
_status = -1;
}
void unlock() {
std::unique_lock<std::mutex> lck(_mtx);
if (_status == -1) {
_status = 0;
} else {
_status -= 1;
}
if (_waiting_writers > 0) {
if (_status == 0) {
_write_cv.notify_one();
}
} else {
_read_cv.notify_all();
}
}
private:
// -1 : one writer
// 0 : no reader and no writer
// n > 0 : n reader
int32_t _status;
int32_t _waiting_readers;
int32_t _waiting_writers;
std::mutex _mtx;
std::condition_variable _read_cv;
std::condition_variable _write_cv;
};
struct globalStates
{
static inline globalStates& inst()
......@@ -101,7 +46,7 @@ private:
{
}
RWLock jobLock;
::cpputil::RWLock jobLock;
};
} // namespace xmrstak
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment