@ -98,8 +98,7 @@ int opt_queue = 1;
@@ -98,8 +98,7 @@ int opt_queue = 1;
int opt_scantime = 7 ;
int opt_expiry = 28 ;
char * opt_algorithm ;
algorithm_t * algorithm ;
algorithm_t * default_algorithm ;
static const bool opt_time = true ;
unsigned long long global_hashrate ;
@ -199,6 +198,11 @@ pthread_rwlock_t devices_lock;
@@ -199,6 +198,11 @@ pthread_rwlock_t devices_lock;
static pthread_mutex_t lp_lock ;
static pthread_cond_t lp_cond ;
static pthread_mutex_t algo_switch_lock ;
static int algo_switch_n = 0 ;
static pthread_mutex_t algo_switch_wait_lock ;
static pthread_cond_t algo_switch_wait_cond ;
pthread_mutex_t restart_lock ;
pthread_cond_t restart_cond ;
@ -538,6 +542,9 @@ struct pool *add_pool(void)
@@ -538,6 +542,9 @@ struct pool *add_pool(void)
buf [ 0 ] = ' \0 ' ;
pool - > name = strdup ( buf ) ;
/* Algorithm */
pool - > algorithm = * default_algorithm ;
pools = ( struct pool * * ) realloc ( pools , sizeof ( struct pool * ) * ( total_pools + 2 ) ) ;
pools [ total_pools + + ] = pool ;
mutex_init ( & pool - > pool_lock ) ;
@ -773,6 +780,35 @@ static char *set_url(char *arg)
@@ -773,6 +780,35 @@ static char *set_url(char *arg)
return NULL ;
}
static char * set_pool_algorithm ( char * arg )
{
struct pool * pool ;
while ( ( json_array_index + 1 ) > total_pools )
add_pool ( ) ;
pool = pools [ json_array_index ] ;
applog ( LOG_DEBUG , " Setting pool %i algorithm to %s " , pool - > pool_no , arg ) ;
set_algorithm ( & pool - > algorithm , arg ) ;
return NULL ;
}
static char * set_pool_nfactor ( char * arg )
{
struct pool * pool ;
while ( ( json_array_index + 1 ) > total_pools )
add_pool ( ) ;
pool = pools [ json_array_index ] ;
applog ( LOG_DEBUG , " Setting pool %i N-factor to %s " , pool - > pool_no , arg ) ;
set_algorithm_nfactor ( & pool - > algorithm , ( const uint8_t ) atoi ( arg ) ) ;
return NULL ;
}
static char * set_poolname ( char * arg )
{
struct pool * pool = get_current_pool ( ) ;
@ -1034,17 +1070,17 @@ static void load_temp_cutoffs()
@@ -1034,17 +1070,17 @@ static void load_temp_cutoffs()
static char * set_algo ( const char * arg )
{
set_algorithm ( algorithm , arg ) ;
applog ( LOG_INFO , " Set algorithm to %s " , algorithm - > name ) ;
set_algorithm ( default_ algorithm, arg ) ;
applog ( LOG_INFO , " Set default algorithm to %s " , default_ algorithm- > name ) ;
return NULL ;
}
static char * set_nfactor ( const char * arg )
{
set_algorithm_nfactor ( algorithm , ( uint8_t ) atoi ( arg ) ) ;
set_algorithm_nfactor ( default_ algorithm, ( const uint8_t ) atoi ( arg ) ) ;
applog ( LOG_INFO , " Set algorithm N-factor to %d (N to %d) " ,
algorithm - > nfactor , algorithm - > n ) ;
default_ algorithm- > nfactor , default_ algorithm- > n ) ;
return NULL ;
}
@ -1399,6 +1435,12 @@ static struct opt_table opt_config_table[] = {
@@ -1399,6 +1435,12 @@ static struct opt_table opt_config_table[] = {
OPT_WITH_ARG ( " --url|-o " ,
set_url , NULL , NULL ,
" URL for bitcoin JSON-RPC server " ) ,
OPT_WITH_ARG ( " --pool-algorithm " ,
set_pool_algorithm , NULL , NULL ,
" Set algorithm for pool " ) ,
OPT_WITH_ARG ( " --pool-nfactor " ,
set_pool_nfactor , NULL , NULL ,
" Set N-factor for pool " ) ,
OPT_WITH_ARG ( " --user|-u " ,
set_user , NULL , NULL ,
" Username for bitcoin JSON-RPC server " ) ,
@ -3783,7 +3825,6 @@ void switch_pools(struct pool *selected)
@@ -3783,7 +3825,6 @@ void switch_pools(struct pool *selected)
mutex_lock ( & lp_lock ) ;
pthread_cond_broadcast ( & lp_cond ) ;
mutex_unlock ( & lp_lock ) ;
}
void discard_work ( struct work * work )
@ -4415,8 +4456,8 @@ void write_config(FILE *fcfg)
@@ -4415,8 +4456,8 @@ void write_config(FILE *fcfg)
}
if ( opt_removedisabled )
fprintf ( fcfg , " , \n \" remove-disabled \" : true " ) ;
if ( strcmp ( algorithm - > name , " scrypt " ) ! = 0 )
fprintf ( fcfg , " , \n \" algorithm \" : \" %s \" " , json_escape ( algorithm - > name ) ) ;
if ( strcmp ( default_ algorithm- > name , " scrypt " ) ! = 0 )
fprintf ( fcfg , " , \n \" algorithm \" : \" %s \" " , json_escape ( default_ algorithm- > name ) ) ;
if ( opt_api_allow )
fprintf ( fcfg , " , \n \" api-allow \" : \" %s \" " , json_escape ( opt_api_allow ) ) ;
if ( strcmp ( opt_api_mcast_addr , API_MCAST_ADDR ) ! = 0 )
@ -5988,6 +6029,53 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
@@ -5988,6 +6029,53 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
cgtime ( & work - > tv_staged ) ;
}
static void get_work_prepare_thread ( struct thr_info * mythr , struct work * work )
{
int i ;
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE , NULL ) ;
mutex_lock ( & algo_switch_lock ) ;
if ( cmp_algorithm ( & work - > pool - > algorithm , & mythr - > cgpu - > algorithm ) & & ( algo_switch_n = = 0 ) ) {
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
return ;
}
algo_switch_n + + ;
// If all threads are waiting now
if ( algo_switch_n > = mining_threads ) {
rd_lock ( & mining_thr_lock ) ;
// Shutdown all threads first (necessary)
for ( i = 0 ; i < mining_threads ; i + + ) {
struct thr_info * thr = mining_thr [ i ] ;
thr - > cgpu - > drv - > thread_shutdown ( thr ) ;
}
// Change algorithm for each thread (thread_prepare calls initCl)
for ( i = 0 ; i < mining_threads ; i + + ) {
struct thr_info * thr = mining_thr [ i ] ;
thr - > cgpu - > algorithm = work - > pool - > algorithm ;
thr - > cgpu - > drv - > thread_prepare ( thr ) ;
}
rd_unlock ( & mining_thr_lock ) ;
algo_switch_n = 0 ;
mutex_unlock ( & algo_switch_lock ) ;
// Signal other threads to start working now
mutex_lock ( & algo_switch_wait_lock ) ;
pthread_cond_broadcast ( & algo_switch_wait_cond ) ;
mutex_unlock ( & algo_switch_wait_lock ) ;
// Not all threads are waiting, join the waiting list
} else {
mutex_unlock ( & algo_switch_lock ) ;
// Wait for signal to start working again
mutex_lock ( & algo_switch_wait_lock ) ;
pthread_cond_wait ( & algo_switch_wait_cond , & algo_switch_wait_lock ) ;
mutex_unlock ( & algo_switch_wait_lock ) ;
}
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
}
struct work * get_work ( struct thr_info * thr , const int thr_id )
{
struct work * work = NULL ;
@ -6004,6 +6092,9 @@ struct work *get_work(struct thr_info *thr, const int thr_id)
@@ -6004,6 +6092,9 @@ struct work *get_work(struct thr_info *thr, const int thr_id)
wake_gws ( ) ;
}
}
get_work_prepare_thread ( thr , work ) ;
diff_t = time ( NULL ) - diff_t ;
/* Since this is a blocking function, we need to add grace time to
* the device ' s last valid work to not make outages appear to be
@ -6084,7 +6175,7 @@ static void rebuild_nonce(struct work *work, uint32_t nonce)
@@ -6084,7 +6175,7 @@ static void rebuild_nonce(struct work *work, uint32_t nonce)
* work_nonce = htole32 ( nonce ) ;
scrypt_regenhash ( work ) ;
scrypt_regenhash ( work , work - > pool - > algorithm . n ) ;
}
/* For testing a nonce against diff 1 */
@ -6212,8 +6303,10 @@ static void mt_disable(struct thr_info *mythr, const int thr_id,
@@ -6212,8 +6303,10 @@ static void mt_disable(struct thr_info *mythr, const int thr_id,
applog ( LOG_WARNING , " Thread %d being disabled " , thr_id ) ;
mythr - > rolling = mythr - > cgpu - > rolling = 0 ;
applog ( LOG_DEBUG , " Waiting on sem in miner thread " ) ;
mythr - > paused = true ;
cgsem_wait ( & mythr - > sem ) ;
applog ( LOG_WARNING , " Thread %d being re-enabled " , thr_id ) ;
mythr - > paused = false ;
drv - > thread_enable ( mythr ) ;
}
@ -6230,7 +6323,7 @@ static void hash_sole_work(struct thr_info *mythr)
@@ -6230,7 +6323,7 @@ static void hash_sole_work(struct thr_info *mythr)
struct sgminer_stats * pool_stats ;
/* Try to cycle approximately 5 times before each log update */
const long cycle = opt_log_interval / 5 ? 5 : 1 ;
const bool primary = ( ! mythr - > device_thread ) | | mythr - > primary_thread ;
const bool primary = mythr - > device_thread = = 0 ;
struct timeval diff , sdiff , wdiff = { 0 , 0 } ;
uint32_t max_nonce = drv - > can_limit_work ( mythr ) ;
int64_t hashes_done = 0 ;
@ -7835,6 +7928,7 @@ int main(int argc, char *argv[])
@@ -7835,6 +7928,7 @@ int main(int argc, char *argv[])
rwlock_init ( & netacc_lock ) ;
rwlock_init ( & mining_thr_lock ) ;
rwlock_init ( & devices_lock ) ;
mutex_init ( & algo_switch_lock ) ;
mutex_init ( & lp_lock ) ;
if ( unlikely ( pthread_cond_init ( & lp_cond , NULL ) ) )
@ -7844,6 +7938,10 @@ int main(int argc, char *argv[])
@@ -7844,6 +7938,10 @@ int main(int argc, char *argv[])
if ( unlikely ( pthread_cond_init ( & restart_cond , NULL ) ) )
quit ( 1 , " Failed to pthread_cond_init restart_cond " ) ;
mutex_init ( & algo_switch_wait_lock ) ;
if ( unlikely ( pthread_cond_init ( & algo_switch_wait_cond , NULL ) ) )
quit ( 1 , " Failed to pthread_cond_init algo_switch_wait_cond " ) ;
if ( unlikely ( pthread_cond_init ( & gws_cond , NULL ) ) )
quit ( 1 , " Failed to pthread_cond_init gws_cond " ) ;
@ -7887,8 +7985,8 @@ int main(int argc, char *argv[])
@@ -7887,8 +7985,8 @@ int main(int argc, char *argv[])
# endif
/* Default algorithm specified in algorithm.c ATM */
algorithm = ( algorithm_t * ) alloca ( sizeof ( algorithm_t ) ) ;
set_algorithm ( algorithm , " scrypt " ) ;
default_ algorithm = ( algorithm_t * ) alloca ( sizeof ( algorithm_t ) ) ;
set_algorithm ( default_ algorithm, " scrypt " ) ;
devcursor = 8 ;
logstart = devcursor + 1 ;