1
0
mirror of https://github.com/GOSTSec/sgminer synced 2025-01-31 08:54:19 +00:00

Hangup fix

The switcher would hang when no settings needed to be applied and it
tried to tell the mining threads to resume working. Still an issue if
you attempt to switch between two pools that apply settings but don't
perform a hard reset.
This commit is contained in:
ystarnaud 2014-07-01 14:48:17 -04:00
parent d211d5b9bf
commit 55cd3ec220

121
sgminer.c
View File

@ -281,7 +281,8 @@ static pthread_cond_t lp_cond;
static pthread_mutex_t algo_switch_lock; static pthread_mutex_t algo_switch_lock;
static int algo_switch_n = 0; 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; static pthread_cond_t algo_switch_wait_cond;
pthread_mutex_t restart_lock; pthread_mutex_t restart_lock;
@ -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) static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{ {
int i; int i;
int active_threads; //number of actual active threads
unsigned long options;
const char *opt;
//if switcher is disabled //if switcher is disabled
if(opt_switchmode == SWITCH_OFF) if(opt_switchmode == SWITCH_OFF)
@ -6297,20 +6295,42 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
mutex_lock(&algo_switch_lock); mutex_lock(&algo_switch_lock);
if(algo_switch_n == 0)
{
//get pool options to apply on switch
pool_switch_options = 0;
//switcher mode - switch on algorithm change //switcher mode - switch on algorithm change
if(opt_switchmode == SWITCH_ALGO) if(opt_switchmode == SWITCH_ALGO)
{ {
if(cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm) && (algo_switch_n == 0)) //if algorithms are different
{ if(!cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm))
mutex_unlock(&algo_switch_lock); pool_switch_options = compare_pool_settings(pools[mythr->pool_no], work->pool);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
return;
}
} }
//switcher mode - switch on pool change //switcher mode - switch on pool change
else if(opt_switchmode == SWITCH_POOL) else if(opt_switchmode == SWITCH_POOL)
{ {
if((work->pool->pool_no == mythr->pool_no) && (algo_switch_n == 0)) 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); mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
@ -6321,9 +6341,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
algo_switch_n++; 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 //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); rd_lock(&mining_thr_lock);
int active_threads = 0;
for(i = 0; i < mining_threads; i++) for(i = 0; i < mining_threads; i++)
{ {
struct cgpu_info *cgpu = mining_thr[i]->cgpu; struct cgpu_info *cgpu = mining_thr[i]->cgpu;
@ -6337,13 +6357,13 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
// If all threads are waiting now // If all threads are waiting now
if(algo_switch_n >= active_threads) if(algo_switch_n >= active_threads)
{ {
//compare pools to figure out what we need to apply, if options is 0, don't change anything... const char *opt;
if((options = compare_pool_settings(pools[mythr->pool_no], work->pool)))
{ applog(LOG_NOTICE, "Applying pool settings for %s...", isnull(get_pool_name(work->pool), ""));
rd_lock(&mining_thr_lock); rd_lock(&mining_thr_lock);
// Shutdown all threads first (necessary) // Shutdown all threads first (necessary)
if(opt_isset(options, SWITCHER_SOFT_RESET)) if(opt_isset(pool_switch_options, SWITCHER_SOFT_RESET))
{ {
applog(LOG_DEBUG, "Soft Reset... Shutdown threads..."); applog(LOG_DEBUG, "Soft Reset... Shutdown threads...");
for (i = 0; i < mining_threads; i++) for (i = 0; i < mining_threads; i++)
@ -6357,7 +6377,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
zero_stats(); zero_stats();
//devices //devices
if(opt_isset(options, SWITCHER_APPLY_DEVICE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_DEVICE))
{ {
//reset devices flags //reset devices flags
opt_devs_enabled = 0; opt_devs_enabled = 0;
@ -6371,53 +6391,53 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
} }
//lookup gap //lookup gap
if(opt_isset(options, SWITCHER_APPLY_LG)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_LG))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->lookup_gap, default_profile.lookup_gap)))) if(!empty_string((opt = get_pool_setting(work->pool->lookup_gap, default_profile.lookup_gap))))
set_lookup_gap((char *)opt); set_lookup_gap((char *)opt);
} }
//raw intensity from pool //raw intensity from pool
if(opt_isset(options, SWITCHER_APPLY_RAWINT)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_RAWINT))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->rawintensity, default_profile.rawintensity)))) if(!empty_string((opt = get_pool_setting(work->pool->rawintensity, default_profile.rawintensity))))
set_rawintensity((char *)opt); set_rawintensity((char *)opt);
} }
//xintensity //xintensity
else if(opt_isset(options, SWITCHER_APPLY_XINT)) else if(opt_isset(pool_switch_options, SWITCHER_APPLY_XINT))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->xintensity, default_profile.xintensity)))) if(!empty_string((opt = get_pool_setting(work->pool->xintensity, default_profile.xintensity))))
set_xintensity((char *)opt); set_xintensity((char *)opt);
} }
//intensity //intensity
else if(opt_isset(options, SWITCHER_APPLY_INT)) else if(opt_isset(pool_switch_options, SWITCHER_APPLY_INT))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->intensity, default_profile.intensity)))) if(!empty_string((opt = get_pool_setting(work->pool->intensity, default_profile.intensity))))
set_intensity((char *)opt); set_intensity((char *)opt);
} }
//default basic intensity //default basic intensity
else if(opt_isset(options, SWITCHER_APPLY_INT8)) else if(opt_isset(pool_switch_options, SWITCHER_APPLY_INT8))
{ {
default_profile.intensity = strdup("8"); default_profile.intensity = strdup("8");
set_intensity(default_profile.intensity); set_intensity(default_profile.intensity);
} }
//shaders //shaders
if(opt_isset(options, SWITCHER_APPLY_SHADER)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_SHADER))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->shaders, default_profile.shaders)))) if(!empty_string((opt = get_pool_setting(work->pool->shaders, default_profile.shaders))))
set_shaders((char *)opt); set_shaders((char *)opt);
} }
//thread-concurrency //thread-concurrency
if(opt_isset(options, SWITCHER_APPLY_TC)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_TC))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->thread_concurrency, default_profile.thread_concurrency)))) if(!empty_string((opt = get_pool_setting(work->pool->thread_concurrency, default_profile.thread_concurrency))))
set_thread_concurrency((char *)opt); set_thread_concurrency((char *)opt);
} }
//worksize //worksize
if(opt_isset(options, SWITCHER_APPLY_WORKSIZE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_WORKSIZE))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->worksize, default_profile.worksize)))) if(!empty_string((opt = get_pool_setting(work->pool->worksize, default_profile.worksize))))
set_worksize((char *)opt); set_worksize((char *)opt);
@ -6425,35 +6445,35 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
#ifdef HAVE_ADL #ifdef HAVE_ADL
//GPU clock //GPU clock
if(opt_isset(options, SWITCHER_APPLY_GPU_ENGINE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_ENGINE))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_engine, default_profile.gpu_engine)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_engine, default_profile.gpu_engine))))
set_gpu_engine((char *)opt); set_gpu_engine((char *)opt);
} }
//GPU memory clock //GPU memory clock
if(opt_isset(options, SWITCHER_APPLY_GPU_MEMCLOCK)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_MEMCLOCK))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_memclock, default_profile.gpu_memclock)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_memclock, default_profile.gpu_memclock))))
set_gpu_memclock((char *)opt); set_gpu_memclock((char *)opt);
} }
//GPU fans //GPU fans
if(opt_isset(options, SWITCHER_APPLY_GPU_FAN)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_FAN))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_fan, default_profile.gpu_fan)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_fan, default_profile.gpu_fan))))
set_gpu_fan((char *)opt); set_gpu_fan((char *)opt);
} }
//GPU powertune //GPU powertune
if(opt_isset(options, SWITCHER_APPLY_GPU_POWERTUNE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_POWERTUNE))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_powertune, default_profile.gpu_powertune)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_powertune, default_profile.gpu_powertune))))
set_gpu_powertune((char *)opt); set_gpu_powertune((char *)opt);
} }
//GPU vddc //GPU vddc
if(opt_isset(options, SWITCHER_APPLY_GPU_VDDC)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_VDDC))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_vddc, default_profile.gpu_vddc)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_vddc, default_profile.gpu_vddc))))
set_gpu_vddc((char *)opt); set_gpu_vddc((char *)opt);
@ -6462,21 +6482,21 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
//apply gpu settings //apply gpu settings
for (i = 0; i < nDevs; i++) for (i = 0; i < nDevs; i++)
{ {
if(opt_isset(options, SWITCHER_APPLY_GPU_ENGINE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_ENGINE))
set_engineclock(i, gpus[i].min_engine); set_engineclock(i, gpus[i].min_engine);
if(opt_isset(options, SWITCHER_APPLY_GPU_MEMCLOCK)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_MEMCLOCK))
set_memoryclock(i, gpus[i].gpu_memclock); set_memoryclock(i, gpus[i].gpu_memclock);
if(opt_isset(options, SWITCHER_APPLY_GPU_FAN)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_FAN))
set_fanspeed(i, gpus[i].min_fan); set_fanspeed(i, gpus[i].min_fan);
if(opt_isset(options, SWITCHER_APPLY_GPU_POWERTUNE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_POWERTUNE))
set_powertune(i, gpus[i].gpu_powertune); set_powertune(i, gpus[i].gpu_powertune);
if(opt_isset(options, SWITCHER_APPLY_GPU_VDDC)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GPU_VDDC))
set_vddc(i, gpus[i].gpu_vddc); set_vddc(i, gpus[i].gpu_vddc);
} }
#endif #endif
// Change algorithm for each thread (thread_prepare calls initCl) // Change algorithm for each thread (thread_prepare calls initCl)
if(opt_isset(options, SWITCHER_SOFT_RESET)) if(opt_isset(pool_switch_options, SWITCHER_SOFT_RESET))
applog(LOG_DEBUG, "Soft Reset... Restarting threads..."); applog(LOG_DEBUG, "Soft Reset... Restarting threads...");
struct thr_info *thr; struct thr_info *thr;
@ -6487,10 +6507,10 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
thr->pool_no = work->pool->pool_no; //set thread on new pool thr->pool_no = work->pool->pool_no; //set thread on new pool
//apply new algorithm if set //apply new algorithm if set
if(opt_isset(options, SWITCHER_APPLY_ALGO)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_ALGO))
thr->cgpu->algorithm = work->pool->algorithm; thr->cgpu->algorithm = work->pool->algorithm;
if(opt_isset(options, SWITCHER_SOFT_RESET)) if(opt_isset(pool_switch_options, SWITCHER_SOFT_RESET))
{ {
thr->cgpu->drv->thread_prepare(thr); thr->cgpu->drv->thread_prepare(thr);
thr->cgpu->drv->thread_init(thr); thr->cgpu->drv->thread_init(thr);
@ -6508,12 +6528,12 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
// Hard restart if needed // Hard restart if needed
if(opt_isset(options, SWITCHER_HARD_RESET)) if(opt_isset(pool_switch_options, SWITCHER_HARD_RESET))
{ {
applog(LOG_DEBUG, "Hard Reset Mining Threads..."); applog(LOG_DEBUG, "Hard Reset Mining Threads...");
//if devices changed... enable/disable as needed //if devices changed... enable/disable as needed
if(opt_isset(options, SWITCHER_APPLY_DEVICE)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_DEVICE))
{ {
// reset devices // reset devices
enable_devices(); enable_devices();
@ -6525,7 +6545,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
#ifdef HAVE_ADL #ifdef HAVE_ADL
//change gpu threads if needed //change gpu threads if needed
if(opt_isset(options, SWITCHER_APPLY_GT)) if(opt_isset(pool_switch_options, SWITCHER_APPLY_GT))
{ {
if(!empty_string((opt = get_pool_setting(work->pool->gpu_threads, default_profile.gpu_threads)))) if(!empty_string((opt = get_pool_setting(work->pool->gpu_threads, default_profile.gpu_threads))))
set_gpu_threads(opt); set_gpu_threads(opt);
@ -6559,27 +6579,12 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
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); mutex_lock(&algo_switch_wait_lock);
pthread_cond_broadcast(&algo_switch_wait_cond); pthread_cond_broadcast(&algo_switch_wait_cond);
mutex_unlock(&algo_switch_wait_lock); mutex_unlock(&algo_switch_wait_lock);
// Not all threads are waiting, join the waiting list
} }
else else
{ {