mirror of
https://github.com/monero-project/monero.git
synced 2024-10-01 11:49:47 -04:00
More robust battery status handling.
Added an extra path to check for linux power supply status. Added ignore battery option. If set to true, then when we can't figure out the power status, we'll assume the system is plugged in.
This commit is contained in:
parent
3f171b931f
commit
69ab14d91e
@ -41,6 +41,7 @@
|
||||
#include "common/command_line.h"
|
||||
#include "string_coding.h"
|
||||
#include "storages/portable_storage_template_helper.h"
|
||||
#include "boost/logic/tribool.hpp"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "miner"
|
||||
@ -61,6 +62,7 @@ namespace cryptonote
|
||||
const command_line::arg_descriptor<std::string> arg_start_mining = {"start-mining", "Specify wallet address to mining for", "", true};
|
||||
const command_line::arg_descriptor<uint32_t> arg_mining_threads = {"mining-threads", "Specify mining threads count", 0, true};
|
||||
const command_line::arg_descriptor<bool> arg_bg_mining_enable = {"bg-mining-enable", "enable/disable background mining", true, true};
|
||||
const command_line::arg_descriptor<bool> arg_bg_mining_ignore_battery = {"bg-mining-ignore-battery", "if true, assumes plugged in when unable to query system power status", false, true};
|
||||
const command_line::arg_descriptor<uint64_t> arg_bg_mining_min_idle_interval_seconds = {"bg-mining-min-idle-interval", "Specify min lookback interval in seconds for determining idle state", miner::BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS, true};
|
||||
const command_line::arg_descriptor<uint8_t> arg_bg_mining_idle_threshold_percentage = {"bg-mining-idle-threshold", "Specify minimum avg idle percentage over lookback interval", miner::BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE, true};
|
||||
const command_line::arg_descriptor<uint8_t> arg_bg_mining_miner_target_percentage = {"bg-mining-miner-target", "Specificy maximum percentage cpu use by miner(s)", miner::BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE, true};
|
||||
@ -181,6 +183,7 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, arg_start_mining);
|
||||
command_line::add_arg(desc, arg_mining_threads);
|
||||
command_line::add_arg(desc, arg_bg_mining_enable);
|
||||
command_line::add_arg(desc, arg_bg_mining_ignore_battery);
|
||||
command_line::add_arg(desc, arg_bg_mining_min_idle_interval_seconds);
|
||||
command_line::add_arg(desc, arg_bg_mining_idle_threshold_percentage);
|
||||
command_line::add_arg(desc, arg_bg_mining_miner_target_percentage);
|
||||
@ -230,6 +233,8 @@ namespace cryptonote
|
||||
// Let init set all parameters even if background mining is not enabled, they can start later with params set
|
||||
if(command_line::has_arg(vm, arg_bg_mining_enable))
|
||||
set_is_background_mining_enabled( command_line::get_arg(vm, arg_bg_mining_enable) );
|
||||
if(command_line::has_arg(vm, arg_bg_mining_ignore_battery))
|
||||
set_ignore_battery( command_line::get_arg(vm, arg_bg_mining_ignore_battery) );
|
||||
if(command_line::has_arg(vm, arg_bg_mining_min_idle_interval_seconds))
|
||||
set_min_idle_seconds( command_line::get_arg(vm, arg_bg_mining_min_idle_interval_seconds) );
|
||||
if(command_line::has_arg(vm, arg_bg_mining_idle_threshold_percentage))
|
||||
@ -254,7 +259,7 @@ namespace cryptonote
|
||||
return m_threads_total;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background)
|
||||
bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background, bool ignore_battery)
|
||||
{
|
||||
m_mine_address = adr;
|
||||
m_threads_total = static_cast<uint32_t>(threads_count);
|
||||
@ -278,6 +283,7 @@ namespace cryptonote
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0);
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0);
|
||||
set_is_background_mining_enabled(do_background);
|
||||
set_ignore_battery(ignore_battery);
|
||||
|
||||
for(size_t i = 0; i != threads_count; i++)
|
||||
{
|
||||
@ -469,6 +475,11 @@ namespace cryptonote
|
||||
return m_is_background_mining_enabled;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::get_ignore_battery() const
|
||||
{
|
||||
return m_ignore_battery;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* This has differing behaviour depending on if mining has been started/etc.
|
||||
* Note: add documentation
|
||||
@ -482,6 +493,11 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
void miner::set_ignore_battery(bool ignore_battery)
|
||||
{
|
||||
m_ignore_battery = ignore_battery;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
uint64_t miner::get_min_idle_seconds() const
|
||||
{
|
||||
return m_min_idle_seconds;
|
||||
@ -575,7 +591,21 @@ namespace cryptonote
|
||||
continue; // if interrupted because stop called, loop should end ..
|
||||
}
|
||||
|
||||
bool on_ac_power = !on_battery_power();
|
||||
boost::tribool battery_powered(on_battery_power());
|
||||
bool on_ac_power = false;
|
||||
if(indeterminate( battery_powered ))
|
||||
{
|
||||
// name could be better, only ignores battery requirement if we failed
|
||||
// to get the status of the system
|
||||
if( m_ignore_battery )
|
||||
{
|
||||
on_ac_power = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
on_ac_power = !battery_powered;
|
||||
}
|
||||
|
||||
if( m_is_background_mining_started )
|
||||
{
|
||||
@ -763,45 +793,54 @@ namespace cryptonote
|
||||
return (uint8_t)( ceil( (other * 1.f / total * 1.f) * 100) );
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::on_battery_power()
|
||||
boost::logic::tribool miner::on_battery_power()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
SYSTEM_POWER_STATUS power_status;
|
||||
if ( GetSystemPowerStatus( &power_status ) != 0 )
|
||||
{
|
||||
return power_status.ACLineStatus != 1;
|
||||
return boost::logic::tribool(power_status.ACLineStatus != 1);
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
// i've only tested on UBUNTU, these paths might be different on other systems
|
||||
// need to figure out a way to make this more flexible
|
||||
const std::string POWER_SUPPLY_STATUS_PATH = "/sys/class/power_supply/ACAD/online";
|
||||
|
||||
if( !epee::file_io_utils::is_file_exist(POWER_SUPPLY_STATUS_PATH) )
|
||||
std::string power_supply_path = "";
|
||||
const std::string POWER_SUPPLY_STATUS_PATHS[] =
|
||||
{
|
||||
LOG_ERROR("'" << POWER_SUPPLY_STATUS_PATH << "' file does not exist, can't determine if on AC power");
|
||||
return false;
|
||||
"/sys/class/power_supply/ACAD/online",
|
||||
"/sys/class/power_supply/AC/online"
|
||||
};
|
||||
|
||||
for(const std::string& path : POWER_SUPPLY_STATUS_PATHS)
|
||||
{
|
||||
if( epee::file_io_utils::is_file_exist(path) )
|
||||
{
|
||||
power_supply_path = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( power_supply_path.empty() )
|
||||
{
|
||||
LOG_ERROR("Couldn't find battery/power status file, can't determine if plugged in!");
|
||||
return boost::logic::tribool(boost::logic::indeterminate);;
|
||||
}
|
||||
|
||||
std::ifstream power_stream(POWER_SUPPLY_STATUS_PATH);
|
||||
std::ifstream power_stream(power_supply_path);
|
||||
if( power_stream.fail() )
|
||||
{
|
||||
LOG_ERROR("failed to open '" << POWER_SUPPLY_STATUS_PATH << "'");
|
||||
return false;
|
||||
LOG_ERROR("failed to open '" << power_supply_path << "'");
|
||||
return boost::logic::tribool(boost::logic::indeterminate);;
|
||||
}
|
||||
|
||||
return power_stream.get() != '1';
|
||||
return boost::logic::tribool( (power_stream.get() != '1') );
|
||||
|
||||
#endif
|
||||
|
||||
LOG_ERROR("couldn't query power status");
|
||||
return false; // shouldn't get here unless no support for querying battery status
|
||||
// TODO: return enum with ability to signify failure in querying for power status
|
||||
// and change bg-mining logic so that it stops. As @vtnerd states, with the current
|
||||
// setup "If someone enabled background mining on a system that fails to grab ac
|
||||
// status, it will just continually check with little hope of ever being resolved
|
||||
// automagically". This is also the case for time/idle stats functions.
|
||||
return boost::logic::tribool(boost::logic::indeterminate);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/logic/tribool_fwd.hpp>
|
||||
#include <atomic>
|
||||
#include "cryptonote_basic.h"
|
||||
#include "difficulty.h"
|
||||
@ -67,7 +68,7 @@ namespace cryptonote
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
bool set_block_template(const block& bl, const difficulty_type& diffic, uint64_t height);
|
||||
bool on_block_chain_update();
|
||||
bool start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background = false);
|
||||
bool start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs, bool do_background = false, bool ignore_battery = false);
|
||||
uint64_t get_speed() const;
|
||||
uint32_t get_threads_count() const;
|
||||
void send_stop_signal();
|
||||
@ -82,6 +83,7 @@ namespace cryptonote
|
||||
void resume();
|
||||
void do_print_hashrate(bool do_hr);
|
||||
bool get_is_background_mining_enabled() const;
|
||||
bool get_ignore_battery() const;
|
||||
uint64_t get_min_idle_seconds() const;
|
||||
bool set_min_idle_seconds(uint64_t min_idle_seconds);
|
||||
uint8_t get_idle_threshold() const;
|
||||
@ -149,8 +151,10 @@ namespace cryptonote
|
||||
// background mining stuffs ..
|
||||
|
||||
bool set_is_background_mining_enabled(bool is_background_mining_enabled);
|
||||
void set_ignore_battery(bool ignore_battery);
|
||||
bool background_worker_thread();
|
||||
std::atomic<bool> m_is_background_mining_enabled;
|
||||
bool m_ignore_battery;
|
||||
boost::mutex m_is_background_mining_enabled_mutex;
|
||||
boost::condition_variable m_is_background_mining_enabled_cond;
|
||||
std::atomic<bool> m_is_background_mining_started;
|
||||
@ -164,6 +168,6 @@ namespace cryptonote
|
||||
static bool get_system_times(uint64_t& total_time, uint64_t& idle_time);
|
||||
static bool get_process_time(uint64_t& total_time);
|
||||
static uint8_t get_percent_of_total(uint64_t some_time, uint64_t total_time);
|
||||
static bool on_battery_power();
|
||||
static boost::logic::tribool on_battery_power();
|
||||
};
|
||||
}
|
||||
|
@ -272,12 +272,18 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
|
||||
std::cout << "Mining to a testnet address, make sure this is intentional!" << std::endl;
|
||||
uint64_t threads_count = 1;
|
||||
bool do_background_mining = false;
|
||||
if(args.size() > 3)
|
||||
bool ignore_battery = false;
|
||||
if(args.size() > 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(args.size() == 3)
|
||||
if(args.size() == 4)
|
||||
{
|
||||
ignore_battery = args[3] == "true";
|
||||
}
|
||||
|
||||
if(args.size() >= 3)
|
||||
{
|
||||
do_background_mining = args[2] == "true";
|
||||
}
|
||||
@ -288,7 +294,7 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
|
||||
threads_count = (ok && 0 < threads_count) ? threads_count : 1;
|
||||
}
|
||||
|
||||
m_executor.start_mining(adr, threads_count, testnet, do_background_mining);
|
||||
m_executor.start_mining(adr, threads_count, testnet, do_background_mining, ignore_battery);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ t_command_server::t_command_server(
|
||||
m_command_lookup.set_handler(
|
||||
"start_mining"
|
||||
, std::bind(&t_command_parser_executor::start_mining, &m_parser, p::_1)
|
||||
, "Start mining for specified address, start_mining <addr> [<threads>] [do_background_mining], default 1 thread, no background mining"
|
||||
, "Start mining for specified address, start_mining <addr> [<threads>] [do_background_mining] [ignore_battery], default 1 thread, no background mining"
|
||||
);
|
||||
m_command_lookup.set_handler(
|
||||
"stop_mining"
|
||||
|
@ -929,13 +929,14 @@ bool t_rpc_command_executor::print_transaction_pool_stats() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining = false) {
|
||||
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining, bool ignore_battery) {
|
||||
cryptonote::COMMAND_RPC_START_MINING::request req;
|
||||
cryptonote::COMMAND_RPC_START_MINING::response res;
|
||||
req.miner_address = cryptonote::get_account_address_as_str(testnet, address);
|
||||
req.threads_count = num_threads;
|
||||
req.do_background_mining = do_background_mining;
|
||||
|
||||
req.ignore_battery = ignore_battery;
|
||||
|
||||
std::string fail_message = "Mining did not start";
|
||||
|
||||
if (m_is_rpc)
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
|
||||
bool print_transaction_pool_stats();
|
||||
|
||||
bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining);
|
||||
bool start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet, bool do_background_mining = false, bool ignore_battery = false);
|
||||
|
||||
bool stop_mining();
|
||||
|
||||
|
@ -635,7 +635,7 @@ namespace cryptonote
|
||||
boost::thread::attributes attrs;
|
||||
attrs.set_stack_size(THREAD_STACK_SIZE);
|
||||
|
||||
if(!m_core.get_miner().start(adr, static_cast<size_t>(req.threads_count), attrs, req.do_background_mining))
|
||||
if(!m_core.get_miner().start(adr, static_cast<size_t>(req.threads_count), attrs, req.do_background_mining, req.ignore_battery))
|
||||
{
|
||||
res.status = "Failed, mining not started";
|
||||
LOG_PRINT_L0(res.status);
|
||||
|
@ -501,11 +501,13 @@ namespace cryptonote
|
||||
std::string miner_address;
|
||||
uint64_t threads_count;
|
||||
bool do_background_mining;
|
||||
bool ignore_battery;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(miner_address)
|
||||
KV_SERIALIZE(threads_count)
|
||||
KV_SERIALIZE(do_background_mining)
|
||||
KV_SERIALIZE(ignore_battery)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user