Browse Source

Algorithm Switcher Update

Updated Algorithm switcher to change on pool rather than on algorithm.
This way if, for example, 2 pools use the same algorithm but different
GPU settings, the settings will be applied when changing pool.

Additionally:
* Included a "common" algorithm type in API pool/profile listing. For
example using "marucoin-mod" will return "X13", "darkcoin-mod" will
return "X11", scrypt + nfactor != 10 will return "NScrypt", etc...

* Added "kernel" config option to be backwards compatible with other
miners' configs.

* Added a few algorithm aliases: x11mod -> darkcoin-mod, x13mod ->
marucoin-mod...

* New config keyword: "includes", which holds an array of include files.
This is to counter the JSON limitation not allowing multiple values with
the same name, thus preventing inclusion of multiple files.
djm34
ystarnaud 10 years ago
parent
commit
3ae5f97b94
  1. 69
      algorithm.c
  2. 16
      algorithm.h
  3. 12
      api.c
  4. 28
      config_parser.c
  5. 1
      driver-opencl.c
  6. 37
      miner.h
  7. 605
      sgminer.c

69
algorithm.c

@ -31,6 +31,21 @@ @@ -31,6 +31,21 @@
#include <inttypes.h>
#include <string.h>
const char *algorithm_type_str[] = {
"Unknown",
"Scrypt",
"NScrypt",
"X11",
"X13",
"Keccak",
"Quarkcoin",
"Twecoin",
"Fugue256",
"NIST"
};
void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
{
sph_sha256_context ctx_sha2;
@ -308,6 +323,7 @@ static cl_int queue_talkcoin_mod_kernel(struct __clState *clState, struct _dev_b @@ -308,6 +323,7 @@ static cl_int queue_talkcoin_mod_kernel(struct __clState *clState, struct _dev_b
typedef struct _algorithm_settings_t {
const char *name; /* Human-readable identifier */
algorithm_type_t type; //common algorithm type
double diff_multiplier1;
double diff_multiplier2;
double share_diff_multiplier;
@ -329,7 +345,7 @@ typedef struct _algorithm_settings_t { @@ -329,7 +345,7 @@ typedef struct _algorithm_settings_t {
static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using litecoin algorithm
#define A_SCRYPT(a) \
{ a, 1, 65536, 65536, 0, 0, 0xFF, 0x0000ffff00000000ULL, 0xFFFFFFFFULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, scrypt_regenhash, queue_scrypt_kernel, gen_hash, append_scrypt_compiler_options}
{ a, ALGO_SCRYPT, 1, 65536, 65536, 0, 0, 0xFF, 0x0000ffff00000000ULL, 0xFFFFFFFFULL, 0x0000ffffUL, 0, -1, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, scrypt_regenhash, queue_scrypt_kernel, gen_hash, append_scrypt_compiler_options}
A_SCRYPT( "ckolivas" ),
A_SCRYPT( "alexkarnew" ),
A_SCRYPT( "alexkarnold" ),
@ -340,7 +356,7 @@ static algorithm_settings_t algos[] = { @@ -340,7 +356,7 @@ static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using quarkcoin algorithm
#define A_QUARK(a, b) \
{ a, 256, 256, 256, 0, 0, 0xFF, 0x000000ffff000000ULL, 0xFFFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, gen_hash, NULL}
{ a, ALGO_QUARK, 256, 256, 256, 0, 0, 0xFF, 0x000000ffff000000ULL, 0xFFFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, gen_hash, NULL}
A_QUARK( "quarkcoin", quarkcoin_regenhash),
A_QUARK( "qubitcoin", qubitcoin_regenhash),
A_QUARK( "animecoin", animecoin_regenhash),
@ -349,31 +365,31 @@ static algorithm_settings_t algos[] = { @@ -349,31 +365,31 @@ static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using bitcoin algorithm
#define A_DARK(a, b) \
{ a, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, gen_hash, NULL}
{ a, ALGO_X11, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, gen_hash, NULL}
A_DARK( "darkcoin", darkcoin_regenhash),
A_DARK( "inkcoin", inkcoin_regenhash),
A_DARK( "myriadcoin-groestl", myriadcoin_groestl_regenhash),
#undef A_DARK
{ "twecoin", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, twecoin_regenhash, queue_sph_kernel, sha256, NULL},
{ "maxcoin", 1, 256, 1, 4, 15, 0x0F, 0x00000000ffff0000ULL, 0xFFFFULL, 0x000000ffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, maxcoin_regenhash, queue_maxcoin_kernel, sha256, NULL},
{ "darkcoin-mod", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 10, 8 * 16 * 4194304, 0, darkcoin_regenhash, queue_darkcoin_mod_kernel, gen_hash, NULL},
{ "twecoin", ALGO_TWE, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, twecoin_regenhash, queue_sph_kernel, sha256, NULL},
{ "maxcoin", ALGO_KECCAK, 1, 256, 1, 4, 15, 0x0F, 0x00000000ffff0000ULL, 0xFFFFULL, 0x000000ffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, maxcoin_regenhash, queue_maxcoin_kernel, sha256, NULL},
{ "darkcoin-mod", ALGO_X11, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 10, 8 * 16 * 4194304, 0, darkcoin_regenhash, queue_darkcoin_mod_kernel, gen_hash, NULL},
{ "marucoin", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, marucoin_regenhash, queue_sph_kernel, gen_hash, append_hamsi_compiler_options},
{ "marucoin-mod", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 12, 8 * 16 * 4194304, 0, marucoin_regenhash, queue_marucoin_mod_kernel, gen_hash, append_hamsi_compiler_options},
{ "marucoin-modold", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 10, 8 * 16 * 4194304, 0, marucoin_regenhash, queue_marucoin_mod_old_kernel, gen_hash, append_hamsi_compiler_options},
{ "marucoin", ALGO_X13, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, marucoin_regenhash, queue_sph_kernel, gen_hash, append_hamsi_compiler_options},
{ "marucoin-mod", ALGO_X13, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 12, 8 * 16 * 4194304, 0, marucoin_regenhash, queue_marucoin_mod_kernel, gen_hash, append_hamsi_compiler_options},
{ "marucoin-modold", ALGO_X13, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 10, 8 * 16 * 4194304, 0, marucoin_regenhash, queue_marucoin_mod_old_kernel, gen_hash, append_hamsi_compiler_options},
{ "talkcoin-mod", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 4, 8 * 16 * 4194304, 0, talkcoin_regenhash, queue_talkcoin_mod_kernel, gen_hash, NULL},
{ "talkcoin-mod", ALGO_NIST, 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 4, 8 * 16 * 4194304, 0, talkcoin_regenhash, queue_talkcoin_mod_kernel, gen_hash, NULL},
// kernels starting from this will have difficulty calculated by using fuguecoin algorithm
#define A_FUGUE(a, b) \
{ a, 1, 256, 256, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, sha256, NULL}
{ a, ALGO_FUGUE, 1, 256, 256, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 0, 0, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, b, queue_sph_kernel, sha256, NULL}
A_FUGUE( "fuguecoin", fuguecoin_regenhash),
A_FUGUE( "groestlcoin", groestlcoin_regenhash),
#undef A_FUGUE
// Terminator (do not remove)
{ NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL}
{ NULL, ALGO_UNK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL}
};
void copy_algorithm_settings(algorithm_t* dest, const char* algo)
@ -381,9 +397,12 @@ void copy_algorithm_settings(algorithm_t* dest, const char* algo) @@ -381,9 +397,12 @@ void copy_algorithm_settings(algorithm_t* dest, const char* algo)
algorithm_settings_t* src;
// Find algorithm settings and copy
for (src = algos; src->name; src++) {
if (strcmp(src->name, algo) == 0) {
for (src = algos; src->name; src++)
{
if (strcmp(src->name, algo) == 0)
{
strcpy(dest->name, src->name);
dest->type = src->type;
dest->diff_multiplier1 = src->diff_multiplier1;
dest->diff_multiplier2 = src->diff_multiplier2;
@ -406,7 +425,8 @@ void copy_algorithm_settings(algorithm_t* dest, const char* algo) @@ -406,7 +425,8 @@ void copy_algorithm_settings(algorithm_t* dest, const char* algo)
}
// if not found
if (src->name == NULL) {
if (src->name == NULL)
{
applog(LOG_WARNING, "Algorithm %s not found, using %s.", algo, algos->name);
copy_algorithm_settings(dest, algos->name);
}
@ -457,6 +477,25 @@ void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor) @@ -457,6 +477,25 @@ void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor)
{
algo->nfactor = nfactor;
algo->n = (1 << nfactor);
//adjust algo type accordingly
switch (algo->type)
{
case ALGO_SCRYPT:
//if nfactor isnt 10, switch to NSCRYPT
if(algo->nfactor != 10)
algo->type = ALGO_NSCRYPT;
break;
//nscrypt
case ALGO_NSCRYPT:
//if nfactor is 10, switch to SCRYPT
if(algo->nfactor == 10)
algo->type = ALGO_SCRYPT;
break;
//ignore rest
default:
break;
}
}
bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2)

16
algorithm.h

@ -10,6 +10,21 @@ @@ -10,6 +10,21 @@
#include <inttypes.h>
#include <stdbool.h>
typedef enum {
ALGO_UNK,
ALGO_SCRYPT,
ALGO_NSCRYPT,
ALGO_X11,
ALGO_X13,
ALGO_KECCAK,
ALGO_QUARK,
ALGO_TWE,
ALGO_FUGUE,
ALGO_NIST
} algorithm_type_t;
extern const char *algorithm_type_str[];
extern void gen_hash(const unsigned char *data, unsigned int len, unsigned char *hash);
struct __clState;
@ -23,6 +38,7 @@ struct work; @@ -23,6 +38,7 @@ struct work;
*/
typedef struct _algorithm_t {
char name[20]; /* Human-readable identifier */
algorithm_type_t type; //algorithm type
uint32_t n; /* N (CPU/Memory tradeoff parameter) */
uint8_t nfactor; /* Factor of N above (n = 2^nfactor) */
double diff_multiplier1;

12
api.c

@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
#include "pool.h"
#include "util.h"
#include "pool.h"
#include "algorithm.h"
#include "config_parser.h"
@ -1602,8 +1603,14 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m @@ -1602,8 +1603,14 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
root = api_add_string(root, "Name", get_pool_name(pool), true);
mutex_unlock(&pool->stratum_lock);
root = api_add_escape(root, "URL", pool->rpc_url, false);
root = api_add_string(root, "Profile", pool->profile, false);
root = api_add_string(root, "Algorithm", pool->algorithm.name, false);
root = api_add_escape(root, "Profile", pool->profile, false);
root = api_add_escape(root, "Algorithm", pool->algorithm.name, false);
root = api_add_escape(root, "Algorithm Type", (char *)algorithm_type_str[pool->algorithm.type], false);
//show nfactor for nscrypt
if(pool->algorithm.type == ALGO_NSCRYPT)
root = api_add_int(root, "Algorithm NFactor", (int *)&(pool->algorithm.nfactor), false);
root = api_add_string(root, "Description", pool->description, false);
root = api_add_string(root, "Status", status, false);
root = api_add_int(root, "Priority", &(pool->prio), false);
@ -1620,6 +1627,7 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m @@ -1620,6 +1627,7 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
root = api_add_escape(root, "User", pool->rpc_user, false);
root = api_add_time(root, "Last Share Time", &(pool->last_share_time), false);
root = api_add_double(root, "Diff1 Shares", &(pool->diff1), false);
if (pool->rpc_proxy) {
root = api_add_const(root, "Proxy Type", proxytype(pool->rpc_proxytype), false);
root = api_add_escape(root, "Proxy", pool->rpc_proxy, false);

28
config_parser.c

@ -499,7 +499,8 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int @@ -499,7 +499,8 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int
{
//char *err = NULL;
const char *key;
json_t *val;
size_t idx;
json_t *val, *subval;
json_object_foreach(obj, key, val)
{
@ -509,6 +510,18 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int @@ -509,6 +510,18 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int
if(val && json_is_string(val))
load_config(json_string_value(val), parentkey, NULL);
}
//process includes - multi include
else if(!strcasecmp(key, "includes"))
{
if(val && json_is_array(val))
{
json_array_foreach(val, idx, subval)
{
if(subval && json_is_string(subval))
load_config(json_string_value(subval), parentkey, NULL);
}
}
}
else
parse_config(val, key, parentkey, fileconf, parent_iteration);
/*
@ -689,7 +702,7 @@ void load_default_profile() @@ -689,7 +702,7 @@ void load_default_profile()
// ... and copy settings
if(!empty_string(profile->algorithm.name))
set_algorithm(&default_profile.algorithm, profile->algorithm.name);
default_profile.algorithm = profile->algorithm;
if(!empty_string(profile->devices))
default_profile.devices = profile->devices;
@ -743,8 +756,10 @@ void apply_defaults() @@ -743,8 +756,10 @@ void apply_defaults()
set_algorithm(&default_profile.algorithm, "scrypt");
//by default all unless specified
if (empty_string(default_profile.devices))
if(empty_string(default_profile.devices))
default_profile.devices = strdup("all");
applog(LOG_DEBUG, "Default Devices = %s", default_profile.devices);
set_devices((char *)default_profile.devices);
//set raw intensity first
@ -1919,7 +1934,12 @@ void api_profile_list(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma @@ -1919,7 +1934,12 @@ void api_profile_list(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma
root = api_add_escape(root, "Name", profile->name, true);
root = api_add_bool(root, "IsDefault", &b, false);
root = api_add_escape(root, "Algorithm", isnull((char *)profile->algorithm.name, ""), true);
root = api_add_int(root, "NFactor", (int *)&profile->algorithm.nfactor, false);
root = api_add_escape(root, "Algorithm Type", (char *)algorithm_type_str[profile->algorithm.type], false);
//show nfactor for nscrypt
if(profile->algorithm.type == ALGO_NSCRYPT)
root = api_add_int(root, "Algorithm NFactor", (int *)&(profile->algorithm.nfactor), false);
root = api_add_escape(root, "LookupGap", isnull((char *)profile->lookup_gap, ""), true);
root = api_add_escape(root, "Devices", isnull((char *)profile->devices, ""), true);
root = api_add_escape(root, "Intensity", isnull((char *)profile->intensity, ""), true);

1
driver-opencl.c

@ -1320,6 +1320,7 @@ static bool opencl_thread_init(struct thr_info *thr) @@ -1320,6 +1320,7 @@ static bool opencl_thread_init(struct thr_info *thr)
static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work)
{
work->blk.work = work;
thr->pool_no = work->pool->pool_no;
return true;
}

37
miner.h

@ -321,9 +321,45 @@ struct gpu_adl { @@ -321,9 +321,45 @@ struct gpu_adl {
};
#endif
/***********************************
* Switcher stuff
****************************************/
#ifndef opt_isset
#define opt_isset(opt, val) (((opt & val) == val)?1:0)
#endif
#ifndef get_pool_setting
#define get_pool_setting(val, default_val) ((!empty_string(val))?val:((!empty_string(default_val))?default_val:""))
#endif
enum switcher_mode {
SWITCH_OFF,
SWITCH_ALGO,
SWITCH_POOL
};
extern int opt_switchmode;
enum switcher_options {
SWITCHER_APPLY_NONE = 0x00,
SWITCHER_APPLY_ALGO = 0x01,
SWITCHER_APPLY_DEVICE = 0x02,
SWITCHER_APPLY_GT = 0x04,
SWITCHER_APPLY_LG = 0x08,
SWITCHER_APPLY_RAWINT = 0x10,
SWITCHER_APPLY_XINT = 0x20,
SWITCHER_APPLY_INT = 0x40,
SWITCHER_APPLY_INT8 = 0x80,
SWITCHER_APPLY_SHADER = 0x100,
SWITCHER_APPLY_TC = 0x200,
SWITCHER_APPLY_WORKSIZE = 0x400,
SWITCHER_APPLY_GPU_ENGINE = 0x800,
SWITCHER_APPLY_GPU_MEMCLOCK = 0x1000,
SWITCHER_APPLY_GPU_FAN = 0x2000,
SWITCHER_APPLY_GPU_POWERTUNE = 0x4000,
SWITCHER_APPLY_GPU_VDDC = 0x8000,
SWITCHER_SOFT_RESET = 0x4000000,
SWITCHER_HARD_RESET = 0x8000000
};
enum gpu_adl_options {
APPLY_ENGINE = 1,
@ -572,6 +608,7 @@ struct thr_info { @@ -572,6 +608,7 @@ struct thr_info {
struct thread_q *q;
struct cgpu_info *cgpu;
void *cgpu_data;
int pool_no;
struct timeval last;
struct timeval sick;

605
sgminer.c

@ -332,6 +332,9 @@ enum pool_strategy pool_strategy = POOL_FAILOVER; @@ -332,6 +332,9 @@ enum pool_strategy pool_strategy = POOL_FAILOVER;
int opt_rotate_period;
static int total_urls;
//default mode apply algorithm/gpu settings when pool changes
int opt_switchmode = SWITCH_POOL;
static
#ifndef HAVE_CURSES
const
@ -730,17 +733,17 @@ void get_intrange(char *arg, int *val1, int *val2) @@ -730,17 +733,17 @@ void get_intrange(char *arg, int *val1, int *val2)
char *set_devices(char *arg)
{
int i, val1 = 0, val2 = 0;
char *nextptr;
char *p, *nextptr;
if(*arg)
if(arg[0] != '\0')
{
if (*arg == '?')
if(!strcasecmp(arg, "?"))
{
opt_display_devs = true;
return NULL;
}
//all devices enabled
else if(*arg == '*' || !strcasecmp(arg, "all"))
else if(!strcasecmp(arg, "*") || !strcasecmp(arg, "all"))
{
applog(LOG_DEBUG, "set_devices(all)");
opt_devs_enabled = 0;
@ -752,33 +755,33 @@ char *set_devices(char *arg) @@ -752,33 +755,33 @@ char *set_devices(char *arg)
applog(LOG_DEBUG, "set_devices(%s)", arg);
nextptr = strtok(arg, ",");
p = strdup(arg);
nextptr = strtok(p, ",");
do {
if (nextptr == NULL)
{
free(p);
return "Invalid parameters for set devices";
get_intrange(nextptr, &val1, &val2);
if (val1 < 0 || val1 > MAX_DEVICES || val2 < 0 || val2 > MAX_DEVICES ||
val1 > val2) {
return "Invalid value passed to set devices";
}
for (i = val1; i <= val2; i++) {
devices_enabled[i] = true;
opt_devs_enabled++;
}
while ((nextptr = strtok(NULL, ",")) != NULL) {
get_intrange(nextptr, &val1, &val2);
if (val1 < 0 || val1 > MAX_DEVICES || val2 < 0 || val2 > MAX_DEVICES ||
val1 > val2) {
if (val1 < 0 || val1 > MAX_DEVICES || val2 < 0 || val2 > MAX_DEVICES || val1 > val2)
{
free(p);
return "Invalid value passed to set devices";
}
for (i = val1; i <= val2; i++) {
for (i = val1; i <= val2; i++)
{
devices_enabled[i] = true;
opt_devs_enabled++;
}
}
} while ((nextptr = strtok(NULL, ",")) != NULL);
applog(LOG_DEBUG, "set_devices(%s) done.", arg);
free(p);
return NULL;
}
@ -1074,6 +1077,21 @@ static char *set_pool_state(char *arg) @@ -1074,6 +1077,21 @@ static char *set_pool_state(char *arg)
return NULL;
}
static char *set_switcher_mode(char *arg)
{
if(!strcasecmp(arg, "off"))
opt_switchmode = SWITCH_OFF;
else if(!strcasecmp(arg, "algorithm"))
opt_switchmode = SWITCH_ALGO;
else if(!strcasecmp(arg, "pool"))
opt_switchmode = SWITCH_POOL;
else
return NULL;
applog(LOG_INFO, "Setting switcher mode to %s", arg);
return NULL;
}
static char *set_quota(char *arg)
{
char *semicolon = strchr(arg, ';'), *url;
@ -1320,7 +1338,7 @@ char *set_difficulty_multiplier(char *arg) @@ -1320,7 +1338,7 @@ char *set_difficulty_multiplier(char *arg)
/* These options are available from config file or commandline */
struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--algorithm",
OPT_WITH_ARG("--algorithm|--kernel|-k",
set_default_algorithm, NULL, NULL,
"Set mining algorithm and most common defaults, default: scrypt"),
OPT_WITH_ARG("--api-allow",
@ -1542,7 +1560,7 @@ struct opt_table opt_config_table[] = { @@ -1542,7 +1560,7 @@ struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--poolname", /* TODO: Backward compatibility, to be removed. */
set_poolname_deprecated, NULL, NULL,
opt_hidden),
OPT_WITH_ARG("--pool-algorithm",
OPT_WITH_ARG("--pool-algorithm|--pool-kernel",
set_pool_algorithm, NULL, NULL,
"Set algorithm for pool"),
OPT_WITH_ARG("--pool-device",
@ -1600,7 +1618,7 @@ struct opt_table opt_config_table[] = { @@ -1600,7 +1618,7 @@ struct opt_table opt_config_table[] = {
set_pool_priority, NULL, NULL,
"Pool priority"),
OPT_WITH_ARG("--profile-algorithm",
OPT_WITH_ARG("--profile-algorithm|--profile-kernel",
set_profile_algorithm, NULL, NULL,
"Set algorithm for profile"),
OPT_WITH_ARG("--profile-device",
@ -1711,6 +1729,9 @@ struct opt_table opt_config_table[] = { @@ -1711,6 +1729,9 @@ struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--state|--pool-state",
set_pool_state, NULL, NULL,
"Specify pool state at startup (default: enabled)"),
OPT_WITH_ARG("--switcher-mode",
set_switcher_mode, NULL, NULL,
"Algorithm/gpu settings switcher mode."),
#ifdef HAVE_SYSLOG_H
OPT_WITHOUT_ARG("--syslog",
opt_set_bool, &use_syslog,
@ -5988,10 +6009,13 @@ static void gen_stratum_work(struct pool *pool, struct work *work) @@ -5988,10 +6009,13 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
static void apply_initial_gpu_settings(struct pool *pool)
{
int i;
const char *opt;
unsigned char options; //gpu adl options to apply
unsigned int start_threads = mining_threads, //initial count of mining threads before 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);
//apply gpu settings
rd_lock(&mining_thr_lock);
@ -6001,68 +6025,32 @@ static void apply_initial_gpu_settings(struct pool *pool) @@ -6001,68 +6025,32 @@ static void apply_initial_gpu_settings(struct pool *pool)
devices_enabled[i] = false;
//assign pool devices if any
if(!empty_string(pool->devices))
set_devices((char *)pool->devices);
//assign default devices if any
else if(!empty_string(default_profile.devices))
set_devices((char *)default_profile.devices);
if(!empty_string((opt = get_pool_setting(pool->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all")))))
set_devices((char *)opt);
//lookup gap
if(!empty_string(pool->lookup_gap))
set_lookup_gap((char *)pool->lookup_gap);
else if(!empty_string(default_profile.lookup_gap))
set_lookup_gap((char *)default_profile.lookup_gap);
if(!empty_string((opt = get_pool_setting(pool->lookup_gap, default_profile.lookup_gap))))
set_lookup_gap((char *)opt);
//raw intensity from pool
if (!empty_string(pool->rawintensity))
set_rawintensity(pool->rawintensity);
//raw intensity from default profile
else if(!empty_string(default_profile.rawintensity))
set_rawintensity(default_profile.rawintensity);
//if no rawintensity is set try xintensity
else
{
//xintensity from pool
if (!empty_string(pool->xintensity))
set_xintensity(pool->xintensity);
//xintensity from default profile
else if(!empty_string(default_profile.xintensity))
set_xintensity(default_profile.xintensity);
//no xintensity set try intensity
else
{
//intensity from pool
if(!empty_string(pool->intensity))
set_intensity(pool->intensity);
//intensity from defaults
else if(!empty_string(default_profile.intensity))
set_intensity(default_profile.intensity);
//nothing set anywhere, use 8
else
{
default_profile.intensity = strdup("8");
set_intensity(default_profile.intensity);
}
}
}
//set intensity
if(!empty_string((opt = get_pool_setting(pool->rawintensity, default_profile.rawintensity))))
set_rawintensity((char *)opt);
else if(!empty_string((opt = get_pool_setting(pool->xintensity, default_profile.xintensity))))
set_xintensity((char *)opt);
else if(!empty_string((opt = get_pool_setting(pool->intensity, ((!empty_string(default_profile.intensity))?default_profile.intensity:"8")))))
set_intensity((char *)opt);
//shaders
if (!empty_string(pool->shaders))
set_shaders((char *)pool->shaders);
else if(!empty_string(default_profile.shaders))
set_shaders((char *)default_profile.shaders);
if(!empty_string((opt = get_pool_setting(pool->shaders, default_profile.shaders))))
set_shaders((char *)opt);
//thread-concurrency
if (!empty_string(pool->thread_concurrency))
set_thread_concurrency((char *)pool->thread_concurrency);
else if(!empty_string(default_profile.thread_concurrency))
set_thread_concurrency((char *)default_profile.thread_concurrency);
if(!empty_string((opt = get_pool_setting(pool->thread_concurrency, default_profile.thread_concurrency))))
set_thread_concurrency((char *)opt);
//worksize
if (!empty_string(pool->worksize))
set_worksize((char *)pool->worksize);
else if(!empty_string(default_profile.worksize))
set_worksize((char *)default_profile.worksize);
if(!empty_string((opt = get_pool_setting(pool->worksize, default_profile.worksize))))
set_worksize((char *)opt);
//apply algorithm
for (i = 0; i < nDevs; i++)
@ -6072,42 +6060,32 @@ static void apply_initial_gpu_settings(struct pool *pool) @@ -6072,42 +6060,32 @@ static void apply_initial_gpu_settings(struct pool *pool)
options = APPLY_ENGINE | APPLY_MEMCLOCK | APPLY_FANSPEED | APPLY_POWERTUNE | APPLY_VDDC;
//GPU clock
if(!empty_string(pool->gpu_engine))
set_gpu_engine(pool->gpu_engine);
else if(!empty_string(default_profile.gpu_engine))
set_gpu_engine(default_profile.gpu_engine);
if(!empty_string((opt = get_pool_setting(pool->gpu_engine, default_profile.gpu_engine))))
set_gpu_engine((char *)opt);
else
options ^= APPLY_ENGINE;
//GPU memory clock
if(!empty_string(pool->gpu_memclock))
set_gpu_memclock(pool->gpu_memclock);
else if(!empty_string(default_profile.gpu_memclock))
set_gpu_memclock(default_profile.gpu_memclock);
if(!empty_string((opt = get_pool_setting(pool->gpu_memclock, default_profile.gpu_memclock))))
set_gpu_memclock((char *)opt);
else
options ^= APPLY_MEMCLOCK;
//GPU fans
if(!empty_string(pool->gpu_fan))
set_gpu_fan(pool->gpu_fan);
else if(!empty_string(default_profile.gpu_fan))
set_gpu_fan(default_profile.gpu_fan);
if(!empty_string((opt = get_pool_setting(pool->gpu_fan, default_profile.gpu_fan))))
set_gpu_fan((char *)opt);
else
options ^= APPLY_FANSPEED;
//GPU powertune
if(!empty_string(pool->gpu_powertune))
set_gpu_powertune((char *)pool->gpu_powertune);
else if(!empty_string(default_profile.gpu_powertune))
set_gpu_powertune((char *)default_profile.gpu_powertune);
if(!empty_string((opt = get_pool_setting(pool->gpu_powertune, default_profile.gpu_powertune))))
set_gpu_powertune((char *)opt);
else
options ^= APPLY_POWERTUNE;
//GPU vddc
if(!empty_string(pool->gpu_vddc))
set_gpu_vddc((char *)pool->gpu_vddc);
else if(!empty_string(default_profile.gpu_vddc))
set_gpu_vddc((char *)default_profile.gpu_vddc);
if(!empty_string((opt = get_pool_setting(pool->gpu_vddc, default_profile.gpu_vddc))))
set_gpu_vddc((char *)opt);
else
options ^= APPLY_VDDC;
@ -6160,10 +6138,8 @@ static void apply_initial_gpu_settings(struct pool *pool) @@ -6160,10 +6138,8 @@ static void apply_initial_gpu_settings(struct pool *pool)
//recount the number of needed mining threads
#ifdef HAVE_ADL
if(!empty_string(pool->gpu_threads))
set_gpu_threads(pool->gpu_threads);
else if(!empty_string(default_profile.gpu_threads))
set_gpu_threads(default_profile.gpu_threads);
if(!empty_string((opt = get_pool_setting(pool->gpu_threads, default_profile.gpu_threads))))
set_gpu_threads((char *)opt);
for (i = 0; i < total_devices; i++)
needed_threads += devices[i]->threads;
@ -6181,22 +6157,188 @@ static void apply_initial_gpu_settings(struct pool *pool) @@ -6181,22 +6157,188 @@ static void apply_initial_gpu_settings(struct pool *pool)
restart_mining_threads(needed_threads);
}
static unsigned long compare_pool_settings(struct pool *pool1, struct pool *pool2)
{
unsigned int options = 0;
const char *opt1, *opt2;
if(!pool1 || !pool2)
return 0;
//compare algorithm
if(!cmp_algorithm(&pool1->algorithm, &pool2->algorithm))
options |= (SWITCHER_APPLY_ALGO | SWITCHER_HARD_RESET);
//compare pool devices
opt1 = get_pool_setting(pool1->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all"));
opt2 = get_pool_setting(pool2->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all"));
//changing devices means a hard reset of mining threads
if(strcasecmp(opt1, opt2) != 0)
options |= (SWITCHER_APPLY_DEVICE | SWITCHER_HARD_RESET);
//compare gpu threads
opt1 = get_pool_setting(pool1->gpu_threads, default_profile.gpu_threads);
opt2 = get_pool_setting(pool2->gpu_threads, default_profile.gpu_threads);
//changing gpu threads means a hard reset of mining threads
if(strcasecmp(opt1, opt2) != 0)
options |= (SWITCHER_APPLY_GT | SWITCHER_HARD_RESET);
//lookup gap
opt1 = get_pool_setting(pool1->lookup_gap, default_profile.lookup_gap);
opt2 = get_pool_setting(pool2->lookup_gap, default_profile.lookup_gap);
//lookup gap means soft reset but only if hard reset isnt set
if(strcasecmp(opt1, opt2) != 0)
options |= (SWITCHER_APPLY_LG | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
//intensities
opt1 = get_pool_setting(pool1->rawintensity, default_profile.rawintensity);
opt2 = get_pool_setting(pool2->rawintensity, default_profile.rawintensity);
if(strcasecmp(opt1, opt2) != 0)
{
//intensity is soft reset
if(!empty_string(opt2))
options |= (SWITCHER_APPLY_RAWINT | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
}
//xintensity -- only if raw intensity not set
if(!opt_isset(options, SWITCHER_APPLY_RAWINT))
{
opt1 = get_pool_setting(pool1->xintensity, default_profile.xintensity);
opt2 = get_pool_setting(pool2->xintensity, default_profile.xintensity);
//if different...
if(strcasecmp(opt1, opt2) != 0)
{
//intensity is soft reset
if(!empty_string(opt2))
options |= (SWITCHER_APPLY_XINT | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
}
}
//intensity -- only if raw intensity and xintensity not set
if(!opt_isset(options, SWITCHER_APPLY_RAWINT) && !opt_isset(options, SWITCHER_APPLY_XINT))
{
opt1 = get_pool_setting(pool1->intensity, default_profile.intensity);
opt2 = get_pool_setting(pool2->intensity, default_profile.intensity);
//if different...
if(strcasecmp(opt1, opt2) != 0)
{
//intensity is soft reset
if(!empty_string(opt2))
options |= (SWITCHER_APPLY_INT | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
//if blank, set default profile to intensity 8 and apply
else
options |= (SWITCHER_APPLY_INT8 | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
}
}
//shaders
opt1 = get_pool_setting(pool1->shaders, default_profile.shaders);
opt2 = get_pool_setting(pool2->shaders, default_profile.shaders);
if(strcasecmp(opt1, opt2) != 0)
{
//shaders is soft reset
if(!empty_string(opt2))
options |= (SWITCHER_APPLY_SHADER | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
}
//thread-concurrency
opt1 = get_pool_setting(pool1->thread_concurrency, default_profile.thread_concurrency);
opt2 = get_pool_setting(pool2->thread_concurrency, default_profile.thread_concurrency);
//thread-concurrency is soft reset
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= (SWITCHER_APPLY_TC | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
//worksize
opt1 = get_pool_setting(pool1->worksize, default_profile.worksize);
opt2 = get_pool_setting(pool2->worksize, default_profile.worksize);
//worksize is soft reset
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= (SWITCHER_APPLY_WORKSIZE | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
#ifdef HAVE_ADL
//gpu-engine
opt1 = get_pool_setting(pool1->gpu_engine, default_profile.gpu_engine);
opt2 = get_pool_setting(pool2->gpu_engine, default_profile.gpu_engine);
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= SWITCHER_APPLY_GPU_ENGINE;
//gpu-memclock
opt1 = get_pool_setting(pool1->gpu_memclock, default_profile.gpu_memclock);
opt2 = get_pool_setting(pool2->gpu_memclock, default_profile.gpu_memclock);
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= SWITCHER_APPLY_GPU_MEMCLOCK;
//GPU fans
opt1 = get_pool_setting(pool1->gpu_fan, default_profile.gpu_fan);
opt2 = get_pool_setting(pool2->gpu_fan, default_profile.gpu_fan);
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= SWITCHER_APPLY_GPU_FAN;
//GPU powertune
opt1 = get_pool_setting(pool1->gpu_powertune, default_profile.gpu_powertune);
opt2 = get_pool_setting(pool2->gpu_powertune, default_profile.gpu_powertune);
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= SWITCHER_APPLY_GPU_POWERTUNE;
//GPU vddc
opt1 = get_pool_setting(pool1->gpu_vddc, default_profile.gpu_vddc);
opt2 = get_pool_setting(pool2->gpu_vddc, default_profile.gpu_vddc);
if(strcasecmp(opt1, opt2) != 0 && !empty_string(opt2))
options |= SWITCHER_APPLY_GPU_VDDC;
#endif
return options;
}
static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{
int i;
int active_threads; //number of actual active threads
int start_threads; //number of threads at start before devices enabled change
unsigned char options; //gpu adl options to apply
unsigned long options;
const char *opt;
//if switcher is disabled
if(opt_switchmode == SWITCH_OFF)
return;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
mutex_lock(&algo_switch_lock);
if (cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm) && (algo_switch_n == 0))
//switcher mode - switch on algorithm change
if(opt_switchmode == SWITCH_ALGO)
{
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;
}
}
//switcher mode - switch on pool change
else if(opt_switchmode == SWITCH_POOL)
{
if((work->pool->pool_no == mythr->pool_no) && (algo_switch_n == 0))
{
mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
return;
}
}
algo_switch_n++;
@ -6207,19 +6349,23 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6207,19 +6349,23 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
struct thr_info *thr = mining_thr[i];
if(thr->cgpu->deven != DEV_DISABLED)
active_threads ++;
active_threads++;
}
// 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
bool soft_restart = !work->pool->gpu_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);
// Shutdown all threads first (necessary)
if (soft_restart)
if(opt_isset(options, SWITCHER_SOFT_RESET))
{
applog(LOG_DEBUG, "Soft Reset... Shutdown threads...");
for (i = 0; i < start_threads; i++)
{
struct thr_info *thr = mining_thr[i];
@ -6230,142 +6376,143 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6230,142 +6376,143 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
// Reset stats (e.g. for working_diff to be set properly in hash_sole_work)
zero_stats();
// Apply other pool-specific settings or revert to defaults
//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;
//assign pool devices if any
if(!empty_string(work->pool->devices))
set_devices((char *)work->pool->devices);
//assign default devices if any
else if(!empty_string(default_profile.devices))
set_devices((char *)default_profile.devices);
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(!empty_string(work->pool->lookup_gap))
set_lookup_gap((char *)work->pool->lookup_gap);
else if(!empty_string(default_profile.lookup_gap))
set_lookup_gap((char *)default_profile.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);
}
//raw intensity from pool
if (!empty_string(work->pool->rawintensity))
set_rawintensity(work->pool->rawintensity);
//raw intensity from default profile
else if(!empty_string(default_profile.rawintensity))
set_rawintensity(default_profile.rawintensity);
//if no rawintensity is set try xintensity
else
if(opt_isset(options, SWITCHER_APPLY_RAWINT))
{
//xintensity from pool
if (!empty_string(work->pool->xintensity))
set_xintensity(work->pool->xintensity);
//xintensity from default profile
else if(!empty_string(default_profile.xintensity))
set_xintensity(default_profile.xintensity);
//no xintensity set try intensity
else
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))
{
//intensity from pool
if(!empty_string(work->pool->intensity))
set_intensity(work->pool->intensity);
//intensity from defaults
else if(!empty_string(default_profile.intensity))
set_intensity(default_profile.intensity);
//nothing set anywhere, use 8
else
if(!empty_string((opt = get_pool_setting(work->pool->xintensity, default_profile.xintensity))))
set_xintensity((char *)opt);
}
//intensity
else if(opt_isset(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(options, SWITCHER_APPLY_INT8))
{
default_profile.intensity = strdup("8");
set_intensity(default_profile.intensity);
}
}
}
//shaders
if (!empty_string(work->pool->shaders))
set_shaders((char *)work->pool->shaders);
else if(!empty_string(default_profile.shaders))
set_shaders((char *)default_profile.shaders);
if(opt_isset(options, SWITCHER_APPLY_SHADER))
{
if(!empty_string((opt = get_pool_setting(work->pool->shaders, default_profile.shaders))))
set_shaders((char *)opt);
}
//thread-concurrency
if (!empty_string(work->pool->thread_concurrency))
set_thread_concurrency((char *)work->pool->thread_concurrency);
else if(!empty_string(default_profile.thread_concurrency))
set_thread_concurrency((char *)default_profile.thread_concurrency);
if(opt_isset(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 (!empty_string(work->pool->worksize))
set_worksize((char *)work->pool->worksize);
else if(!empty_string(default_profile.worksize))
set_worksize((char *)default_profile.worksize);
if(opt_isset(options, SWITCHER_APPLY_WORKSIZE))
{
if(!empty_string((opt = get_pool_setting(work->pool->worksize, default_profile.worksize))))
set_worksize((char *)opt);
}
#ifdef HAVE_ADL
options = APPLY_ENGINE | APPLY_MEMCLOCK | APPLY_FANSPEED | APPLY_POWERTUNE | APPLY_VDDC;
//apply algorithm
if(opt_isset(options, SWITCHER_APPLY_ALGO))
{
for (i = 0; i < nDevs; i++)
gpus[i].algorithm = work->pool->algorithm;
}
#ifdef HAVE_ADL
//GPU clock
if(!empty_string(work->pool->gpu_engine))
set_gpu_engine(work->pool->gpu_engine);
else if(!empty_string(default_profile.gpu_engine))
set_gpu_engine(default_profile.gpu_engine);
else
options ^= APPLY_ENGINE;
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);
}
//GPU memory clock
if(!empty_string(work->pool->gpu_memclock))
set_gpu_memclock(work->pool->gpu_memclock);
else if(!empty_string(default_profile.gpu_memclock))
set_gpu_memclock(default_profile.gpu_memclock);
else
options ^= APPLY_MEMCLOCK;
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);
}
//GPU fans
if(!empty_string(work->pool->gpu_fan))
set_gpu_fan(work->pool->gpu_fan);
else if(!empty_string(default_profile.gpu_fan))
set_gpu_fan(default_profile.gpu_fan);
else
options ^= APPLY_FANSPEED;
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);
}
//GPU powertune
if(!empty_string(work->pool->gpu_powertune))
set_gpu_powertune((char *)work->pool->gpu_powertune);
else if(!empty_string(default_profile.gpu_powertune))
set_gpu_powertune((char *)default_profile.gpu_powertune);
else
options ^= APPLY_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);
}
//GPU vddc
if(!empty_string(work->pool->gpu_vddc))
set_gpu_vddc((char *)work->pool->gpu_vddc);
else if(!empty_string(default_profile.gpu_vddc))
set_gpu_vddc((char *)default_profile.gpu_vddc);
else
options ^= APPLY_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);
}
//apply gpu settings
for (i = 0; i < nDevs; i++)
{
if(opt_isset(options, APPLY_ENGINE))
if(opt_isset(options, SWITCHER_APPLY_GPU_ENGINE))
set_engineclock(i, gpus[i].min_engine);
if(opt_isset(options, APPLY_MEMCLOCK))
if(opt_isset(options, SWITCHER_APPLY_GPU_MEMCLOCK))
set_memoryclock(i, gpus[i].gpu_memclock);
if(opt_isset(options, APPLY_FANSPEED))
if(opt_isset(options, SWITCHER_APPLY_GPU_FAN))
set_fanspeed(i, gpus[i].min_fan);
if(opt_isset(options, APPLY_POWERTUNE))
if(opt_isset(options, SWITCHER_APPLY_GPU_POWERTUNE))
set_powertune(i, gpus[i].gpu_powertune);
if(opt_isset(options, APPLY_VDDC))
if(opt_isset(options, SWITCHER_APPLY_GPU_VDDC))
set_vddc(i, gpus[i].gpu_vddc);
}
#endif
// Change algorithm for each thread (thread_prepare calls initCl)
if(opt_isset(options, SWITCHER_SOFT_RESET))
{
struct thr_info *thr;
applog(LOG_DEBUG, "Soft Reset... Restarting threads...");
for (i = 0; i < start_threads; i++)
{
struct thr_info *thr = mining_thr[i];
thr->cgpu->algorithm = work->pool->algorithm;
if (soft_restart)
thr = mining_thr[i];
thr->pool_no = work->pool->pool_no; //set thread on new pool
if(opt_isset(options, SWITCHER_SOFT_RESET))
{
thr->cgpu->drv->thread_prepare(thr);
thr->cgpu->drv->thread_init(thr);
@ -6374,6 +6521,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6374,6 +6521,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
// Necessary because algorithms can have dramatically different diffs
thr->cgpu->drv->working_diff = 1;
}
}
rd_unlock(&mining_thr_lock);
@ -6381,10 +6529,15 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6381,10 +6529,15 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
algo_switch_n = 0;
mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
// Hard restart (when gpu_threads is changed)
if (!soft_restart)
// Hard restart if needed
if(opt_isset(options, SWITCHER_HARD_RESET))
{
applog(LOG_DEBUG, "Hard Reset Mining Threads...");
//if devices changed... enable/disable as needed
if(opt_isset(options, SWITCHER_APPLY_DEVICE))
{
//enable/disable devices based on profile/pool/defaults
sgminer_id_count = 0; //reset sgminer_ids
mining_threads = 0; //mining threads gets added inside each enable_device() so reset
if(opt_devs_enabled)
@ -6393,13 +6546,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6393,13 +6546,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{
//device should be enabled
if(devices_enabled[i] && i < total_devices)
{
applog(LOG_DEBUG, "Enabling device %d", i);
enable_device(devices[i]);
}
else if(i < total_devices)
{
applog(LOG_DEBUG, "Disabling device %d", i);
//if option is set to not remove disabled, enable device
if(!opt_removedisabled)
enable_device(devices[i]);
@ -6415,18 +6564,21 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6415,18 +6564,21 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
for (i = 0; i < total_devices; ++i)
enable_device(devices[i]);
}
}
//devices reset - assign gpu-threads as needed
//figure out how many mining threads we'll need
unsigned int n_threads = 0;
pthread_t restart_thr;
#ifdef HAVE_ADL
if(!empty_string(work->pool->gpu_threads))
set_gpu_threads(work->pool->gpu_threads);
else if(!empty_string(default_profile.gpu_threads))
set_gpu_threads(default_profile.gpu_threads);
//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);
}
for (i = 0; i < total_devices; ++i)
for (i = 0; i < total_devices; i++)
n_threads += devices[i]->threads;
#else
n_threads = mining_threads;
@ -6455,6 +6607,22 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work) @@ -6455,6 +6607,22 @@ 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");
}
}
//nothing changed... new pool uses same settings
else
{
//apply new pool_no to all mining threads
for (i = 0; i < start_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
mutex_lock(&algo_switch_wait_lock);
pthread_cond_broadcast(&algo_switch_wait_cond);
@ -7942,13 +8110,16 @@ static void restart_mining_threads(unsigned int new_n_threads) @@ -7942,13 +8110,16 @@ static void restart_mining_threads(unsigned int new_n_threads)
unsigned int i, j, k;
// Stop and free threads
if (mining_thr) {
if (mining_thr)
{
rd_lock(&mining_thr_lock);
for (i = 0; i < mining_threads; i++) {
for (i = 0; i < mining_threads; i++)
{
applog(LOG_DEBUG, "Shutting down thread %d", i);
mining_thr[i]->cgpu->shutdown = true;
}
rd_unlock(&mining_thr_lock);
// kill_mining will rd lock mining_thr_lock
kill_mining();
rd_lock(&mining_thr_lock);
@ -7963,13 +8134,16 @@ static void restart_mining_threads(unsigned int new_n_threads) @@ -7963,13 +8134,16 @@ static void restart_mining_threads(unsigned int new_n_threads)
wr_lock(&mining_thr_lock);
if (mining_thr) {
for (i = 0; i < total_devices; ++i) {
if (mining_thr)
{
for (i = 0; i < total_devices; i++) {
free(devices[i]->thr);
}
for (i = 0; i < mining_threads; i++) {
free(mining_thr[i]);
}
free(mining_thr);
}
@ -7988,7 +8162,10 @@ static void restart_mining_threads(unsigned int new_n_threads) @@ -7988,7 +8162,10 @@ static void restart_mining_threads(unsigned int new_n_threads)
}
rd_lock(&devices_lock);
// Start threads
struct pool *pool = current_pool();
k = 0;
for (i = 0; i < total_devices; ++i) {
struct cgpu_info *cgpu = devices[i];
@ -7996,9 +8173,11 @@ static void restart_mining_threads(unsigned int new_n_threads) @@ -7996,9 +8173,11 @@ static void restart_mining_threads(unsigned int new_n_threads)
cgpu->thr[cgpu->threads] = NULL;
cgpu->status = LIFE_INIT;
for (j = 0; j < cgpu->threads; ++j, ++k) {
for (j = 0; j < cgpu->threads; ++j, ++k)
{
thr = mining_thr[k];
thr->id = k;
thr->pool_no = pool->pool_no;
thr->cgpu = cgpu;
thr->device_thread = j;

Loading…
Cancel
Save