mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-10 23:08:07 +00:00
Refactor and stability improvements when restarting threads
enable_device should not modify mining_threads because this is unsafe after initialization. it is also not necessary in most cases where it is currently used, except in initialization refactored some of the new restart_mining_threads code and incorporated above change for better stability properly handle disabled devices in restart_mining_threads when opt_removedisabled is set total_devices was set incorrectly if the disabled devices were not at the end of devices, so total_devices is now always the number of detected devices, since that is what is in the devices variable
This commit is contained in:
parent
be7d47dcee
commit
7f0451336b
@ -1154,6 +1154,7 @@ static void opencl_detect(bool hotplug)
|
|||||||
cgpu = &gpus[i];
|
cgpu = &gpus[i];
|
||||||
cgpu->deven = DEV_ENABLED;
|
cgpu->deven = DEV_ENABLED;
|
||||||
cgpu->drv = &opencl_drv;
|
cgpu->drv = &opencl_drv;
|
||||||
|
cgpu->thr = NULL;
|
||||||
cgpu->device_id = i;
|
cgpu->device_id = i;
|
||||||
#ifndef HAVE_ADL
|
#ifndef HAVE_ADL
|
||||||
cgpu->threads = opt_g_threads;
|
cgpu->threads = opt_g_threads;
|
||||||
|
139
sgminer.c
139
sgminer.c
@ -5977,13 +5977,45 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|||||||
cgtime(&work->tv_staged);
|
cgtime(&work->tv_staged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void enable_devices(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//enable/disable devices as needed
|
||||||
|
sgminer_id_count = 0;
|
||||||
|
|
||||||
|
if(opt_devs_enabled)
|
||||||
|
{
|
||||||
|
for (i = 0; i < total_devices; i++)
|
||||||
|
{
|
||||||
|
//device should be enabled
|
||||||
|
if(devices_enabled[i])
|
||||||
|
enable_device(devices[i]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if option is set to not remove disabled, enable device
|
||||||
|
if(!opt_removedisabled)
|
||||||
|
enable_device(devices[i]);
|
||||||
|
|
||||||
|
//mark as disabled
|
||||||
|
devices[i]->deven = DEV_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//enable all devices
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < total_devices; ++i)
|
||||||
|
enable_device(devices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void apply_initial_gpu_settings(struct pool *pool)
|
static void apply_initial_gpu_settings(struct pool *pool)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *opt;
|
const char *opt;
|
||||||
unsigned char options; //gpu adl options to apply
|
unsigned char options; //gpu adl options to apply
|
||||||
unsigned int start_threads = mining_threads, //initial count of mining threads before we change devices
|
unsigned int needed_threads = 0; //number of mining threads needed after we change devices
|
||||||
needed_threads = 0; //number of mining threads needed after we change devices
|
|
||||||
|
|
||||||
applog(LOG_NOTICE, "Startup Pool No = %d", pool->pool_no);
|
applog(LOG_NOTICE, "Startup Pool No = %d", pool->pool_no);
|
||||||
|
|
||||||
@ -6082,32 +6114,7 @@ static void apply_initial_gpu_settings(struct pool *pool)
|
|||||||
rd_unlock(&mining_thr_lock);
|
rd_unlock(&mining_thr_lock);
|
||||||
|
|
||||||
//enable/disable devices as needed
|
//enable/disable devices as needed
|
||||||
sgminer_id_count = 0; //reset sgminer_ids
|
enable_devices();
|
||||||
mining_threads = 0; //mining threads gets added inside each enable_device() so reset
|
|
||||||
if(opt_devs_enabled)
|
|
||||||
{
|
|
||||||
for (i = 0; i < MAX_DEVICES; i++)
|
|
||||||
{
|
|
||||||
//device should be enabled
|
|
||||||
if(devices_enabled[i] && i < total_devices)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
else if(i < total_devices)
|
|
||||||
{
|
|
||||||
//if option is set to not remove disabled, enable device
|
|
||||||
if(!opt_removedisabled)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
|
|
||||||
//mark as disabled
|
|
||||||
devices[i]->deven = DEV_DISABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//enable all devices
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < total_devices; ++i)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//recount the number of needed mining threads
|
//recount the number of needed mining threads
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
@ -6115,14 +6122,12 @@ static void apply_initial_gpu_settings(struct pool *pool)
|
|||||||
set_gpu_threads((char *)opt);
|
set_gpu_threads((char *)opt);
|
||||||
|
|
||||||
for (i = 0; i < total_devices; i++)
|
for (i = 0; i < total_devices; i++)
|
||||||
|
if (!opt_removedisabled || !opt_devs_enabled || devices_enabled[i])
|
||||||
needed_threads += devices[i]->threads;
|
needed_threads += devices[i]->threads;
|
||||||
#else
|
#else
|
||||||
needed_threads = mining_threads;
|
needed_threads = mining_threads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//revert global mining thread count to start thread count so we don't touch threads outside of count
|
|
||||||
mining_threads = start_threads;
|
|
||||||
|
|
||||||
//bad thread count?
|
//bad thread count?
|
||||||
if(needed_threads == 0)
|
if(needed_threads == 0)
|
||||||
quit(1, "No GPUs Initialized.");
|
quit(1, "No GPUs Initialized.");
|
||||||
@ -6281,7 +6286,6 @@ 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
|
int active_threads; //number of actual active threads
|
||||||
int start_threads; //number of threads at start before devices enabled change
|
|
||||||
unsigned long options;
|
unsigned long options;
|
||||||
const char *opt;
|
const char *opt;
|
||||||
|
|
||||||
@ -6332,8 +6336,6 @@ 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)
|
||||||
{
|
{
|
||||||
start_threads = mining_threads; //use start_threads below
|
|
||||||
|
|
||||||
//compare pools to figure out what we need to apply, if options is 0, don't change anything...
|
//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)))
|
if((options = compare_pool_settings(pools[mythr->pool_no], work->pool)))
|
||||||
{
|
{
|
||||||
@ -6343,7 +6345,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
if(opt_isset(options, SWITCHER_SOFT_RESET))
|
if(opt_isset(options, SWITCHER_SOFT_RESET))
|
||||||
{
|
{
|
||||||
applog(LOG_DEBUG, "Soft Reset... Shutdown threads...");
|
applog(LOG_DEBUG, "Soft Reset... Shutdown threads...");
|
||||||
for (i = 0; i < start_threads; i++)
|
for (i = 0; i < mining_threads; i++)
|
||||||
{
|
{
|
||||||
struct thr_info *thr = mining_thr[i];
|
struct thr_info *thr = mining_thr[i];
|
||||||
thr->cgpu->drv->thread_shutdown(thr);
|
thr->cgpu->drv->thread_shutdown(thr);
|
||||||
@ -6477,7 +6479,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
|
|
||||||
struct thr_info *thr;
|
struct thr_info *thr;
|
||||||
|
|
||||||
for (i = 0; i < start_threads; i++)
|
for (i = 0; i < mining_threads; i++)
|
||||||
{
|
{
|
||||||
thr = mining_thr[i];
|
thr = mining_thr[i];
|
||||||
thr->pool_no = work->pool->pool_no; //set thread on new pool
|
thr->pool_no = work->pool->pool_no; //set thread on new pool
|
||||||
@ -6511,32 +6513,8 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
//if devices changed... enable/disable as needed
|
//if devices changed... enable/disable as needed
|
||||||
if(opt_isset(options, SWITCHER_APPLY_DEVICE))
|
if(opt_isset(options, SWITCHER_APPLY_DEVICE))
|
||||||
{
|
{
|
||||||
sgminer_id_count = 0; //reset sgminer_ids
|
// reset devices
|
||||||
mining_threads = 0; //mining threads gets added inside each enable_device() so reset
|
enable_devices();
|
||||||
if(opt_devs_enabled)
|
|
||||||
{
|
|
||||||
for (i = 0; i < MAX_DEVICES; i++)
|
|
||||||
{
|
|
||||||
//device should be enabled
|
|
||||||
if(devices_enabled[i] && i < total_devices)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
else if(i < total_devices)
|
|
||||||
{
|
|
||||||
//if option is set to not remove disabled, enable device
|
|
||||||
if(!opt_removedisabled)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
|
|
||||||
//mark as disabled
|
|
||||||
devices[i]->deven = DEV_DISABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//enable all devices
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < total_devices; ++i)
|
|
||||||
enable_device(devices[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//figure out how many mining threads we'll need
|
//figure out how many mining threads we'll need
|
||||||
@ -6552,15 +6530,12 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < total_devices; i++)
|
for (i = 0; i < total_devices; i++)
|
||||||
|
if (!opt_removedisabled || !opt_devs_enabled || devices_enabled[i])
|
||||||
n_threads += devices[i]->threads;
|
n_threads += devices[i]->threads;
|
||||||
#else
|
#else
|
||||||
n_threads = mining_threads;
|
n_threads = mining_threads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*use start_threads to close original threads... mining_threads was recounted above and would cause crashes
|
|
||||||
when trying to close a thread index that doesn't exist.*/
|
|
||||||
mining_threads = start_threads;
|
|
||||||
|
|
||||||
if (unlikely(pthread_create(&restart_thr, NULL, restart_mining_threads_thread, (void *) (intptr_t) n_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");
|
quit(1, "restart_mining_threads create thread failed");
|
||||||
sleep(60);
|
sleep(60);
|
||||||
@ -6585,7 +6560,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//apply new pool_no to all mining threads
|
//apply new pool_no to all mining threads
|
||||||
for (i = 0; i < start_threads; i++)
|
for (i = 0; i < mining_threads; i++)
|
||||||
{
|
{
|
||||||
struct thr_info *thr = mining_thr[i];
|
struct thr_info *thr = mining_thr[i];
|
||||||
thr->pool_no = work->pool->pool_no;
|
thr->pool_no = work->pool->pool_no;
|
||||||
@ -8017,11 +7992,6 @@ void enable_device(struct cgpu_info *cgpu)
|
|||||||
wr_lock(&devices_lock);
|
wr_lock(&devices_lock);
|
||||||
devices[cgpu->sgminer_id = sgminer_id_count++] = cgpu;
|
devices[cgpu->sgminer_id = sgminer_id_count++] = cgpu;
|
||||||
wr_unlock(&devices_lock);
|
wr_unlock(&devices_lock);
|
||||||
|
|
||||||
mining_threads += cgpu->threads;
|
|
||||||
#ifdef HAVE_CURSES
|
|
||||||
adj_width(mining_threads, &dev_width);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _cgpu_devid_counter {
|
struct _cgpu_devid_counter {
|
||||||
@ -8111,7 +8081,7 @@ static void restart_mining_threads(unsigned int new_n_threads)
|
|||||||
if (mining_thr)
|
if (mining_thr)
|
||||||
{
|
{
|
||||||
for (i = 0; i < total_devices; i++) {
|
for (i = 0; i < total_devices; i++) {
|
||||||
free(devices[i]->thr);
|
if (devices[i]->thr) free(devices[i]->thr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < mining_threads; i++) {
|
for (i = 0; i < mining_threads; i++) {
|
||||||
@ -8148,6 +8118,12 @@ static void restart_mining_threads(unsigned int new_n_threads)
|
|||||||
k = 0;
|
k = 0;
|
||||||
for (i = 0; i < total_devices; ++i) {
|
for (i = 0; i < total_devices; ++i) {
|
||||||
struct cgpu_info *cgpu = devices[i];
|
struct cgpu_info *cgpu = devices[i];
|
||||||
|
|
||||||
|
if (cgpu->deven == DEV_DISABLED && opt_removedisabled) {
|
||||||
|
cgpu->threads = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cgpu->thr = (struct thr_info **)malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));
|
cgpu->thr = (struct thr_info **)malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));
|
||||||
cgpu->thr[cgpu->threads] = NULL;
|
cgpu->thr[cgpu->threads] = NULL;
|
||||||
cgpu->status = LIFE_INIT;
|
cgpu->status = LIFE_INIT;
|
||||||
@ -8393,6 +8369,7 @@ int main(int argc, char *argv[])
|
|||||||
/* Use the DRIVER_PARSE_COMMANDS macro to fill all the device_drvs */
|
/* Use the DRIVER_PARSE_COMMANDS macro to fill all the device_drvs */
|
||||||
DRIVER_PARSE_COMMANDS(DRIVER_FILL_DEVICE_DRV)
|
DRIVER_PARSE_COMMANDS(DRIVER_FILL_DEVICE_DRV)
|
||||||
|
|
||||||
|
// this will set total_devices
|
||||||
opencl_drv.drv_detect(false);
|
opencl_drv.drv_detect(false);
|
||||||
|
|
||||||
if (opt_display_devs) {
|
if (opt_display_devs) {
|
||||||
@ -8414,19 +8391,27 @@ int main(int argc, char *argv[])
|
|||||||
if (i >= total_devices)
|
if (i >= total_devices)
|
||||||
quit (1, "Command line options set a device that doesn't exist");
|
quit (1, "Command line options set a device that doesn't exist");
|
||||||
enable_device(devices[i]);
|
enable_device(devices[i]);
|
||||||
|
mining_threads += devices[i]->threads;
|
||||||
} else if (i < total_devices) {
|
} else if (i < total_devices) {
|
||||||
if (!opt_removedisabled)
|
if (!opt_removedisabled) {
|
||||||
enable_device(devices[i]);
|
enable_device(devices[i]);
|
||||||
|
mining_threads += devices[i]->threads;
|
||||||
|
}
|
||||||
devices[i]->deven = DEV_DISABLED;
|
devices[i]->deven = DEV_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
total_devices = sgminer_id_count;
|
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < total_devices; ++i)
|
for (i = 0; i < total_devices; ++i) {
|
||||||
enable_device(devices[i]);
|
enable_device(devices[i]);
|
||||||
|
mining_threads += devices[i]->threads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!total_devices)
|
#ifdef HAVE_CURSES
|
||||||
|
adj_width(mining_threads, &dev_width);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mining_threads == 0)
|
||||||
quit(1, "All devices disabled, cannot mine!");
|
quit(1, "All devices disabled, cannot mine!");
|
||||||
|
|
||||||
most_devices = total_devices;
|
most_devices = total_devices;
|
||||||
|
Loading…
Reference in New Issue
Block a user