|
|
@ -2039,7 +2039,7 @@ static inline bool can_roll(struct work *work) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool get_work(struct work *work, bool queued, struct thr_info *thr, |
|
|
|
static bool get_work(struct work *work, bool queued, struct thr_info *thr, |
|
|
|
const int thr_id) |
|
|
|
const int thr_id, uint32_t hash_div) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct timespec abstime = {}; |
|
|
|
struct timespec abstime = {}; |
|
|
|
struct timeval now; |
|
|
|
struct timeval now; |
|
|
@ -2181,7 +2181,7 @@ static void *miner_thread(void *userdata) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct thr_info *mythr = userdata; |
|
|
|
struct thr_info *mythr = userdata; |
|
|
|
const int thr_id = mythr->id; |
|
|
|
const int thr_id = mythr->id; |
|
|
|
uint32_t max_nonce = 0xffffff; |
|
|
|
uint32_t max_nonce = 0xffffff, total_hashes = 0; |
|
|
|
unsigned long hashes_done = max_nonce; |
|
|
|
unsigned long hashes_done = max_nonce; |
|
|
|
bool needs_work = true; |
|
|
|
bool needs_work = true; |
|
|
|
/* Try to cycle approximately 5 times before each log update */ |
|
|
|
/* Try to cycle approximately 5 times before each log update */ |
|
|
@ -2190,6 +2190,7 @@ static void *miner_thread(void *userdata) |
|
|
|
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1; |
|
|
|
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1; |
|
|
|
unsigned const long request_nonce = MAXTHREADS / 3 * 2; |
|
|
|
unsigned const long request_nonce = MAXTHREADS / 3 * 2; |
|
|
|
bool requested = true; |
|
|
|
bool requested = true; |
|
|
|
|
|
|
|
uint32_t hash_div = 1; |
|
|
|
|
|
|
|
|
|
|
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); |
|
|
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); |
|
|
|
|
|
|
|
|
|
|
@ -2213,15 +2214,16 @@ static void *miner_thread(void *userdata) |
|
|
|
if (needs_work) { |
|
|
|
if (needs_work) { |
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
if (unlikely(!get_work(&work, requested, mythr, thr_id))) { |
|
|
|
if (unlikely(!get_work(&work, requested, mythr, thr_id, hash_div))) { |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
"mining thread %d", thr_id); |
|
|
|
"mining thread %d", thr_id); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
mythr->cgpu->getworks++; |
|
|
|
mythr->cgpu->getworks++; |
|
|
|
needs_work = requested = false; |
|
|
|
needs_work = requested = false; |
|
|
|
work.blk.nonce = 0; |
|
|
|
total_hashes = 0; |
|
|
|
max_nonce = hashes_done; |
|
|
|
work.blk.nonce = work.res_nonce;; |
|
|
|
|
|
|
|
max_nonce = work.blk.nonce + hashes_done; |
|
|
|
} |
|
|
|
} |
|
|
|
hashes_done = 0; |
|
|
|
hashes_done = 0; |
|
|
|
gettimeofday(&tv_start, NULL); |
|
|
|
gettimeofday(&tv_start, NULL); |
|
|
@ -2308,6 +2310,7 @@ static void *miner_thread(void *userdata) |
|
|
|
|
|
|
|
|
|
|
|
hashes_done -= work.blk.nonce; |
|
|
|
hashes_done -= work.blk.nonce; |
|
|
|
hashmeter(thr_id, &diff, hashes_done); |
|
|
|
hashmeter(thr_id, &diff, hashes_done); |
|
|
|
|
|
|
|
total_hashes += hashes_done; |
|
|
|
work.blk.nonce += hashes_done; |
|
|
|
work.blk.nonce += hashes_done; |
|
|
|
|
|
|
|
|
|
|
|
/* adjust max_nonce to meet target cycle time */ |
|
|
|
/* adjust max_nonce to meet target cycle time */ |
|
|
@ -2342,9 +2345,11 @@ static void *miner_thread(void *userdata) |
|
|
|
requested = true; |
|
|
|
requested = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (diff.tv_sec > opt_scantime || work_restart[thr_id].restart || |
|
|
|
if (diff.tv_sec > opt_scantime) { |
|
|
|
work.blk.nonce >= MAXTHREADS - hashes_done || |
|
|
|
hash_div = (MAXTHREADS / total_hashes) ? : 1; |
|
|
|
stale_work(&work)) |
|
|
|
needs_work = true; |
|
|
|
|
|
|
|
} else if (work_restart[thr_id].restart || stale_work(&work) || |
|
|
|
|
|
|
|
work.blk.nonce >= MAXTHREADS - hashes_done) |
|
|
|
needs_work = true; |
|
|
|
needs_work = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2448,6 +2453,7 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1; |
|
|
|
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1; |
|
|
|
unsigned const long request_nonce = MAXTHREADS / 3 * 2; |
|
|
|
unsigned const long request_nonce = MAXTHREADS / 3 * 2; |
|
|
|
bool requested = true; |
|
|
|
bool requested = true; |
|
|
|
|
|
|
|
uint32_t total_hashes = 0, hash_div = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (opt_dynamic) { |
|
|
|
if (opt_dynamic) { |
|
|
|
/* Minimise impact on desktop if we want dynamic mode */ |
|
|
|
/* Minimise impact on desktop if we want dynamic mode */ |
|
|
@ -2477,7 +2483,7 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
{ applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed."); goto out; } |
|
|
|
{ applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed."); goto out; } |
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
if (unlikely(!get_work(work, requested, mythr, thr_id))) { |
|
|
|
if (unlikely(!get_work(work, requested, mythr, thr_id, hash_div))) { |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
"gpu mining thread %d", thr_id); |
|
|
|
"gpu mining thread %d", thr_id); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
@ -2527,7 +2533,7 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
gettimeofday(&tv_workstart, NULL); |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
/* obtain new work from internal workio thread */ |
|
|
|
if (unlikely(!get_work(work, requested, mythr, thr_id))) { |
|
|
|
if (unlikely(!get_work(work, requested, mythr, thr_id, hash_div))) { |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
applog(LOG_ERR, "work retrieval failed, exiting " |
|
|
|
"gpu mining thread %d", thr_id); |
|
|
|
"gpu mining thread %d", thr_id); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
@ -2575,6 +2581,7 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
gettimeofday(&tv_end, NULL); |
|
|
|
gettimeofday(&tv_end, NULL); |
|
|
|
timeval_subtract(&diff, &tv_end, &tv_start); |
|
|
|
timeval_subtract(&diff, &tv_end, &tv_start); |
|
|
|
hashes_done += hashes; |
|
|
|
hashes_done += hashes; |
|
|
|
|
|
|
|
total_hashes += hashes; |
|
|
|
work->blk.nonce += hashes; |
|
|
|
work->blk.nonce += hashes; |
|
|
|
if (diff.tv_usec > 500000) |
|
|
|
if (diff.tv_usec > 500000) |
|
|
|
diff.tv_sec++; |
|
|
|
diff.tv_sec++; |
|
|
@ -2585,7 +2592,10 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
timeval_subtract(&diff, &tv_end, &tv_workstart); |
|
|
|
timeval_subtract(&diff, &tv_end, &tv_workstart); |
|
|
|
if (!requested && (diff.tv_sec > request_interval || work->blk.nonce > request_nonce)) { |
|
|
|
if (!requested) { |
|
|
|
|
|
|
|
if (diff.tv_sec > request_interval) |
|
|
|
|
|
|
|
hash_div = (MAXTHREADS / total_hashes) ? : 1; |
|
|
|
|
|
|
|
if (diff.tv_sec > request_interval || work->blk.nonce > request_nonce) { |
|
|
|
if (unlikely(!queue_request())) { |
|
|
|
if (unlikely(!queue_request())) { |
|
|
|
applog(LOG_ERR, "Failed to queue_request in gpuminer_thread %d", thr_id); |
|
|
|
applog(LOG_ERR, "Failed to queue_request in gpuminer_thread %d", thr_id); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
@ -2593,6 +2603,7 @@ static void *gpuminer_thread(void *userdata) |
|
|
|
requested = true; |
|
|
|
requested = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
out: |
|
|
|
out: |
|
|
|
tq_freeze(mythr->q); |
|
|
|
tq_freeze(mythr->q); |
|
|
|
|
|
|
|
|
|
|
|