Skip to content
This repository has been archived by the owner on Apr 24, 2022. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/master' into release/0.12
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Sep 13, 2017
2 parents a660d71 + 65b4778 commit 466eaed
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 29 deletions.
5 changes: 0 additions & 5 deletions ethminer/MinerAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,6 @@ class MinerCLI
this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration));

auto mp = f.miningProgress();
f.resetMiningProgress();
if (!i)
continue;
auto rate = mp.rate();
Expand Down Expand Up @@ -715,7 +714,6 @@ class MinerCLI
for (unsigned i = 0; !completed; ++i)
{
auto mp = f.miningProgress();
f.resetMiningProgress();

cnote << "Mining on difficulty " << difficulty << " " << mp;
this_thread::sleep_for(chrono::milliseconds(1000));
Expand Down Expand Up @@ -801,7 +799,6 @@ class MinerCLI
for (unsigned i = 0; !completed; ++i)
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (current)
{
minelog << mp << f.getSolutionStats() << f.farmLaunchedFormatted();
Expand Down Expand Up @@ -951,7 +948,6 @@ class MinerCLI
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (client.isConnected())
{
if (client.current())
Expand Down Expand Up @@ -1001,7 +997,6 @@ class MinerCLI
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (client.isConnected())
{
if (client.current())
Expand Down
119 changes: 95 additions & 24 deletions libethcore/Farm.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#pragma once

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <thread>
#include <list>
#include <atomic>
Expand All @@ -29,6 +31,8 @@
#include <libethcore/Miner.h>
#include <libethcore/BlockHeader.h>

using namespace boost::asio;

namespace dev
{

Expand Down Expand Up @@ -60,13 +64,16 @@ class Farm: public FarmFace
*/
void setWork(WorkPackage const& _wp)
{
//Collect hashrate before miner reset their work
collectHashRate();

// Set work to each miner
Guard l(x_minerWork);
if (_wp.header == m_work.header && _wp.startNonce == m_work.startNonce)
return;
m_work = _wp;
for (auto const& m: m_miners)
m->setWork(m_work);
resetTimer();
}

void setSealers(std::map<std::string, SealerDescriptor> const& _sealers) { m_sealers = _sealers; }
Expand Down Expand Up @@ -110,9 +117,21 @@ class Farm: public FarmFace
m_isMining = true;
m_lastSealer = _sealer;
b_lastMixed = mixed;
resetTimer();

if (!p_hashrateTimer) {
p_hashrateTimer = new boost::asio::deadline_timer(m_io_service, boost::posix_time::milliseconds(1000));
p_hashrateTimer->async_wait(boost::bind(&Farm::processHashRate, this, boost::asio::placeholders::error));
if (m_serviceThread.joinable()) {
m_io_service.reset();
}
else {
m_serviceThread = std::thread{ boost::bind(&boost::asio::io_service::run, &m_io_service) };
}
}

return true;
}

/**
* @brief Stop all mining activities.
*/
Expand All @@ -121,6 +140,59 @@ class Farm: public FarmFace
Guard l(x_minerWork);
m_miners.clear();
m_isMining = false;

if (p_hashrateTimer) {
p_hashrateTimer->cancel();
}

m_io_service.stop();
m_serviceThread.join();
p_hashrateTimer = nullptr;
}

void collectHashRate()
{
WorkingProgress p;
Guard l2(x_minerWork);
p.ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - m_lastStart).count();
//Collect
for (auto const& i : m_miners)
{
uint64_t minerHashCount = i->hashCount();
p.hashes += minerHashCount;
p.minersHashes.push_back(minerHashCount);
}

//Reset
for (auto const& i : m_miners)
{
i->resetHashCount();
}
m_lastStart = std::chrono::steady_clock::now();

if (p.hashes > 0) {
m_lastProgresses.push_back(p);
}

// We smooth the hashrate over the last x seconds
int allMs = 0;
for (auto const& cp : m_lastProgresses) {
allMs += cp.ms;
}
if (allMs > m_hashrateSmoothInterval) {
m_lastProgresses.erase(m_lastProgresses.begin());
}
}

void processHashRate(const boost::system::error_code& ec) {

if (!ec) {
collectHashRate();
}

// Restart timer
p_hashrateTimer->expires_at(p_hashrateTimer->expires_at() + boost::posix_time::milliseconds(1000));
p_hashrateTimer->async_wait(boost::bind(&Farm::processHashRate, this, boost::asio::placeholders::error));
}

/**
Expand Down Expand Up @@ -148,32 +220,30 @@ class Farm: public FarmFace
WorkingProgress const& miningProgress() const
{
WorkingProgress p;
p.ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - m_lastStart).count();
p.ms = 0;
p.hashes = 0;
{
Guard l2(x_minerWork);
for (auto const& i: m_miners)
for (auto const& i : m_miners) {
(void) i; // unused
p.minersHashes.push_back(0);
}
}

for (auto const& cp : m_lastProgresses) {
p.ms += cp.ms;
p.hashes += cp.hashes;
for (unsigned int i = 0; i < cp.minersHashes.size(); i++)
{
uint64_t minerHashCount = i->hashCount();
p.hashes += minerHashCount;
p.minersHashes.push_back(minerHashCount);
p.minersHashes.at(i) += cp.minersHashes.at(i);
}
}

Guard l(x_progress);
m_progress = p;
return m_progress;
}

/**
* @brief Reset the mining progess counter.
*/
void resetMiningProgress()
{
DEV_GUARDED(x_minerWork)
for (auto const& i: m_miners)
i->resetHashCount();
resetTimer();
}

SolutionStats getSolutionStats() {
return m_solutionStats;
}
Expand Down Expand Up @@ -248,11 +318,6 @@ class Farm: public FarmFace
return m_onSolutionFound(_s);
}

void resetTimer()
{
m_lastStart = std::chrono::steady_clock::now();
}

mutable Mutex x_minerWork;
std::vector<std::shared_ptr<Miner>> m_miners;
WorkPackage m_work;
Expand All @@ -261,7 +326,6 @@ class Farm: public FarmFace

mutable Mutex x_progress;
mutable WorkingProgress m_progress;
std::chrono::steady_clock::time_point m_lastStart;

SolutionFound m_onSolutionFound;
MinerRestart m_onMinerRestart;
Expand All @@ -270,6 +334,13 @@ class Farm: public FarmFace
std::string m_lastSealer;
bool b_lastMixed = false;

std::chrono::steady_clock::time_point m_lastStart;
int m_hashrateSmoothInterval = 10000;
std::thread m_serviceThread; ///< The IO service thread.
boost::asio::io_service m_io_service;
boost::asio::deadline_timer * p_hashrateTimer = nullptr;
std::vector<WorkingProgress> m_lastProgresses;

mutable SolutionStats m_solutionStats;
std::chrono::steady_clock::time_point m_farm_launched = std::chrono::steady_clock::now();
};
Expand Down

0 comments on commit 466eaed

Please sign in to comment.