|
|
|
@ -64,7 +64,6 @@
@@ -64,7 +64,6 @@
|
|
|
|
|
|
|
|
|
|
enum workio_commands { |
|
|
|
|
WC_GET_WORK, |
|
|
|
|
WC_SUBMIT_WORK, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct workio_cmd { |
|
|
|
@ -2737,11 +2736,8 @@ static void workio_cmd_free(struct workio_cmd *wc)
@@ -2737,11 +2736,8 @@ static void workio_cmd_free(struct workio_cmd *wc)
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
switch (wc->cmd) { |
|
|
|
|
case WC_SUBMIT_WORK: |
|
|
|
|
free_work(wc->work); |
|
|
|
|
break; |
|
|
|
|
default: /* do nothing */ |
|
|
|
|
break; |
|
|
|
|
default: /* do nothing */ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset(wc, 0, sizeof(*wc)); /* poison */ |
|
|
|
@ -3284,8 +3280,7 @@ static void check_solve(struct work *work)
@@ -3284,8 +3280,7 @@ static void check_solve(struct work *work)
|
|
|
|
|
|
|
|
|
|
static void *submit_work_thread(void *userdata) |
|
|
|
|
{ |
|
|
|
|
struct workio_cmd *wc = (struct workio_cmd *)userdata; |
|
|
|
|
struct work *work = wc->work; |
|
|
|
|
struct work *work = (struct work *)userdata; |
|
|
|
|
struct pool *pool = work->pool; |
|
|
|
|
bool resubmit = false; |
|
|
|
|
struct curl_ent *ce; |
|
|
|
@ -3374,25 +3369,9 @@ static void *submit_work_thread(void *userdata)
@@ -3374,25 +3369,9 @@ static void *submit_work_thread(void *userdata)
|
|
|
|
|
} |
|
|
|
|
push_curl_entry(ce, pool); |
|
|
|
|
out: |
|
|
|
|
workio_cmd_free(wc); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* We try to reuse curl handles as much as possible, but if there is already
|
|
|
|
|
* work queued to be submitted, we start generating extra handles to submit |
|
|
|
|
* the shares to avoid ever increasing backlogs. This allows us to scale to |
|
|
|
|
* any size hardware */ |
|
|
|
|
static bool workio_submit_work(struct workio_cmd *wc) |
|
|
|
|
{ |
|
|
|
|
pthread_t submit_thread; |
|
|
|
|
|
|
|
|
|
if (unlikely(pthread_create(&submit_thread, NULL, submit_work_thread, (void *)wc))) { |
|
|
|
|
applog(LOG_ERR, "Failed to create submit_work_thread"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Find the pool that currently has the highest priority */ |
|
|
|
|
static struct pool *priority_pool(int choice) |
|
|
|
|
{ |
|
|
|
@ -4482,9 +4461,6 @@ static void *workio_thread(void *userdata)
@@ -4482,9 +4461,6 @@ static void *workio_thread(void *userdata)
|
|
|
|
|
case WC_GET_WORK: |
|
|
|
|
ok = workio_get_work(wc); |
|
|
|
|
break; |
|
|
|
|
case WC_SUBMIT_WORK: |
|
|
|
|
ok = workio_submit_work(wc); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
ok = false; |
|
|
|
|
break; |
|
|
|
@ -5454,35 +5430,16 @@ out:
@@ -5454,35 +5430,16 @@ out:
|
|
|
|
|
work->mined = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool submit_work_sync(struct thr_info *thr, struct work *work_in, struct timeval *tv_work_found) |
|
|
|
|
void submit_work_async(struct work *work_in, struct timeval *tv_work_found) |
|
|
|
|
{ |
|
|
|
|
struct workio_cmd *wc; |
|
|
|
|
|
|
|
|
|
/* fill out work request message */ |
|
|
|
|
wc = calloc(1, sizeof(*wc)); |
|
|
|
|
if (unlikely(!wc)) { |
|
|
|
|
applog(LOG_ERR, "Failed to calloc wc in submit_work_sync"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
struct work *work = copy_work(work_in); |
|
|
|
|
pthread_t submit_thread; |
|
|
|
|
|
|
|
|
|
wc->work = copy_work(work_in); |
|
|
|
|
wc->cmd = WC_SUBMIT_WORK; |
|
|
|
|
wc->thr = thr; |
|
|
|
|
if (tv_work_found) |
|
|
|
|
memcpy(&(wc->work->tv_work_found), tv_work_found, sizeof(struct timeval)); |
|
|
|
|
|
|
|
|
|
memcpy(&(work->tv_work_found), tv_work_found, sizeof(struct timeval)); |
|
|
|
|
applog(LOG_DEBUG, "Pushing submit work to work thread"); |
|
|
|
|
|
|
|
|
|
/* send solution to workio thread */ |
|
|
|
|
if (unlikely(!tq_push(thr_info[work_thr_id].q, wc))) { |
|
|
|
|
applog(LOG_ERR, "Failed to tq_push work in submit_work_sync"); |
|
|
|
|
goto err_out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
err_out: |
|
|
|
|
workio_cmd_free(wc); |
|
|
|
|
return false; |
|
|
|
|
if (unlikely(pthread_create(&submit_thread, NULL, submit_work_thread, (void *)work))) |
|
|
|
|
quit(1, "Failed to create submit_work_thread"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool hashtest(struct thr_info *thr, struct work *work) |
|
|
|
@ -5552,7 +5509,7 @@ static bool test_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
@@ -5552,7 +5509,7 @@ static bool test_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
|
|
|
|
return hashtest(thr, work); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) |
|
|
|
|
void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) |
|
|
|
|
{ |
|
|
|
|
struct timeval tv_work_found; |
|
|
|
|
gettimeofday(&tv_work_found, NULL); |
|
|
|
@ -5566,9 +5523,9 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
@@ -5566,9 +5523,9 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
|
|
|
|
/* Do one last check before attempting to submit the work */ |
|
|
|
|
/* Side effect: sets work->data for us */ |
|
|
|
|
if (!test_nonce(thr, work, nonce)) |
|
|
|
|
return true; |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
return submit_work_sync(thr, work, &tv_work_found); |
|
|
|
|
submit_work_async(work, &tv_work_found); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes) |
|
|
|
|