@ -281,7 +281,8 @@ static pthread_cond_t lp_cond;
@@ -281,7 +281,8 @@ 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 unsigned long pool_switch_options = 0 ;
static pthread_mutex_t algo_switch_wait_lock = PTHREAD_MUTEX_INITIALIZER ;
static pthread_cond_t algo_switch_wait_cond ;
pthread_mutex_t restart_lock ;
@ -6286,9 +6287,6 @@ static unsigned long compare_pool_settings(struct pool *pool1, struct pool *pool
@@ -6286,9 +6287,6 @@ static unsigned long compare_pool_settings(struct pool *pool1, struct pool *pool
static void get_work_prepare_thread ( struct thr_info * mythr , struct work * work )
{
int i ;
int active_threads ; //number of actual active threads
unsigned long options ;
const char * opt ;
//if switcher is disabled
if ( opt_switchmode = = SWITCH_OFF )
@ -6297,20 +6295,42 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
@@ -6297,20 +6295,42 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE , NULL ) ;
mutex_lock ( & algo_switch_lock ) ;
//switcher mode - switch on algorithm change
if ( opt_switchmode = = SWITCH_ALGO )
if ( algo_switch_n = = 0 )
{
if ( cmp_algorithm ( & work - > pool - > algorithm , & mythr - > cgpu - > algorithm ) & & ( algo_switch_n = = 0 ) )
//get pool options to apply on switch
pool_switch_options = 0 ;
//switcher mode - switch on algorithm change
if ( opt_switchmode = = SWITCH_ALGO )
{
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
return ;
//if algorithms are different
if ( ! cmp_algorithm ( & work - > pool - > algorithm , & mythr - > cgpu - > algorithm ) )
pool_switch_options = compare_pool_settings ( pools [ mythr - > pool_no ] , work - > pool ) ;
}
}
//switcher mode - switch on pool change
else if ( opt_switchmode = = SWITCH_POOL )
{
if ( ( work - > pool - > pool_no = = mythr - > pool_no ) & & ( algo_switch_n = = 0 ) )
//switcher mode - switch on pool change
else if ( opt_switchmode = = SWITCH_POOL )
{
if ( work - > pool - > pool_no ! = mythr - > pool_no )
{
if ( ( pool_switch_options = compare_pool_settings ( pools [ mythr - > pool_no ] , work - > pool ) ) = = 0 )
{
applog ( LOG_NOTICE , " No settings change from pool %s... " , isnull ( get_pool_name ( work - > pool ) , " " ) ) ;
rd_lock ( & mining_thr_lock ) ;
//apply new pool_no to all mining threads
for ( i = 0 ; i < mining_threads ; i + + )
{
struct thr_info * thr = mining_thr [ i ] ;
thr - > pool_no = work - > pool - > pool_no ;
}
rd_unlock ( & mining_thr_lock ) ;
}
}
}
if ( pool_switch_options = = 0 )
{
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
@ -6321,9 +6341,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
@@ -6321,9 +6341,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
algo_switch_n + + ;
//get the number of active threads to know when to switch... if we only check total threads, we may wait for ever on a disabled GPU
active_threads = 0 ;
rd_lock ( & mining_thr_lock ) ;
int active_threads = 0 ;
for ( i = 0 ; i < mining_threads ; i + + )
{
struct cgpu_info * cgpu = mining_thr [ i ] - > cgpu ;
@ -6337,249 +6357,234 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
@@ -6337,249 +6357,234 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
// If all threads are waiting now
if ( algo_switch_n > = active_threads )
{
//compare pools to figure out what we need to apply, if options is 0, don't change anything...
if ( ( options = compare_pool_settings ( pools [ mythr - > pool_no ] , work - > pool ) ) )
{
rd_lock ( & mining_thr_lock ) ;
const char * opt ;
applog ( LOG_NOTICE , " Applying pool settings for %s... " , isnull ( get_pool_name ( work - > pool ) , " " ) ) ;
rd_lock ( & mining_thr_lock ) ;
// Shutdown all threads first (necessary)
if ( opt_isset ( options , SWITCHER_SOFT_RESET ) )
// Shutdown all threads first (necessary)
if ( opt_isset ( pool_switch_options , SWITCHER_SOFT_RESET ) )
{
applog ( LOG_DEBUG , " Soft Reset... Shutdown threads... " ) ;
for ( i = 0 ; i < mining_threads ; i + + )
{
applog ( LOG_DEBUG , " Soft Reset... Shutdown threads... " ) ;
for ( i = 0 ; i < mining_threads ; i + + )
{
struct thr_info * thr = mining_thr [ i ] ;
thr - > cgpu - > drv - > thread_shutdown ( thr ) ;
}
struct thr_info * thr = mining_thr [ i ] ;
thr - > cgpu - > drv - > thread_shutdown ( thr ) ;
}
}
// Reset stats (e.g. for working_diff to be set properly in hash_sole_work)
zero_stats ( ) ;
//devices
if ( opt_isset ( options , SWITCHER_APPLY_DEVICE ) )
{
//reset devices flags
opt_devs_enabled = 0 ;
for ( i = 0 ; i < MAX_DEVICES ; i + + )
devices_enabled [ i ] = false ;
// Reset stats (e.g. for working_diff to be set properly in hash_sole_work)
zero_stats ( ) ;
//assign pool devices if any
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > devices , ( ( ! empty_string ( default_profile . devices ) ) ? default_profile . devices : " all " ) ) ) ) ) {
set_devices ( ( char * ) opt ) ;
}
//devices
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_DEVICE ) )
{
//reset devices flags
opt_devs_enabled = 0 ;
for ( i = 0 ; i < MAX_DEVICES ; i + + )
devices_enabled [ i ] = false ;
//assign pool devices if any
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > devices , ( ( ! empty_string ( default_profile . devices ) ) ? default_profile . devices : " all " ) ) ) ) ) {
set_devices ( ( char * ) opt ) ;
}
}
//lookup gap
if ( opt_isset ( options , SWITCHER_APPLY_LG ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > lookup_gap , default_profile . lookup_gap ) ) ) )
set_lookup_gap ( ( char * ) opt ) ;
}
//lookup gap
if ( opt_isset ( pool_switch_ options, SWITCHER_APPLY_LG ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > lookup_gap , default_profile . lookup_gap ) ) ) )
set_lookup_gap ( ( char * ) opt ) ;
}
//raw intensity from pool
if ( opt_isset ( options , SWITCHER_APPLY_RAWINT ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > rawintensity , default_profile . rawintensity ) ) ) )
set_rawintensity ( ( char * ) opt ) ;
}
//xintensity
else if ( opt_isset ( options , SWITCHER_APPLY_XINT ) )
//raw intensity from pool
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_RAWINT ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > rawintensity , default_profile . rawintensity ) ) ) )
set_rawintensity ( ( char * ) opt ) ;
}
//xintensity
else if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_XINT ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > xintensity , default_profile . xintensity ) ) ) )
set_xintensity ( ( char * ) opt ) ;
}
//intensity
else if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_INT ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > intensity , default_profile . intensity ) ) ) )
set_intensity ( ( char * ) opt ) ;
}
//default basic intensity
else if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_INT8 ) )
{
default_profile . intensity = strdup ( " 8 " ) ;
set_intensity ( default_profile . intensity ) ;
}
//shaders
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_SHADER ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > shaders , default_profile . shaders ) ) ) )
set_shaders ( ( char * ) opt ) ;
}
//thread-concurrency
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_TC ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > thread_concurrency , default_profile . thread_concurrency ) ) ) )
set_thread_concurrency ( ( char * ) opt ) ;
}
//worksize
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_WORKSIZE ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > worksize , default_profile . worksize ) ) ) )
set_worksize ( ( char * ) opt ) ;
}
# ifdef HAVE_ADL
//GPU clock
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_ENGINE ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > xintensity , default_profile . xintensity ) ) ) )
set_xintensity ( ( char * ) opt ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_engine , default_profile . gpu_engine ) ) ) )
set_gpu_engine ( ( char * ) opt ) ;
}
//intensity
else if ( opt_isset ( options , SWITCHER_APPLY_INT ) )
//GPU memory clock
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_MEMCLOCK ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > intensity , default_profile . intensity ) ) ) )
set_intensity ( ( char * ) opt ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_memclock , default_profile . gpu_memclock ) ) ) )
set_gpu_memclock ( ( char * ) opt ) ;
}
//default basic intensity
else if ( opt_isset ( options , SWITCHER_APPLY_INT8 ) )
//GPU fans
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_FAN ) )
{
default_profile . intensity = strdup ( " 8 " ) ;
set_intensity ( default_profile . intensity ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_fan , default_profile . gpu_fan ) ) ) )
set_gpu_fan ( ( char * ) opt ) ;
}
//shaders
if ( opt_isset ( options , SWITCHER_APPLY_SHADER ) )
//GPU powertune
if ( opt_isset ( pool_switch_ options, SWITCHER_APPLY_GPU_POWERTUNE ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > shaders , default_profile . shaders ) ) ) )
set_shaders ( ( char * ) opt ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_powertune , default_profile . gpu_powertune ) ) ) )
set_gpu_powertune ( ( char * ) opt ) ;
}
//thread-concurrency
if ( opt_isset ( options , SWITCHER_APPLY_TC ) )
//GPU vddc
if ( opt_isset ( pool_switch_ options, SWITCHER_APPLY_GPU_VDD C ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > thread_concurrency , default_profile . thread_concurrency ) ) ) )
set_thread_concurrency ( ( char * ) opt ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_vddc , default_profile . gpu_vddc ) ) ) )
set_gpu_vddc ( ( char * ) opt ) ;
}
//worksize
if ( opt_isset ( options , SWITCHER_APPLY_WORKSIZE ) )
//apply gpu settings
for ( i = 0 ; i < nDevs ; i + + )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > worksize , default_profile . worksize ) ) ) )
set_worksize ( ( char * ) opt ) ;
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_ENGINE ) )
set_engineclock ( i , gpus [ i ] . min_engine ) ;
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_MEMCLOCK ) )
set_memoryclock ( i , gpus [ i ] . gpu_memclock ) ;
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_FAN ) )
set_fanspeed ( i , gpus [ i ] . min_fan ) ;
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_POWERTUNE ) )
set_powertune ( i , gpus [ i ] . gpu_powertune ) ;
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GPU_VDDC ) )
set_vddc ( i , gpus [ i ] . gpu_vddc ) ;
}
# endif
# ifdef HAVE_ADL
//GPU clock
if ( opt_isset ( options , SWITCHER_APPLY_GPU_ENGINE ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_engine , default_profile . gpu_engine ) ) ) )
set_gpu_engine ( ( char * ) opt ) ;
}
// Change algorithm for each thread (thread_prepare calls initCl)
if ( opt_isset ( pool_switch_options , SWITCHER_SOFT_RESET ) )
applog ( LOG_DEBUG , " Soft Reset... Restarting threads... " ) ;
//GPU memory clock
if ( opt_isset ( options , SWITCHER_APPLY_GPU_MEMCLOCK ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_memclock , default_profile . gpu_memclock ) ) ) )
set_gpu_memclock ( ( char * ) opt ) ;
}
struct thr_info * thr ;
//GPU fans
if ( opt_isset ( options , SWITCHER_APPLY_GPU_FAN ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_fan , default_profile . gpu_fan ) ) ) )
set_gpu_fan ( ( char * ) opt ) ;
}
for ( i = 0 ; i < mining_threads ; i + + )
{
thr = mining_thr [ i ] ;
thr - > pool_no = work - > pool - > pool_no ; //set thread on new pool
//GPU powertune
if ( opt_isset ( options , SWITCHER_APPLY_GPU_POWERTUNE ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_powertune , default_profile . gpu_powertune ) ) ) )
set_gpu_powertune ( ( char * ) opt ) ;
}
//apply new algorithm if set
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_ALGO ) )
thr - > cgpu - > algorithm = work - > pool - > algorithm ;
//GPU vddc
if ( opt_isset ( options , SWITCHER_APPLY_GPU_VDDC ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_vddc , default_profile . gpu_vddc ) ) ) )
set_gpu_vddc ( ( char * ) opt ) ;
}
if ( opt_isset ( pool_switch_options , SWITCHER_SOFT_RESET ) )
{
thr - > cgpu - > drv - > thread_prepare ( thr ) ;
thr - > cgpu - > drv - > thread_init ( thr ) ;
}
//apply gpu settings
for ( i = 0 ; i < nDevs ; i + + )
{
if ( opt_isset ( options , SWITCHER_APPLY_GPU_ENGINE ) )
set_engineclock ( i , gpus [ i ] . min_engine ) ;
if ( opt_isset ( options , SWITCHER_APPLY_GPU_MEMCLOCK ) )
set_memoryclock ( i , gpus [ i ] . gpu_memclock ) ;
if ( opt_isset ( options , SWITCHER_APPLY_GPU_FAN ) )
set_fanspeed ( i , gpus [ i ] . min_fan ) ;
if ( opt_isset ( options , SWITCHER_APPLY_GPU_POWERTUNE ) )
set_powertune ( i , gpus [ i ] . gpu_powertune ) ;
if ( opt_isset ( options , SWITCHER_APPLY_GPU_VDDC ) )
set_vddc ( i , gpus [ i ] . gpu_vddc ) ;
}
# endif
// Necessary because algorithms can have dramatically different diffs
thr - > cgpu - > drv - > working_diff = 1 ;
}
rd_unlock ( & mining_thr_lock ) ;
// Change algorithm for each thread (thread_prepare calls initCl)
if ( opt_isset ( options , SWITCHER_SOFT_RESET ) )
applog ( LOG_DEBUG , " Soft Reset... Restarting threads... " ) ;
// Finish switching pools
algo_switch_n = 0 ;
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
struct thr_info * thr ;
// Hard restart if needed
if ( opt_isset ( pool_switch_options , SWITCHER_HARD_RESET ) )
{
applog ( LOG_DEBUG , " Hard Reset Mining Threads... " ) ;
for ( i = 0 ; i < mining_threads ; i + + )
//if devices changed... enable/disable as needed
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_DEVICE ) )
{
thr = mining_thr [ i ] ;
thr - > pool_no = work - > pool - > pool_no ; //set thread on new pool
// reset devices
enable_devices ( ) ;
}
//apply new algorithm if set
if ( opt_isset ( options , SWITCHER_APPLY_ALGO ) )
thr - > cgpu - > algorithm = work - > pool - > algorithm ;
//figure out how many mining threads we'll need
unsigned int n_threads = 0 ;
pthread_t restart_thr ;
if ( opt_isset ( options , SWITCHER_SOFT_RESET ) )
# ifdef HAVE_ADL
//change gpu threads if needed
if ( opt_isset ( pool_switch_options , SWITCHER_APPLY_GT ) )
{
thr - > cgpu - > drv - > thread_prepare ( thr ) ;
thr - > cgpu - > drv - > thread_init ( thr ) ;
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_threads , default_profile . gpu_threads ) ) ) )
set_gpu_threads ( opt ) ;
}
// Necessary because algorithms can have dramatically different diffs
thr - > cgpu - > drv - > working_diff = 1 ;
}
rd_unlock ( & mining_thr_lock ) ;
// Finish switching pools
algo_switch_n = 0 ;
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
rd_lock ( & devices_lock ) ;
for ( i = 0 ; i < total_devices ; i + + )
if ( ! opt_removedisabled | | ! opt_devs_enabled | | devices_enabled [ i ] )
n_threads + = devices [ i ] - > threads ;
rd_unlock ( & devices_lock ) ;
# else
n_threads = mining_threads ;
# endif
// Hard restart if needed
if ( opt_isset ( options , SWITCHER_HARD_RESET ) )
{
applog ( LOG_DEBUG , " Hard Reset Mining Threads... " ) ;
if ( unlikely ( pthread_create ( & restart_thr , NULL , restart_mining_threads_thread , ( void * ) ( intptr_t ) n_threads ) ) )
quit ( 1 , " restart_mining_threads create thread failed " ) ;
sleep ( 60 ) ;
//if devices changed... enable/disable as needed
if ( opt_isset ( options , SWITCHER_APPLY_DEVICE ) )
# ifdef __TEMP_ALGO_SWITCH_FIX__
//if restart thread is done, then abort...
if ( ! thread_fix_search ( restart_thr ) )
{
// reset devices
enable_devices ( ) ;
applog ( LOG_DEBUG , " thread %d not found in fix list, don't exit sgminer " , restart_thr ) ;
pthread_cancel ( restart_thr ) ;
mutex_lock ( & algo_switch_wait_lock ) ;
pthread_cond_broadcast ( & algo_switch_wait_cond ) ;
mutex_unlock ( & algo_switch_wait_lock ) ;
return ;
}
# endif /* __TEMP_ALGO_SWITCH_FIX__ */
//figure out how many mining threads we'll need
unsigned int n_threads = 0 ;
pthread_t restart_thr ;
# ifdef HAVE_ADL
//change gpu threads if needed
if ( opt_isset ( options , SWITCHER_APPLY_GT ) )
{
if ( ! empty_string ( ( opt = get_pool_setting ( work - > pool - > gpu_threads , default_profile . gpu_threads ) ) ) )
set_gpu_threads ( opt ) ;
}
rd_lock ( & devices_lock ) ;
for ( i = 0 ; i < total_devices ; i + + )
if ( ! opt_removedisabled | | ! opt_devs_enabled | | devices_enabled [ i ] )
n_threads + = devices [ i ] - > threads ;
rd_unlock ( & devices_lock ) ;
# else
n_threads = mining_threads ;
# endif
if ( unlikely ( pthread_create ( & restart_thr , NULL , restart_mining_threads_thread , ( void * ) ( intptr_t ) n_threads ) ) )
quit ( 1 , " restart_mining_threads create thread failed " ) ;
sleep ( 60 ) ;
# ifdef __TEMP_ALGO_SWITCH_FIX__
//if restart thread is done, then abort...
if ( ! thread_fix_search ( restart_thr ) )
{
applog ( LOG_DEBUG , " thread %d not found in fix list, don't exit sgminer " , restart_thr ) ;
pthread_cancel ( restart_thr ) ;
mutex_lock ( & algo_switch_wait_lock ) ;
pthread_cond_broadcast ( & algo_switch_wait_cond ) ;
mutex_unlock ( & algo_switch_wait_lock ) ;
return ;
}
# endif /* __TEMP_ALGO_SWITCH_FIX__ */
quit ( 1 , " thread was not cancelled in 60 seconds after restart_mining_threads " ) ;
}
quit ( 1 , " thread was not cancelled in 60 seconds after restart_mining_threads " ) ;
}
//nothing changed... new pool uses same settings
else
{
//apply new pool_no to all mining threads
for ( i = 0 ; i < mining_threads ; i + + )
{
struct thr_info * thr = mining_thr [ i ] ;
thr - > pool_no = work - > pool - > pool_no ;
}
algo_switch_n = 0 ;
mutex_unlock ( & algo_switch_lock ) ;
pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE , NULL ) ;
}
// Signal other threads to start working now
// Signal other threads to start working now
//Broken... the following hangs the thread
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
{