mirror of
https://github.com/GOSTSec/sgminer
synced 2025-02-02 01:44:23 +00:00
remove unused code (mostly intended for ASICs which are not supported in sgminer), fix some compiler warnings
This commit is contained in:
parent
cabbd7362f
commit
5e3142cf68
@ -418,5 +418,3 @@ void scrypt_regenhash(struct work *work)
|
|||||||
scrypt_n_1_1_256_sp(data, scratchbuf, ohash, work->pool->algorithm.n);
|
scrypt_n_1_1_256_sp(data, scratchbuf, ohash, work->pool->algorithm.n);
|
||||||
flip32(ohash, ohash);
|
flip32(ohash, ohash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t diff1targ = 0x0000ffff;
|
|
||||||
|
25
miner.h
25
miner.h
@ -522,11 +522,6 @@ struct cgpu_info {
|
|||||||
|
|
||||||
struct sgminer_stats sgminer_stats;
|
struct sgminer_stats sgminer_stats;
|
||||||
|
|
||||||
pthread_rwlock_t qlock;
|
|
||||||
struct work *queued_work;
|
|
||||||
struct work *unqueued_work;
|
|
||||||
unsigned int queued_count;
|
|
||||||
|
|
||||||
bool shutdown;
|
bool shutdown;
|
||||||
|
|
||||||
struct timeval dev_start_tv;
|
struct timeval dev_start_tv;
|
||||||
@ -1009,7 +1004,6 @@ extern pthread_cond_t restart_cond;
|
|||||||
extern void clear_stratum_shares(struct pool *pool);
|
extern void clear_stratum_shares(struct pool *pool);
|
||||||
extern void clear_pool_work(struct pool *pool);
|
extern void clear_pool_work(struct pool *pool);
|
||||||
extern void set_target(unsigned char *dest_target, double diff, double diff_multiplier2);
|
extern void set_target(unsigned char *dest_target, double diff, double diff_multiplier2);
|
||||||
extern int restart_wait(struct thr_info *thr, unsigned int mstime);
|
|
||||||
|
|
||||||
extern void kill_work(void);
|
extern void kill_work(void);
|
||||||
|
|
||||||
@ -1061,7 +1055,6 @@ extern struct cgpu_info gpus[MAX_GPUDEVICES];
|
|||||||
extern double total_secs;
|
extern double total_secs;
|
||||||
extern int mining_threads;
|
extern int mining_threads;
|
||||||
extern int total_devices;
|
extern int total_devices;
|
||||||
extern int zombie_devs;
|
|
||||||
extern struct cgpu_info **devices;
|
extern struct cgpu_info **devices;
|
||||||
extern int total_pools;
|
extern int total_pools;
|
||||||
extern struct pool **pools;
|
extern struct pool **pools;
|
||||||
@ -1368,26 +1361,9 @@ struct work {
|
|||||||
extern void get_datestamp(char *, size_t, struct timeval *);
|
extern void get_datestamp(char *, size_t, struct timeval *);
|
||||||
extern void inc_hw_errors(struct thr_info *thr);
|
extern void inc_hw_errors(struct thr_info *thr);
|
||||||
extern bool test_nonce(struct work *work, uint32_t nonce);
|
extern bool test_nonce(struct work *work, uint32_t nonce);
|
||||||
extern bool test_nonce_diff(struct work *work, uint32_t nonce, double diff);
|
|
||||||
extern bool submit_tested_work(struct thr_info *thr, struct work *work);
|
extern bool submit_tested_work(struct thr_info *thr, struct work *work);
|
||||||
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
||||||
extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
|
|
||||||
int noffset);
|
|
||||||
extern struct work *get_work(struct thr_info *thr, const int thr_id);
|
extern struct work *get_work(struct thr_info *thr, const int thr_id);
|
||||||
extern void __add_queued(struct cgpu_info *cgpu, struct work *work);
|
|
||||||
extern struct work *get_queued(struct cgpu_info *cgpu);
|
|
||||||
extern void add_queued(struct cgpu_info *cgpu, struct work *work);
|
|
||||||
extern struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id);
|
|
||||||
extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
|
||||||
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
|
||||||
extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
|
||||||
extern void __work_completed(struct cgpu_info *cgpu, struct work *work);
|
|
||||||
extern int age_queued_work(struct cgpu_info *cgpu, double secs);
|
|
||||||
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
|
|
||||||
extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
|
||||||
extern void flush_queue(struct cgpu_info *cgpu);
|
|
||||||
extern void hash_driver_work(struct thr_info *mythr);
|
|
||||||
extern void hash_queued_work(struct thr_info *mythr);
|
|
||||||
extern void _wlog(const char *str);
|
extern void _wlog(const char *str);
|
||||||
extern void _wlogprint(const char *str);
|
extern void _wlogprint(const char *str);
|
||||||
extern int curses_int(const char *query);
|
extern int curses_int(const char *query);
|
||||||
@ -1416,7 +1392,6 @@ extern void adl(void);
|
|||||||
extern void app_restart(void);
|
extern void app_restart(void);
|
||||||
extern void clean_work(struct work *work);
|
extern void clean_work(struct work *work);
|
||||||
extern void free_work(struct work *work);
|
extern void free_work(struct work *work);
|
||||||
extern void set_work_ntime(struct work *work, int ntime);
|
|
||||||
extern struct work *copy_work_noffset(struct work *base_work, int noffset);
|
extern struct work *copy_work_noffset(struct work *base_work, int noffset);
|
||||||
#define copy_work(work_in) copy_work_noffset(work_in, 0)
|
#define copy_work(work_in) copy_work_noffset(work_in, 0)
|
||||||
extern struct thr_info *get_thread(int thr_id);
|
extern struct thr_info *get_thread(int thr_id);
|
||||||
|
422
sgminer.c
422
sgminer.c
@ -100,7 +100,6 @@ int opt_expiry = 28;
|
|||||||
|
|
||||||
algorithm_t *opt_algorithm;
|
algorithm_t *opt_algorithm;
|
||||||
|
|
||||||
static const bool opt_time = true;
|
|
||||||
unsigned long long global_hashrate;
|
unsigned long long global_hashrate;
|
||||||
unsigned long global_quota_gcd = 1;
|
unsigned long global_quota_gcd = 1;
|
||||||
bool opt_show_coindiff = false;
|
bool opt_show_coindiff = false;
|
||||||
@ -117,7 +116,6 @@ static int opt_devs_enabled;
|
|||||||
static bool opt_display_devs;
|
static bool opt_display_devs;
|
||||||
static bool opt_removedisabled;
|
static bool opt_removedisabled;
|
||||||
int total_devices;
|
int total_devices;
|
||||||
int zombie_devs;
|
|
||||||
static int most_devices;
|
static int most_devices;
|
||||||
struct cgpu_info **devices;
|
struct cgpu_info **devices;
|
||||||
int mining_threads;
|
int mining_threads;
|
||||||
@ -816,6 +814,7 @@ static char *set_pool_thread_concurrency(const char *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ADL
|
||||||
static char *set_pool_gpu_engine(const char *arg)
|
static char *set_pool_gpu_engine(const char *arg)
|
||||||
{
|
{
|
||||||
struct pool *pool = get_current_pool();
|
struct pool *pool = get_current_pool();
|
||||||
@ -843,6 +842,7 @@ static char *set_pool_gpu_fan(const char *arg)
|
|||||||
pool->gpu_fan = arg;
|
pool->gpu_fan = arg;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *set_pool_nfactor(const char *arg)
|
static char *set_pool_nfactor(const char *arg)
|
||||||
{
|
{
|
||||||
@ -3736,17 +3736,6 @@ static void _copy_work(struct work *work, const struct work *base_work, int noff
|
|||||||
work->coinbase = strdup(base_work->coinbase);
|
work->coinbase = strdup(base_work->coinbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_work_ntime(struct work *work, int ntime)
|
|
||||||
{
|
|
||||||
uint32_t *work_ntime = (uint32_t *)(work->data + 68);
|
|
||||||
|
|
||||||
*work_ntime = htobe32(ntime);
|
|
||||||
if (work->ntime) {
|
|
||||||
free(work->ntime);
|
|
||||||
work->ntime = bin2hex((unsigned char *)work_ntime, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generates a copy of an existing work struct, creating fresh heap allocations
|
/* Generates a copy of an existing work struct, creating fresh heap allocations
|
||||||
* for all dynamically allocated arrays within the struct. noffset is used for
|
* for all dynamically allocated arrays within the struct. noffset is used for
|
||||||
* when a driver has internally rolled the ntime, noffset is a relative value.
|
* when a driver has internally rolled the ntime, noffset is a relative value.
|
||||||
@ -4035,34 +4024,6 @@ static void discard_stale(void)
|
|||||||
applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale);
|
applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A generic wait function for threads that poll that will wait a specified
|
|
||||||
* time tdiff waiting on the pthread conditional that is broadcast when a
|
|
||||||
* work restart is required. Returns the value of pthread_cond_timedwait
|
|
||||||
* which is zero if the condition was met or ETIMEDOUT if not.
|
|
||||||
*/
|
|
||||||
int restart_wait(struct thr_info *thr, unsigned int mstime)
|
|
||||||
{
|
|
||||||
struct timeval now, then, tdiff;
|
|
||||||
struct timespec abstime;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
tdiff.tv_sec = mstime / 1000;
|
|
||||||
tdiff.tv_usec = mstime * 1000 - (tdiff.tv_sec * 1000000);
|
|
||||||
cgtime(&now);
|
|
||||||
timeradd(&now, &tdiff, &then);
|
|
||||||
abstime.tv_sec = then.tv_sec;
|
|
||||||
abstime.tv_nsec = then.tv_usec * 1000;
|
|
||||||
|
|
||||||
mutex_lock(&restart_lock);
|
|
||||||
if (thr->work_restart)
|
|
||||||
rc = 0;
|
|
||||||
else
|
|
||||||
rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);
|
|
||||||
mutex_unlock(&restart_lock);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *restart_thread(void __maybe_unused *arg)
|
static void *restart_thread(void __maybe_unused *arg)
|
||||||
{
|
{
|
||||||
struct pool *cp = current_pool();
|
struct pool *cp = current_pool();
|
||||||
@ -4089,7 +4050,6 @@ static void *restart_thread(void __maybe_unused *arg)
|
|||||||
if (cgpu->deven != DEV_ENABLED)
|
if (cgpu->deven != DEV_ENABLED)
|
||||||
continue;
|
continue;
|
||||||
mining_thr[i]->work_restart = true;
|
mining_thr[i]->work_restart = true;
|
||||||
flush_queue(cgpu);
|
|
||||||
cgpu->drv->flush_work(cgpu);
|
cgpu->drv->flush_work(cgpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4157,17 +4117,6 @@ static bool block_exists(char *hexstr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tests if this work is from a block that has been seen before */
|
|
||||||
static inline bool from_existing_block(struct work *work)
|
|
||||||
{
|
|
||||||
char *hexstr = bin2hex(work->data + 8, 18);
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
ret = block_exists(hexstr);
|
|
||||||
free(hexstr);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int block_sort(struct block *blocka, struct block *blockb)
|
static int block_sort(struct block *blocka, struct block *blockb)
|
||||||
{
|
{
|
||||||
return blocka->block_no - blockb->block_no;
|
return blocka->block_no - blockb->block_no;
|
||||||
@ -4475,7 +4424,10 @@ void write_config(FILE *fcfg)
|
|||||||
if (nDevs) {
|
if (nDevs) {
|
||||||
fputs(",\n\"intensity\" : \"", fcfg);
|
fputs(",\n\"intensity\" : \"", fcfg);
|
||||||
for(i = 0; i < nDevs; i++)
|
for(i = 0; i < nDevs; i++)
|
||||||
fprintf(fcfg, gpus[i].dynamic ? "%sd" : "%s%d", i > 0 ? "," : "", gpus[i].intensity);
|
if (gpus[i].dynamic)
|
||||||
|
fprintf(fcfg, "%sd", i > 0 ? "," : "");
|
||||||
|
else
|
||||||
|
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].intensity);
|
||||||
|
|
||||||
fputs("\",\n\"xintensity\" : \"", fcfg);
|
fputs("\",\n\"xintensity\" : \"", fcfg);
|
||||||
for(i = 0; i < nDevs; i++)
|
for(i = 0; i < nDevs; i++)
|
||||||
@ -6288,7 +6240,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
|||||||
n_threads = mining_threads;
|
n_threads = mining_threads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (unlikely(pthread_create(&restart_thr, NULL, restart_mining_threads_thread, (void *)n_threads)))
|
if (unlikely(pthread_create(&restart_thr, NULL, restart_mining_threads_thread, (void *) (intptr_t) n_threads)))
|
||||||
quit(1, "restart_mining_threads create thread failed");
|
quit(1, "restart_mining_threads create thread failed");
|
||||||
sleep(60);
|
sleep(60);
|
||||||
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");
|
||||||
@ -6422,18 +6374,6 @@ bool test_nonce(struct work *work, uint32_t nonce)
|
|||||||
return (le32toh(*hash_32) <= diff1targ);
|
return (le32toh(*hash_32) <= diff1targ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For testing a nonce against an arbitrary diff */
|
|
||||||
bool test_nonce_diff(struct work *work, uint32_t nonce, double diff)
|
|
||||||
{
|
|
||||||
uint64_t *hash64 = (uint64_t *)(work->hash + 24), diff64;
|
|
||||||
|
|
||||||
rebuild_nonce(work, nonce);
|
|
||||||
diff64 = work->pool->algorithm.diff_nonce;
|
|
||||||
diff64 /= diff;
|
|
||||||
|
|
||||||
return (le64toh(*hash64) <= diff64);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_work_stats(struct thr_info *thr, struct work *work)
|
static void update_work_stats(struct thr_info *thr, struct work *work)
|
||||||
{
|
{
|
||||||
double test_diff = current_diff;
|
double test_diff = current_diff;
|
||||||
@ -6489,36 +6429,6 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allows drivers to submit work items where the driver has changed the ntime
|
|
||||||
* value by noffset. Must be only used with a work protocol that does not ntime
|
|
||||||
* roll itself intrinsically to generate work (eg stratum). We do not touch
|
|
||||||
* the original work struct, but the copy of it only. */
|
|
||||||
bool submit_noffset_nonce(struct thr_info *thr, struct work *work_in, uint32_t nonce,
|
|
||||||
int noffset)
|
|
||||||
{
|
|
||||||
struct work *work = make_work();
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
_copy_work(work, work_in, noffset);
|
|
||||||
if (!test_nonce(work, nonce)) {
|
|
||||||
inc_hw_errors(thr);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = true;
|
|
||||||
update_work_stats(thr, work);
|
|
||||||
if (!fulltest(work->hash, work->target)) {
|
|
||||||
applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name,
|
|
||||||
thr->cgpu->device_id);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
submit_work_async(work);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (!ret)
|
|
||||||
free_work(work);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
|
static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
|
||||||
{
|
{
|
||||||
if (wdiff->tv_sec > opt_scantime ||
|
if (wdiff->tv_sec > opt_scantime ||
|
||||||
@ -6708,315 +6618,6 @@ static void hash_sole_work(struct thr_info *mythr)
|
|||||||
cgpu->deven = DEV_DISABLED;
|
cgpu->deven = DEV_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put a new unqueued work item in cgpu->unqueued_work under cgpu->qlock till
|
|
||||||
* the driver tells us it's full so that it may extract the work item using
|
|
||||||
* the get_queued() function which adds it to the hashtable on
|
|
||||||
* cgpu->queued_work. */
|
|
||||||
static void fill_queue(struct thr_info *mythr, struct cgpu_info *cgpu, struct device_drv *drv, const int thr_id)
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
bool need_work;
|
|
||||||
|
|
||||||
/* Do this lockless just to know if we need more unqueued work. */
|
|
||||||
need_work = (!cgpu->unqueued_work);
|
|
||||||
|
|
||||||
/* get_work is a blocking function so do it outside of lock
|
|
||||||
* to prevent deadlocks with other locks. */
|
|
||||||
if (need_work) {
|
|
||||||
struct work *work = get_work(mythr, thr_id);
|
|
||||||
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
/* Check we haven't grabbed work somehow between
|
|
||||||
* checking and picking up the lock. */
|
|
||||||
if (likely(!cgpu->unqueued_work))
|
|
||||||
cgpu->unqueued_work = work;
|
|
||||||
else
|
|
||||||
need_work = false;
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
if (unlikely(!need_work))
|
|
||||||
discard_work(work);
|
|
||||||
}
|
|
||||||
/* The queue_full function should be used by the driver to
|
|
||||||
* actually place work items on the physical device if it
|
|
||||||
* does have a queue. */
|
|
||||||
} while (!drv->queue_full(cgpu));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a work item to a cgpu's queued hashlist */
|
|
||||||
void __add_queued(struct cgpu_info *cgpu, struct work *work)
|
|
||||||
{
|
|
||||||
cgpu->queued_count++;
|
|
||||||
HASH_ADD_INT(cgpu->queued_work, id, work);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is for retrieving one work item from the unqueued pointer and
|
|
||||||
* adding it to the hashtable of queued work. Code using this function must be
|
|
||||||
* able to handle NULL as a return which implies there is no work available. */
|
|
||||||
struct work *get_queued(struct cgpu_info *cgpu)
|
|
||||||
{
|
|
||||||
struct work *work = NULL;
|
|
||||||
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
if (cgpu->unqueued_work) {
|
|
||||||
work = cgpu->unqueued_work;
|
|
||||||
if (unlikely(stale_work(work, false))) {
|
|
||||||
discard_work(work);
|
|
||||||
work = NULL;
|
|
||||||
wake_gws();
|
|
||||||
} else
|
|
||||||
__add_queued(cgpu, work);
|
|
||||||
cgpu->unqueued_work = NULL;
|
|
||||||
}
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
return work;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_queued(struct cgpu_info *cgpu, struct work *work)
|
|
||||||
{
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
__add_queued(cgpu, work);
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get fresh work and add it to cgpu's queued hashlist */
|
|
||||||
struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id)
|
|
||||||
{
|
|
||||||
struct work *work = get_work(thr, thr_id);
|
|
||||||
|
|
||||||
add_queued(cgpu, work);
|
|
||||||
return work;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is for finding an already queued work item in the
|
|
||||||
* given que hashtable. Code using this function must be able
|
|
||||||
* to handle NULL as a return which implies there is no matching work.
|
|
||||||
* The calling function must lock access to the que if it is required.
|
|
||||||
* The common values for midstatelen, offset, datalen are 32, 64, 12 */
|
|
||||||
struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
|
|
||||||
{
|
|
||||||
struct work *work, *tmp, *ret = NULL;
|
|
||||||
|
|
||||||
HASH_ITER(hh, que, work, tmp) {
|
|
||||||
if (memcmp(work->midstate, midstate, midstatelen) == 0 &&
|
|
||||||
memcmp(work->data + offset, data, datalen) == 0) {
|
|
||||||
ret = work;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is for finding an already queued work item in the
|
|
||||||
* device's queued_work hashtable. Code using this function must be able
|
|
||||||
* to handle NULL as a return which implies there is no matching work.
|
|
||||||
* The common values for midstatelen, offset, datalen are 32, 64, 12 */
|
|
||||||
struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
|
|
||||||
{
|
|
||||||
struct work *ret;
|
|
||||||
|
|
||||||
rd_lock(&cgpu->qlock);
|
|
||||||
ret = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
|
|
||||||
rd_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
|
|
||||||
{
|
|
||||||
struct work *work, *ret = NULL;
|
|
||||||
|
|
||||||
rd_lock(&cgpu->qlock);
|
|
||||||
work = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
|
|
||||||
if (work)
|
|
||||||
ret = copy_work(work);
|
|
||||||
rd_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __work_completed(struct cgpu_info *cgpu, struct work *work)
|
|
||||||
{
|
|
||||||
cgpu->queued_count--;
|
|
||||||
HASH_DEL(cgpu->queued_work, work);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This iterates over a queued hashlist finding work started more than secs
|
|
||||||
* seconds ago and discards the work as completed. The driver must set the
|
|
||||||
* work->tv_work_start value appropriately. Returns the number of items aged. */
|
|
||||||
int age_queued_work(struct cgpu_info *cgpu, double secs)
|
|
||||||
{
|
|
||||||
struct work *work, *tmp;
|
|
||||||
struct timeval tv_now;
|
|
||||||
int aged = 0;
|
|
||||||
|
|
||||||
cgtime(&tv_now);
|
|
||||||
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
HASH_ITER(hh, cgpu->queued_work, work, tmp) {
|
|
||||||
if (tdiff(&tv_now, &work->tv_work_start) > secs) {
|
|
||||||
__work_completed(cgpu, work);
|
|
||||||
aged++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
return aged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function should be used by queued device drivers when they're sure
|
|
||||||
* the work struct is no longer in use. */
|
|
||||||
void work_completed(struct cgpu_info *cgpu, struct work *work)
|
|
||||||
{
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
__work_completed(cgpu, work);
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
free_work(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Combines find_queued_work_bymidstate and work_completed in one function
|
|
||||||
* withOUT destroying the work so the driver must free it. */
|
|
||||||
struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
|
|
||||||
{
|
|
||||||
struct work *work;
|
|
||||||
|
|
||||||
wr_lock(&cgpu->qlock);
|
|
||||||
work = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
|
|
||||||
if (work)
|
|
||||||
__work_completed(cgpu, work);
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
return work;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_queue(struct cgpu_info *cgpu)
|
|
||||||
{
|
|
||||||
struct work *work = NULL;
|
|
||||||
|
|
||||||
if (unlikely(!cgpu))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Use only a trylock in case we get into a deadlock with a queueing
|
|
||||||
* function holding the read lock when we're called. */
|
|
||||||
if (wr_trylock(&cgpu->qlock))
|
|
||||||
return;
|
|
||||||
work = cgpu->unqueued_work;
|
|
||||||
cgpu->unqueued_work = NULL;
|
|
||||||
wr_unlock(&cgpu->qlock);
|
|
||||||
|
|
||||||
if (work) {
|
|
||||||
free_work(work);
|
|
||||||
applog(LOG_DEBUG, "Discarded queued work item");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This version of hash work is for devices that are fast enough to always
|
|
||||||
* perform a full nonce range and need a queue to maintain the device busy.
|
|
||||||
* Work creation and destruction is not done from within this function
|
|
||||||
* directly. */
|
|
||||||
void hash_queued_work(struct thr_info *mythr)
|
|
||||||
{
|
|
||||||
struct timeval tv_start = {0, 0}, tv_end;
|
|
||||||
struct cgpu_info *cgpu = mythr->cgpu;
|
|
||||||
struct device_drv *drv = cgpu->drv;
|
|
||||||
const int thr_id = mythr->id;
|
|
||||||
int64_t hashes_done = 0;
|
|
||||||
|
|
||||||
while (likely(!cgpu->shutdown)) {
|
|
||||||
struct timeval diff;
|
|
||||||
int64_t hashes;
|
|
||||||
|
|
||||||
mythr->work_update = false;
|
|
||||||
|
|
||||||
fill_queue(mythr, cgpu, drv, thr_id);
|
|
||||||
|
|
||||||
hashes = drv->scanwork(mythr);
|
|
||||||
|
|
||||||
/* Reset the bool here in case the driver looks for it
|
|
||||||
* synchronously in the scanwork loop. */
|
|
||||||
mythr->work_restart = false;
|
|
||||||
|
|
||||||
if (unlikely(hashes == -1 )) {
|
|
||||||
applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id);
|
|
||||||
cgpu->deven = DEV_DISABLED;
|
|
||||||
dev_error(cgpu, REASON_THREAD_ZERO_HASH);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashes_done += hashes;
|
|
||||||
cgtime(&tv_end);
|
|
||||||
timersub(&tv_end, &tv_start, &diff);
|
|
||||||
/* Update the hashmeter at most 5 times per second */
|
|
||||||
if ((hashes_done && (diff.tv_sec > 0 || diff.tv_usec > 200000)) ||
|
|
||||||
diff.tv_sec >= opt_log_interval) {
|
|
||||||
hashmeter(thr_id, &diff, hashes_done);
|
|
||||||
hashes_done = 0;
|
|
||||||
copy_time(&tv_start, &tv_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))
|
|
||||||
mt_disable(mythr, thr_id, drv);
|
|
||||||
|
|
||||||
if (mythr->work_update)
|
|
||||||
drv->update_work(cgpu);
|
|
||||||
}
|
|
||||||
cgpu->deven = DEV_DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This version of hash_work is for devices drivers that want to do their own
|
|
||||||
* work management entirely, usually by using get_work(). Note that get_work
|
|
||||||
* is a blocking function and will wait indefinitely if no work is available
|
|
||||||
* so this must be taken into consideration in the driver. */
|
|
||||||
void hash_driver_work(struct thr_info *mythr)
|
|
||||||
{
|
|
||||||
struct timeval tv_start = {0, 0}, tv_end;
|
|
||||||
struct cgpu_info *cgpu = mythr->cgpu;
|
|
||||||
struct device_drv *drv = cgpu->drv;
|
|
||||||
const int thr_id = mythr->id;
|
|
||||||
int64_t hashes_done = 0;
|
|
||||||
|
|
||||||
while (likely(!cgpu->shutdown)) {
|
|
||||||
struct timeval diff;
|
|
||||||
int64_t hashes;
|
|
||||||
|
|
||||||
mythr->work_update = false;
|
|
||||||
|
|
||||||
hashes = drv->scanwork(mythr);
|
|
||||||
|
|
||||||
/* Reset the bool here in case the driver looks for it
|
|
||||||
* synchronously in the scanwork loop. */
|
|
||||||
mythr->work_restart = false;
|
|
||||||
|
|
||||||
if (unlikely(hashes == -1 )) {
|
|
||||||
applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id);
|
|
||||||
cgpu->deven = DEV_DISABLED;
|
|
||||||
dev_error(cgpu, REASON_THREAD_ZERO_HASH);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashes_done += hashes;
|
|
||||||
cgtime(&tv_end);
|
|
||||||
timersub(&tv_end, &tv_start, &diff);
|
|
||||||
/* Update the hashmeter at most 5 times per second */
|
|
||||||
if ((hashes_done && (diff.tv_sec > 0 || diff.tv_usec > 200000)) ||
|
|
||||||
diff.tv_sec >= opt_log_interval) {
|
|
||||||
hashmeter(thr_id, &diff, hashes_done);
|
|
||||||
hashes_done = 0;
|
|
||||||
copy_time(&tv_start, &tv_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))
|
|
||||||
mt_disable(mythr, thr_id, drv);
|
|
||||||
|
|
||||||
if (mythr->work_update)
|
|
||||||
drv->update_work(cgpu);
|
|
||||||
}
|
|
||||||
cgpu->deven = DEV_DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *miner_thread(void *userdata)
|
void *miner_thread(void *userdata)
|
||||||
{
|
{
|
||||||
struct thr_info *mythr = (struct thr_info *)userdata;
|
struct thr_info *mythr = (struct thr_info *)userdata;
|
||||||
@ -8055,9 +7656,6 @@ void enable_device(struct cgpu_info *cgpu)
|
|||||||
#ifdef HAVE_CURSES
|
#ifdef HAVE_CURSES
|
||||||
adj_width(mining_threads, &dev_width);
|
adj_width(mining_threads, &dev_width);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rwlock_init(&cgpu->qlock);
|
|
||||||
cgpu->queued_work = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _cgpu_devid_counter {
|
struct _cgpu_devid_counter {
|
||||||
@ -8068,8 +7666,8 @@ struct _cgpu_devid_counter {
|
|||||||
|
|
||||||
static void adjust_mostdevs(void)
|
static void adjust_mostdevs(void)
|
||||||
{
|
{
|
||||||
if (total_devices - zombie_devs > most_devices)
|
if (total_devices > most_devices)
|
||||||
most_devices = total_devices - zombie_devs;
|
most_devices = total_devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool add_cgpu(struct cgpu_info *cgpu)
|
bool add_cgpu(struct cgpu_info *cgpu)
|
||||||
@ -8202,7 +7800,7 @@ static void restart_mining_threads(unsigned int new_n_threads)
|
|||||||
|
|
||||||
static void *restart_mining_threads_thread(void *userdata)
|
static void *restart_mining_threads_thread(void *userdata)
|
||||||
{
|
{
|
||||||
restart_mining_threads((unsigned int) userdata);
|
restart_mining_threads((unsigned int) (intptr_t) userdata);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
4
util.c
4
util.c
@ -52,8 +52,10 @@ bool successful_connect = false;
|
|||||||
static void keep_sockalive(SOCKETTYPE fd)
|
static void keep_sockalive(SOCKETTYPE fd)
|
||||||
{
|
{
|
||||||
const int tcp_one = 1;
|
const int tcp_one = 1;
|
||||||
|
#ifdef __linux
|
||||||
|
const int tcp_keepidle = 45;
|
||||||
|
#endif
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
const int tcp_keepidle = 45;
|
|
||||||
const int tcp_keepintvl = 30;
|
const int tcp_keepintvl = 30;
|
||||||
int flags = fcntl(fd, F_GETFL, 0);
|
int flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user