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 11 years ago
parent
commit
3ae5f97b94
  1. 69
      algorithm.c
  2. 16
      algorithm.h
  3. 12
      api.c
  4. 26
      config_parser.c
  5. 1
      driver-opencl.c
  6. 37
      miner.h
  7. 599
      sgminer.c

69
algorithm.c

@ -31,6 +31,21 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.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) void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
{ {
sph_sha256_context ctx_sha2; sph_sha256_context ctx_sha2;
@ -308,6 +323,7 @@ static cl_int queue_talkcoin_mod_kernel(struct __clState *clState, struct _dev_b
typedef struct _algorithm_settings_t { typedef struct _algorithm_settings_t {
const char *name; /* Human-readable identifier */ const char *name; /* Human-readable identifier */
algorithm_type_t type; //common algorithm type
double diff_multiplier1; double diff_multiplier1;
double diff_multiplier2; double diff_multiplier2;
double share_diff_multiplier; double share_diff_multiplier;
@ -329,7 +345,7 @@ typedef struct _algorithm_settings_t {
static algorithm_settings_t algos[] = { static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using litecoin algorithm // kernels starting from this will have difficulty calculated by using litecoin algorithm
#define A_SCRYPT(a) \ #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( "ckolivas" ),
A_SCRYPT( "alexkarnew" ), A_SCRYPT( "alexkarnew" ),
A_SCRYPT( "alexkarnold" ), A_SCRYPT( "alexkarnold" ),
@ -340,7 +356,7 @@ static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using quarkcoin algorithm // kernels starting from this will have difficulty calculated by using quarkcoin algorithm
#define A_QUARK(a, b) \ #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( "quarkcoin", quarkcoin_regenhash),
A_QUARK( "qubitcoin", qubitcoin_regenhash), A_QUARK( "qubitcoin", qubitcoin_regenhash),
A_QUARK( "animecoin", animecoin_regenhash), A_QUARK( "animecoin", animecoin_regenhash),
@ -349,31 +365,31 @@ static algorithm_settings_t algos[] = {
// kernels starting from this will have difficulty calculated by using bitcoin algorithm // kernels starting from this will have difficulty calculated by using bitcoin algorithm
#define A_DARK(a, b) \ #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( "darkcoin", darkcoin_regenhash),
A_DARK( "inkcoin", inkcoin_regenhash), A_DARK( "inkcoin", inkcoin_regenhash),
A_DARK( "myriadcoin-groestl", myriadcoin_groestl_regenhash), A_DARK( "myriadcoin-groestl", myriadcoin_groestl_regenhash),
#undef A_DARK #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}, { "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", 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}, { "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", 1, 1, 1, 0, 0, 0xFF, 0x00000000ffff0000ULL, 0xFFFFULL, 0x0000ffffUL, 10, 8 * 16 * 4194304, 0, darkcoin_regenhash, queue_darkcoin_mod_kernel, gen_hash, 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", 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", 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-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", 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-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 // kernels starting from this will have difficulty calculated by using fuguecoin algorithm
#define A_FUGUE(a, b) \ #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( "fuguecoin", fuguecoin_regenhash),
A_FUGUE( "groestlcoin", groestlcoin_regenhash), A_FUGUE( "groestlcoin", groestlcoin_regenhash),
#undef A_FUGUE #undef A_FUGUE
// Terminator (do not remove) // 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) 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; algorithm_settings_t* src;
// Find algorithm settings and copy // Find algorithm settings and copy
for (src = algos; src->name; src++) { for (src = algos; src->name; src++)
if (strcmp(src->name, algo) == 0) { {
if (strcmp(src->name, algo) == 0)
{
strcpy(dest->name, src->name); strcpy(dest->name, src->name);
dest->type = src->type;
dest->diff_multiplier1 = src->diff_multiplier1; dest->diff_multiplier1 = src->diff_multiplier1;
dest->diff_multiplier2 = src->diff_multiplier2; dest->diff_multiplier2 = src->diff_multiplier2;
@ -406,7 +425,8 @@ void copy_algorithm_settings(algorithm_t* dest, const char* algo)
} }
// if not found // if not found
if (src->name == NULL) { if (src->name == NULL)
{
applog(LOG_WARNING, "Algorithm %s not found, using %s.", algo, algos->name); applog(LOG_WARNING, "Algorithm %s not found, using %s.", algo, algos->name);
copy_algorithm_settings(dest, algos->name); copy_algorithm_settings(dest, algos->name);
} }
@ -457,6 +477,25 @@ void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor)
{ {
algo->nfactor = nfactor; algo->nfactor = nfactor;
algo->n = (1 << 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) bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2)

16
algorithm.h

@ -10,6 +10,21 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.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); extern void gen_hash(const unsigned char *data, unsigned int len, unsigned char *hash);
struct __clState; struct __clState;
@ -23,6 +38,7 @@ struct work;
*/ */
typedef struct _algorithm_t { typedef struct _algorithm_t {
char name[20]; /* Human-readable identifier */ char name[20]; /* Human-readable identifier */
algorithm_type_t type; //algorithm type
uint32_t n; /* N (CPU/Memory tradeoff parameter) */ uint32_t n; /* N (CPU/Memory tradeoff parameter) */
uint8_t nfactor; /* Factor of N above (n = 2^nfactor) */ uint8_t nfactor; /* Factor of N above (n = 2^nfactor) */
double diff_multiplier1; double diff_multiplier1;

12
api.c

@ -31,6 +31,7 @@
#include "pool.h" #include "pool.h"
#include "util.h" #include "util.h"
#include "pool.h" #include "pool.h"
#include "algorithm.h"
#include "config_parser.h" #include "config_parser.h"
@ -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); root = api_add_string(root, "Name", get_pool_name(pool), true);
mutex_unlock(&pool->stratum_lock); mutex_unlock(&pool->stratum_lock);
root = api_add_escape(root, "URL", pool->rpc_url, false); root = api_add_escape(root, "URL", pool->rpc_url, false);
root = api_add_string(root, "Profile", pool->profile, false); root = api_add_escape(root, "Profile", pool->profile, false);
root = api_add_string(root, "Algorithm", pool->algorithm.name, 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, "Description", pool->description, false);
root = api_add_string(root, "Status", status, false); root = api_add_string(root, "Status", status, false);
root = api_add_int(root, "Priority", &(pool->prio), 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
root = api_add_escape(root, "User", pool->rpc_user, false); 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_time(root, "Last Share Time", &(pool->last_share_time), false);
root = api_add_double(root, "Diff1 Shares", &(pool->diff1), false); root = api_add_double(root, "Diff1 Shares", &(pool->diff1), false);
if (pool->rpc_proxy) { if (pool->rpc_proxy) {
root = api_add_const(root, "Proxy Type", proxytype(pool->rpc_proxytype), false); root = api_add_const(root, "Proxy Type", proxytype(pool->rpc_proxytype), false);
root = api_add_escape(root, "Proxy", pool->rpc_proxy, false); root = api_add_escape(root, "Proxy", pool->rpc_proxy, false);

26
config_parser.c

@ -499,7 +499,8 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int
{ {
//char *err = NULL; //char *err = NULL;
const char *key; const char *key;
json_t *val; size_t idx;
json_t *val, *subval;
json_object_foreach(obj, key, val) json_object_foreach(obj, key, val)
{ {
@ -509,6 +510,18 @@ void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int
if(val && json_is_string(val)) if(val && json_is_string(val))
load_config(json_string_value(val), parentkey, NULL); 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 else
parse_config(val, key, parentkey, fileconf, parent_iteration); parse_config(val, key, parentkey, fileconf, parent_iteration);
/* /*
@ -689,7 +702,7 @@ void load_default_profile()
// ... and copy settings // ... and copy settings
if(!empty_string(profile->algorithm.name)) if(!empty_string(profile->algorithm.name))
set_algorithm(&default_profile.algorithm, profile->algorithm.name); default_profile.algorithm = profile->algorithm;
if(!empty_string(profile->devices)) if(!empty_string(profile->devices))
default_profile.devices = profile->devices; default_profile.devices = profile->devices;
@ -745,6 +758,8 @@ void apply_defaults()
//by default all unless specified //by default all unless specified
if(empty_string(default_profile.devices)) if(empty_string(default_profile.devices))
default_profile.devices = strdup("all"); default_profile.devices = strdup("all");
applog(LOG_DEBUG, "Default Devices = %s", default_profile.devices);
set_devices((char *)default_profile.devices); set_devices((char *)default_profile.devices);
//set raw intensity first //set raw intensity first
@ -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_escape(root, "Name", profile->name, true);
root = api_add_bool(root, "IsDefault", &b, false); root = api_add_bool(root, "IsDefault", &b, false);
root = api_add_escape(root, "Algorithm", isnull((char *)profile->algorithm.name, ""), true); 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, "LookupGap", isnull((char *)profile->lookup_gap, ""), true);
root = api_add_escape(root, "Devices", isnull((char *)profile->devices, ""), true); root = api_add_escape(root, "Devices", isnull((char *)profile->devices, ""), true);
root = api_add_escape(root, "Intensity", isnull((char *)profile->intensity, ""), 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)
static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work) static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work)
{ {
work->blk.work = work; work->blk.work = work;
thr->pool_no = work->pool->pool_no;
return true; return true;
} }

37
miner.h

@ -321,9 +321,45 @@ struct gpu_adl {
}; };
#endif #endif
/***********************************
* Switcher stuff
****************************************/
#ifndef opt_isset #ifndef opt_isset
#define opt_isset(opt, val) (((opt & val) == val)?1:0) #define opt_isset(opt, val) (((opt & val) == val)?1:0)
#endif #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 { enum gpu_adl_options {
APPLY_ENGINE = 1, APPLY_ENGINE = 1,
@ -572,6 +608,7 @@ struct thr_info {
struct thread_q *q; struct thread_q *q;
struct cgpu_info *cgpu; struct cgpu_info *cgpu;
void *cgpu_data; void *cgpu_data;
int pool_no;
struct timeval last; struct timeval last;
struct timeval sick; struct timeval sick;

599
sgminer.c

@ -332,6 +332,9 @@ enum pool_strategy pool_strategy = POOL_FAILOVER;
int opt_rotate_period; int opt_rotate_period;
static int total_urls; static int total_urls;
//default mode apply algorithm/gpu settings when pool changes
int opt_switchmode = SWITCH_POOL;
static static
#ifndef HAVE_CURSES #ifndef HAVE_CURSES
const const
@ -730,17 +733,17 @@ void get_intrange(char *arg, int *val1, int *val2)
char *set_devices(char *arg) char *set_devices(char *arg)
{ {
int i, val1 = 0, val2 = 0; 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; opt_display_devs = true;
return NULL; return NULL;
} }
//all devices enabled //all devices enabled
else if(*arg == '*' || !strcasecmp(arg, "all")) else if(!strcasecmp(arg, "*") || !strcasecmp(arg, "all"))
{ {
applog(LOG_DEBUG, "set_devices(all)"); applog(LOG_DEBUG, "set_devices(all)");
opt_devs_enabled = 0; opt_devs_enabled = 0;
@ -752,33 +755,33 @@ char *set_devices(char *arg)
applog(LOG_DEBUG, "set_devices(%s)", arg); applog(LOG_DEBUG, "set_devices(%s)", arg);
nextptr = strtok(arg, ","); p = strdup(arg);
nextptr = strtok(p, ",");
do {
if (nextptr == NULL) if (nextptr == NULL)
{
free(p);
return "Invalid parameters for set devices"; 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); 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"; return "Invalid value passed to set devices";
} }
for (i = val1; i <= val2; i++) { for (i = val1; i <= val2; i++)
{
devices_enabled[i] = true; devices_enabled[i] = true;
opt_devs_enabled++; opt_devs_enabled++;
} }
} } while ((nextptr = strtok(NULL, ",")) != NULL);
applog(LOG_DEBUG, "set_devices(%s) done.", arg);
free(p);
return NULL; return NULL;
} }
@ -1074,6 +1077,21 @@ static char *set_pool_state(char *arg)
return NULL; 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) static char *set_quota(char *arg)
{ {
char *semicolon = strchr(arg, ';'), *url; char *semicolon = strchr(arg, ';'), *url;
@ -1320,7 +1338,7 @@ char *set_difficulty_multiplier(char *arg)
/* These options are available from config file or commandline */ /* These options are available from config file or commandline */
struct opt_table opt_config_table[] = { struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--algorithm", OPT_WITH_ARG("--algorithm|--kernel|-k",
set_default_algorithm, NULL, NULL, set_default_algorithm, NULL, NULL,
"Set mining algorithm and most common defaults, default: scrypt"), "Set mining algorithm and most common defaults, default: scrypt"),
OPT_WITH_ARG("--api-allow", OPT_WITH_ARG("--api-allow",
@ -1542,7 +1560,7 @@ struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--poolname", /* TODO: Backward compatibility, to be removed. */ OPT_WITH_ARG("--poolname", /* TODO: Backward compatibility, to be removed. */
set_poolname_deprecated, NULL, NULL, set_poolname_deprecated, NULL, NULL,
opt_hidden), opt_hidden),
OPT_WITH_ARG("--pool-algorithm", OPT_WITH_ARG("--pool-algorithm|--pool-kernel",
set_pool_algorithm, NULL, NULL, set_pool_algorithm, NULL, NULL,
"Set algorithm for pool"), "Set algorithm for pool"),
OPT_WITH_ARG("--pool-device", OPT_WITH_ARG("--pool-device",
@ -1600,7 +1618,7 @@ struct opt_table opt_config_table[] = {
set_pool_priority, NULL, NULL, set_pool_priority, NULL, NULL,
"Pool priority"), "Pool priority"),
OPT_WITH_ARG("--profile-algorithm", OPT_WITH_ARG("--profile-algorithm|--profile-kernel",
set_profile_algorithm, NULL, NULL, set_profile_algorithm, NULL, NULL,
"Set algorithm for profile"), "Set algorithm for profile"),
OPT_WITH_ARG("--profile-device", OPT_WITH_ARG("--profile-device",
@ -1711,6 +1729,9 @@ struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--state|--pool-state", OPT_WITH_ARG("--state|--pool-state",
set_pool_state, NULL, NULL, set_pool_state, NULL, NULL,
"Specify pool state at startup (default: enabled)"), "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 #ifdef HAVE_SYSLOG_H
OPT_WITHOUT_ARG("--syslog", OPT_WITHOUT_ARG("--syslog",
opt_set_bool, &use_syslog, opt_set_bool, &use_syslog,
@ -5988,10 +6009,13 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
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;
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 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 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 //apply gpu settings
rd_lock(&mining_thr_lock); rd_lock(&mining_thr_lock);
@ -6001,68 +6025,32 @@ static void apply_initial_gpu_settings(struct pool *pool)
devices_enabled[i] = false; devices_enabled[i] = false;
//assign pool devices if any //assign pool devices if any
if(!empty_string(pool->devices)) if(!empty_string((opt = get_pool_setting(pool->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all")))))
set_devices((char *)pool->devices); set_devices((char *)opt);
//assign default devices if any
else if(!empty_string(default_profile.devices))
set_devices((char *)default_profile.devices);
//lookup gap //lookup gap
if(!empty_string(pool->lookup_gap)) if(!empty_string((opt = get_pool_setting(pool->lookup_gap, default_profile.lookup_gap))))
set_lookup_gap((char *)pool->lookup_gap); set_lookup_gap((char *)opt);
else if(!empty_string(default_profile.lookup_gap))
set_lookup_gap((char *)default_profile.lookup_gap);
//raw intensity from pool //set intensity
if (!empty_string(pool->rawintensity)) if(!empty_string((opt = get_pool_setting(pool->rawintensity, default_profile.rawintensity))))
set_rawintensity(pool->rawintensity); set_rawintensity((char *)opt);
//raw intensity from default profile else if(!empty_string((opt = get_pool_setting(pool->xintensity, default_profile.xintensity))))
else if(!empty_string(default_profile.rawintensity)) set_xintensity((char *)opt);
set_rawintensity(default_profile.rawintensity); else if(!empty_string((opt = get_pool_setting(pool->intensity, ((!empty_string(default_profile.intensity))?default_profile.intensity:"8")))))
//if no rawintensity is set try xintensity set_intensity((char *)opt);
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);
}
}
}
//shaders //shaders
if (!empty_string(pool->shaders)) if(!empty_string((opt = get_pool_setting(pool->shaders, default_profile.shaders))))
set_shaders((char *)pool->shaders); set_shaders((char *)opt);
else if(!empty_string(default_profile.shaders))
set_shaders((char *)default_profile.shaders);
//thread-concurrency //thread-concurrency
if (!empty_string(pool->thread_concurrency)) if(!empty_string((opt = get_pool_setting(pool->thread_concurrency, default_profile.thread_concurrency))))
set_thread_concurrency((char *)pool->thread_concurrency); set_thread_concurrency((char *)opt);
else if(!empty_string(default_profile.thread_concurrency))
set_thread_concurrency((char *)default_profile.thread_concurrency);
//worksize //worksize
if (!empty_string(pool->worksize)) if(!empty_string((opt = get_pool_setting(pool->worksize, default_profile.worksize))))
set_worksize((char *)pool->worksize); set_worksize((char *)opt);
else if(!empty_string(default_profile.worksize))
set_worksize((char *)default_profile.worksize);
//apply algorithm //apply algorithm
for (i = 0; i < nDevs; i++) for (i = 0; i < nDevs; i++)
@ -6072,42 +6060,32 @@ static void apply_initial_gpu_settings(struct pool *pool)
options = APPLY_ENGINE | APPLY_MEMCLOCK | APPLY_FANSPEED | APPLY_POWERTUNE | APPLY_VDDC; options = APPLY_ENGINE | APPLY_MEMCLOCK | APPLY_FANSPEED | APPLY_POWERTUNE | APPLY_VDDC;
//GPU clock //GPU clock
if(!empty_string(pool->gpu_engine)) if(!empty_string((opt = get_pool_setting(pool->gpu_engine, default_profile.gpu_engine))))
set_gpu_engine(pool->gpu_engine); set_gpu_engine((char *)opt);
else if(!empty_string(default_profile.gpu_engine))
set_gpu_engine(default_profile.gpu_engine);
else else
options ^= APPLY_ENGINE; options ^= APPLY_ENGINE;
//GPU memory clock //GPU memory clock
if(!empty_string(pool->gpu_memclock)) if(!empty_string((opt = get_pool_setting(pool->gpu_memclock, default_profile.gpu_memclock))))
set_gpu_memclock(pool->gpu_memclock); set_gpu_memclock((char *)opt);
else if(!empty_string(default_profile.gpu_memclock))
set_gpu_memclock(default_profile.gpu_memclock);
else else
options ^= APPLY_MEMCLOCK; options ^= APPLY_MEMCLOCK;
//GPU fans //GPU fans
if(!empty_string(pool->gpu_fan)) if(!empty_string((opt = get_pool_setting(pool->gpu_fan, default_profile.gpu_fan))))
set_gpu_fan(pool->gpu_fan); set_gpu_fan((char *)opt);
else if(!empty_string(default_profile.gpu_fan))
set_gpu_fan(default_profile.gpu_fan);
else else
options ^= APPLY_FANSPEED; options ^= APPLY_FANSPEED;
//GPU powertune //GPU powertune
if(!empty_string(pool->gpu_powertune)) if(!empty_string((opt = get_pool_setting(pool->gpu_powertune, default_profile.gpu_powertune))))
set_gpu_powertune((char *)pool->gpu_powertune); set_gpu_powertune((char *)opt);
else if(!empty_string(default_profile.gpu_powertune))
set_gpu_powertune((char *)default_profile.gpu_powertune);
else else
options ^= APPLY_POWERTUNE; options ^= APPLY_POWERTUNE;
//GPU vddc //GPU vddc
if(!empty_string(pool->gpu_vddc)) if(!empty_string((opt = get_pool_setting(pool->gpu_vddc, default_profile.gpu_vddc))))
set_gpu_vddc((char *)pool->gpu_vddc); set_gpu_vddc((char *)opt);
else if(!empty_string(default_profile.gpu_vddc))
set_gpu_vddc((char *)default_profile.gpu_vddc);
else else
options ^= APPLY_VDDC; options ^= APPLY_VDDC;
@ -6160,10 +6138,8 @@ static void apply_initial_gpu_settings(struct pool *pool)
//recount the number of needed mining threads //recount the number of needed mining threads
#ifdef HAVE_ADL #ifdef HAVE_ADL
if(!empty_string(pool->gpu_threads)) if(!empty_string((opt = get_pool_setting(pool->gpu_threads, default_profile.gpu_threads))))
set_gpu_threads(pool->gpu_threads); set_gpu_threads((char *)opt);
else if(!empty_string(default_profile.gpu_threads))
set_gpu_threads(default_profile.gpu_threads);
for (i = 0; i < total_devices; i++) for (i = 0; i < total_devices; i++)
needed_threads += devices[i]->threads; needed_threads += devices[i]->threads;
@ -6181,22 +6157,188 @@ static void apply_initial_gpu_settings(struct pool *pool)
restart_mining_threads(needed_threads); 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) 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 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); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
mutex_lock(&algo_switch_lock); mutex_lock(&algo_switch_lock);
//switcher mode - switch on algorithm change
if(opt_switchmode == SWITCH_ALGO)
{
if(cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm) && (algo_switch_n == 0)) if(cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm) && (algo_switch_n == 0))
{ {
mutex_unlock(&algo_switch_lock); mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
return; 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++; algo_switch_n++;
@ -6215,11 +6357,15 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{ {
start_threads = mining_threads; //use start_threads below 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); rd_lock(&mining_thr_lock);
// Shutdown all threads first (necessary) // 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++) for (i = 0; i < start_threads; i++)
{ {
struct thr_info *thr = mining_thr[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)
// Reset stats (e.g. for working_diff to be set properly in hash_sole_work) // Reset stats (e.g. for working_diff to be set properly in hash_sole_work)
zero_stats(); zero_stats();
// Apply other pool-specific settings or revert to defaults //devices
if(opt_isset(options, SWITCHER_APPLY_DEVICE))
{
//reset devices flags //reset devices flags
opt_devs_enabled = 0; opt_devs_enabled = 0;
for (i = 0; i < MAX_DEVICES; i++) for (i = 0; i < MAX_DEVICES; i++)
devices_enabled[i] = false; devices_enabled[i] = false;
//assign pool devices if any //assign pool devices if any
if(!empty_string(work->pool->devices)) if(!empty_string((opt = get_pool_setting(work->pool->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all")))))
set_devices((char *)work->pool->devices); set_devices((char *)opt);
//assign default devices if any }
else if(!empty_string(default_profile.devices))
set_devices((char *)default_profile.devices);
//lookup gap //lookup gap
if(!empty_string(work->pool->lookup_gap)) if(opt_isset(options, SWITCHER_APPLY_LG))
set_lookup_gap((char *)work->pool->lookup_gap); {
else if(!empty_string(default_profile.lookup_gap)) if(!empty_string((opt = get_pool_setting(work->pool->lookup_gap, default_profile.lookup_gap))))
set_lookup_gap((char *)default_profile.lookup_gap); set_lookup_gap((char *)opt);
}
//raw intensity from pool //raw intensity from pool
if (!empty_string(work->pool->rawintensity)) if(opt_isset(options, SWITCHER_APPLY_RAWINT))
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
{ {
//xintensity from pool if(!empty_string((opt = get_pool_setting(work->pool->rawintensity, default_profile.rawintensity))))
if (!empty_string(work->pool->xintensity)) set_rawintensity((char *)opt);
set_xintensity(work->pool->xintensity); }
//xintensity from default profile //xintensity
else if(!empty_string(default_profile.xintensity)) else if(opt_isset(options, SWITCHER_APPLY_XINT))
set_xintensity(default_profile.xintensity);
//no xintensity set try intensity
else
{ {
//intensity from pool if(!empty_string((opt = get_pool_setting(work->pool->xintensity, default_profile.xintensity))))
if(!empty_string(work->pool->intensity)) set_xintensity((char *)opt);
set_intensity(work->pool->intensity); }
//intensity from defaults //intensity
else if(!empty_string(default_profile.intensity)) else if(opt_isset(options, SWITCHER_APPLY_INT))
set_intensity(default_profile.intensity); {
//nothing set anywhere, use 8 if(!empty_string((opt = get_pool_setting(work->pool->intensity, default_profile.intensity))))
else set_intensity((char *)opt);
}
//default basic intensity
else if(opt_isset(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 (!empty_string(work->pool->shaders)) if(opt_isset(options, SWITCHER_APPLY_SHADER))
set_shaders((char *)work->pool->shaders); {
else if(!empty_string(default_profile.shaders)) if(!empty_string((opt = get_pool_setting(work->pool->shaders, default_profile.shaders))))
set_shaders((char *)default_profile.shaders); set_shaders((char *)opt);
}
//thread-concurrency //thread-concurrency
if (!empty_string(work->pool->thread_concurrency)) if(opt_isset(options, SWITCHER_APPLY_TC))
set_thread_concurrency((char *)work->pool->thread_concurrency); {
else if(!empty_string(default_profile.thread_concurrency)) if(!empty_string((opt = get_pool_setting(work->pool->thread_concurrency, default_profile.thread_concurrency))))
set_thread_concurrency((char *)default_profile.thread_concurrency); set_thread_concurrency((char *)opt);
}
//worksize //worksize
if (!empty_string(work->pool->worksize)) if(opt_isset(options, SWITCHER_APPLY_WORKSIZE))
set_worksize((char *)work->pool->worksize); {
else if(!empty_string(default_profile.worksize)) if(!empty_string((opt = get_pool_setting(work->pool->worksize, default_profile.worksize))))
set_worksize((char *)default_profile.worksize); set_worksize((char *)opt);
}
#ifdef HAVE_ADL //apply algorithm
options = APPLY_ENGINE | APPLY_MEMCLOCK | APPLY_FANSPEED | APPLY_POWERTUNE | APPLY_VDDC; if(opt_isset(options, SWITCHER_APPLY_ALGO))
{
for (i = 0; i < nDevs; i++)
gpus[i].algorithm = work->pool->algorithm;
}
#ifdef HAVE_ADL
//GPU clock //GPU clock
if(!empty_string(work->pool->gpu_engine)) if(opt_isset(options, SWITCHER_APPLY_GPU_ENGINE))
set_gpu_engine(work->pool->gpu_engine); {
else if(!empty_string(default_profile.gpu_engine)) if(!empty_string((opt = get_pool_setting(work->pool->gpu_engine, default_profile.gpu_engine))))
set_gpu_engine(default_profile.gpu_engine); set_gpu_engine((char *)opt);
else }
options ^= APPLY_ENGINE;
//GPU memory clock //GPU memory clock
if(!empty_string(work->pool->gpu_memclock)) if(opt_isset(options, SWITCHER_APPLY_GPU_MEMCLOCK))
set_gpu_memclock(work->pool->gpu_memclock); {
else if(!empty_string(default_profile.gpu_memclock)) if(!empty_string((opt = get_pool_setting(work->pool->gpu_memclock, default_profile.gpu_memclock))))
set_gpu_memclock(default_profile.gpu_memclock); set_gpu_memclock((char *)opt);
else }
options ^= APPLY_MEMCLOCK;
//GPU fans //GPU fans
if(!empty_string(work->pool->gpu_fan)) if(opt_isset(options, SWITCHER_APPLY_GPU_FAN))
set_gpu_fan(work->pool->gpu_fan); {
else if(!empty_string(default_profile.gpu_fan)) if(!empty_string((opt = get_pool_setting(work->pool->gpu_fan, default_profile.gpu_fan))))
set_gpu_fan(default_profile.gpu_fan); set_gpu_fan((char *)opt);
else }
options ^= APPLY_FANSPEED;
//GPU powertune //GPU powertune
if(!empty_string(work->pool->gpu_powertune)) if(opt_isset(options, SWITCHER_APPLY_GPU_POWERTUNE))
set_gpu_powertune((char *)work->pool->gpu_powertune); {
else if(!empty_string(default_profile.gpu_powertune)) if(!empty_string((opt = get_pool_setting(work->pool->gpu_powertune, default_profile.gpu_powertune))))
set_gpu_powertune((char *)default_profile.gpu_powertune); set_gpu_powertune((char *)opt);
else }
options ^= APPLY_POWERTUNE;
//GPU vddc //GPU vddc
if(!empty_string(work->pool->gpu_vddc)) if(opt_isset(options, SWITCHER_APPLY_GPU_VDDC))
set_gpu_vddc((char *)work->pool->gpu_vddc); {
else if(!empty_string(default_profile.gpu_vddc)) if(!empty_string((opt = get_pool_setting(work->pool->gpu_vddc, default_profile.gpu_vddc))))
set_gpu_vddc((char *)default_profile.gpu_vddc); set_gpu_vddc((char *)opt);
else }
options ^= APPLY_VDDC;
//apply gpu settings //apply gpu settings
for (i = 0; i < nDevs; i++) 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); 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); 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); 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); 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); 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))
{
struct thr_info *thr;
applog(LOG_DEBUG, "Soft Reset... Restarting threads...");
for (i = 0; i < start_threads; i++) for (i = 0; i < start_threads; i++)
{ {
struct thr_info *thr = mining_thr[i]; thr = mining_thr[i];
thr->cgpu->algorithm = work->pool->algorithm; thr->pool_no = work->pool->pool_no; //set thread on new pool
if (soft_restart)
if(opt_isset(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);
@ -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 // Necessary because algorithms can have dramatically different diffs
thr->cgpu->drv->working_diff = 1; thr->cgpu->drv->working_diff = 1;
} }
}
rd_unlock(&mining_thr_lock); rd_unlock(&mining_thr_lock);
@ -6381,10 +6529,15 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
algo_switch_n = 0; algo_switch_n = 0;
mutex_unlock(&algo_switch_lock); mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 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 sgminer_id_count = 0; //reset sgminer_ids
mining_threads = 0; //mining threads gets added inside each enable_device() so reset mining_threads = 0; //mining threads gets added inside each enable_device() so reset
if(opt_devs_enabled) if(opt_devs_enabled)
@ -6393,13 +6546,9 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{ {
//device should be enabled //device should be enabled
if(devices_enabled[i] && i < total_devices) if(devices_enabled[i] && i < total_devices)
{
applog(LOG_DEBUG, "Enabling device %d", i);
enable_device(devices[i]); enable_device(devices[i]);
}
else if(i < total_devices) else if(i < total_devices)
{ {
applog(LOG_DEBUG, "Disabling device %d", i);
//if option is set to not remove disabled, enable device //if option is set to not remove disabled, enable device
if(!opt_removedisabled) if(!opt_removedisabled)
enable_device(devices[i]); enable_device(devices[i]);
@ -6415,18 +6564,21 @@ 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)
enable_device(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; unsigned int n_threads = 0;
pthread_t restart_thr; pthread_t restart_thr;
#ifdef HAVE_ADL #ifdef HAVE_ADL
if(!empty_string(work->pool->gpu_threads)) //change gpu threads if needed
set_gpu_threads(work->pool->gpu_threads); if(opt_isset(options, SWITCHER_APPLY_GT))
else if(!empty_string(default_profile.gpu_threads)) {
set_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);
}
for (i = 0; i < total_devices; ++i) for (i = 0; i < total_devices; i++)
n_threads += devices[i]->threads; n_threads += devices[i]->threads;
#else #else
n_threads = mining_threads; n_threads = mining_threads;
@ -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"); 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 // Signal other threads to start working now
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);
@ -7942,13 +8110,16 @@ static void restart_mining_threads(unsigned int new_n_threads)
unsigned int i, j, k; unsigned int i, j, k;
// Stop and free threads // Stop and free threads
if (mining_thr) { if (mining_thr)
{
rd_lock(&mining_thr_lock); 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); applog(LOG_DEBUG, "Shutting down thread %d", i);
mining_thr[i]->cgpu->shutdown = true; mining_thr[i]->cgpu->shutdown = true;
} }
rd_unlock(&mining_thr_lock); rd_unlock(&mining_thr_lock);
// kill_mining will rd lock mining_thr_lock // kill_mining will rd lock mining_thr_lock
kill_mining(); kill_mining();
rd_lock(&mining_thr_lock); rd_lock(&mining_thr_lock);
@ -7963,13 +8134,16 @@ static void restart_mining_threads(unsigned int new_n_threads)
wr_lock(&mining_thr_lock); wr_lock(&mining_thr_lock);
if (mining_thr) { if (mining_thr)
for (i = 0; i < total_devices; ++i) { {
for (i = 0; i < total_devices; i++) {
free(devices[i]->thr); free(devices[i]->thr);
} }
for (i = 0; i < mining_threads; i++) { for (i = 0; i < mining_threads; i++) {
free(mining_thr[i]); free(mining_thr[i]);
} }
free(mining_thr); free(mining_thr);
} }
@ -7988,7 +8162,10 @@ static void restart_mining_threads(unsigned int new_n_threads)
} }
rd_lock(&devices_lock); rd_lock(&devices_lock);
// Start threads // Start threads
struct pool *pool = current_pool();
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];
@ -7996,9 +8173,11 @@ static void restart_mining_threads(unsigned int new_n_threads)
cgpu->thr[cgpu->threads] = NULL; cgpu->thr[cgpu->threads] = NULL;
cgpu->status = LIFE_INIT; 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 = mining_thr[k];
thr->id = k; thr->id = k;
thr->pool_no = pool->pool_no;
thr->cgpu = cgpu; thr->cgpu = cgpu;
thr->device_thread = j; thr->device_thread = j;

Loading…
Cancel
Save