From ffd86e69f7b579d4ef660eca839b99306122a57b Mon Sep 17 00:00:00 2001 From: Uray Meiviar Date: Fri, 26 Sep 2014 03:13:21 +0700 Subject: [PATCH] race condition bug-fix --- Makefile | 2 +- src/PlotReader.cpp | 82 ++++++++++++++++++++++++++++++---------------- src/PlotReader.h | 9 ++--- src/main.cpp | 1 + 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 5f6139f..b412f0b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS := -O3 -march=native -std=c++11 -Wall +CFLAGS := -O3 -march=native -std=c++11 -Wall -D_REENTRANT CC := g++ $(CFLAGS) LD := g++ -pthread diff --git a/src/PlotReader.cpp b/src/PlotReader.cpp index 79f3382..4ae017a 100644 --- a/src/PlotReader.cpp +++ b/src/PlotReader.cpp @@ -139,13 +139,13 @@ void Burst::PlotReader::readerThread() */ this->runVerify = true; - std::unique_lock verifyLock(this->readLock); - verifyLock.unlock(); std::thread verifierThreadObj(&PlotReader::verifierThread,this); size_t chunkNum = 0; size_t totalChunk = (size_t)std::ceil((double)this->nonceCount / (double)this->staggerSize); this->nonceOffset = 0; + this->nonceRead = 0; + this->verifySignaled = false; this->readBuffer = &this->buffer[0]; this->writeBuffer = &this->buffer[1]; @@ -170,23 +170,40 @@ void Burst::PlotReader::readerThread() this->writeBuffer->resize(scoopBufferSize / MinerConfig::scoopSize); } } + if(scoopBufferSize > MinerConfig::scoopSize) { - //MinerLogger::write("chunk "+std::to_string(chunkNum)+" offset "+std::to_string(startByte + staggerOffset)+" read "+std::to_string(scoopBufferSize)+" nonce offset "+std::to_string(this->nonceOffset)); inputStream.seekg(startByte + staggerOffset); char* scoopData = (char*)&(*this->writeBuffer)[0]; inputStream.read(scoopData, scoopBufferSize); - verifyLock.lock(); + std::unique_lock verifyLock(this->verifyMutex); + + //MinerLogger::write("chunk "+std::to_string(chunkNum)+" offset "+std::to_string(startByte + staggerOffset)+" read "+std::to_string(scoopBufferSize)+" nonce offset "+std::to_string(this->nonceOffset)+" nonceRead "+std::to_string(this->nonceRead)); + std::vector* temp = this->readBuffer; this->readBuffer = this->writeBuffer; this->writeBuffer = temp; this->nonceOffset = chunkNum*this->staggerSize + scoopDoneRead*(scoopBufferSize / MinerConfig::scoopSize); - //MinerLogger::write("read buffer size "+std::to_string(this->readBuffer->size())+" nonce offset "+std::to_string(this->nonceOffset)); + this->verifySignaled = true; + this->verifySignal.notify_one(); verifyLock.unlock(); - this->readSignal.notify_all(); + + while(this->verifySignaled) + { + //MinerLogger::write("stupid"); + std::this_thread::sleep_for(std::chrono::microseconds(1)); + this->verifySignal.notify_one(); + }; + } + /* + else + { + MinerLogger::write("scoop buffer ="+std::to_string(scoopBufferSize)); + } + */ scoopDoneRead++; } @@ -194,45 +211,52 @@ void Burst::PlotReader::readerThread() } inputStream.close(); + - verifyLock.lock(); + std::unique_lock verifyLock(this->verifyMutex); this->runVerify = false; - this->readSignal.notify_all(); + this->readBuffer->clear(); + this->writeBuffer->clear(); + this->verifySignaled = true; + this->verifySignal.notify_all(); verifyLock.unlock(); - this->done = true; verifierThreadObj.join(); + + this->done = true; MinerLogger::write("plot read done. "+Burst::getFileNameFromPath(this->inputPath)+" = "+std::to_string(this->nonceRead)+" nonces "); } } void Burst::PlotReader::verifierThread() { - std::unique_lock verifyLock(this->readLock); - this->nonceRead = 0; + std::unique_lock verifyLock(this->verifyMutex); while(this->runVerify) { - readSignal.wait(verifyLock); + do { + this->verifySignal.wait(verifyLock); + } + while(!this->verifySignaled); + this->verifySignaled = false; + for(size_t i=0 ; ireadBuffer->size() ; i++) { - if(this->nonceOffset + i < this->nonceCount) - { - HashData target; - char* test = (char*)&((*this->readBuffer)[i]); - this->hash.update(&this->gensig[0], MinerConfig::hashSize); - this->hash.update(test,MinerConfig::scoopSize); - this->hash.close(&target[0]); - - uint64_t targetResult = 0; - memcpy(&targetResult,&target[0],sizeof(uint64_t)); - uint64_t deadline = targetResult / this->miner->getBaseTarget(); - - uint64_t nonceNum = this->nonceStart + this->nonceOffset + i; - this->miner->submitNonce(nonceNum, this->accountId, deadline); - this->nonceRead++; - } + HashData target; + char* test = (char*)&((*this->readBuffer)[i]); + this->hash.update(&this->gensig[0], MinerConfig::hashSize); + this->hash.update(test,MinerConfig::scoopSize); + this->hash.close(&target[0]); + + uint64_t targetResult = 0; + memcpy(&targetResult,&target[0],sizeof(uint64_t)); + uint64_t deadline = targetResult / this->miner->getBaseTarget(); + + uint64_t nonceNum = this->nonceStart + this->nonceOffset + i; + this->miner->submitNonce(nonceNum, this->accountId, deadline); + this->nonceRead++; } - //MinerLogger::write("verifier processed "+std::to_string(this->nonceRead)); + //MinerLogger::write("verifier processed "+std::to_string(this->nonceRead)+" readsize "+std::to_string(this->readBuffer->size())); } + //MinerLogger::write("plot read done. "+std::to_string(this->nonceRead)+" nonces "); } diff --git a/src/PlotReader.h b/src/PlotReader.h index d00310e..76a62c8 100644 --- a/src/PlotReader.h +++ b/src/PlotReader.h @@ -35,8 +35,8 @@ namespace Burst uint64_t accountId; GensigData gensig; - std::atomic done; - std::atomic runVerify; + bool done; + bool runVerify; std::string inputPath; Miner* miner; @@ -45,8 +45,9 @@ namespace Burst std::vector buffer[2]; Shabal256 hash; - std::mutex readLock; - std::condition_variable readSignal; + bool verifySignaled; + std::mutex verifyMutex; + std::condition_variable verifySignal; std::vector* readBuffer; std::vector* writeBuffer; }; diff --git a/src/main.cpp b/src/main.cpp index db69f9a..d8a8a6d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ int main(int argc, const char* argv[]) { Burst::MinerLogger::write("Submission Max Delay : "+ std::to_string(config.submissionMaxDelay)); Burst::MinerLogger::write("Submission Max Retry : "+ std::to_string(config.submissionMaxRetry)); + Burst::MinerLogger::write("Buffer Size : "+ std::to_string(config.maxBufferSizeMB)+"MB"); Burst::MinerLogger::write("Pool Host : "+config.poolHost+" port "+ std::to_string(config.poolPort)); Burst::Miner miner(config);