|
|
@ -180,7 +180,7 @@ static unsigned int new_blocks; |
|
|
|
static unsigned int local_work; |
|
|
|
static unsigned int local_work; |
|
|
|
static unsigned int total_lo, total_ro; |
|
|
|
static unsigned int total_lo, total_ro; |
|
|
|
|
|
|
|
|
|
|
|
static struct pool *pools; |
|
|
|
static struct pool *pools = NULL; |
|
|
|
static struct pool *cp; /* Current pool */ |
|
|
|
static struct pool *cp; /* Current pool */ |
|
|
|
static int total_pools; |
|
|
|
static int total_pools; |
|
|
|
|
|
|
|
|
|
|
@ -208,13 +208,43 @@ static void applog_and_exit(const char *fmt, ...) |
|
|
|
|
|
|
|
|
|
|
|
static void add_pool(void) |
|
|
|
static void add_pool(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
struct pool *pool; |
|
|
|
|
|
|
|
|
|
|
|
total_pools++; |
|
|
|
total_pools++; |
|
|
|
pools = realloc(pools, sizeof(struct pool) * total_pools); |
|
|
|
pools = realloc(pools, sizeof(struct pool) * total_pools); |
|
|
|
if (!pools) { |
|
|
|
if (!pools) { |
|
|
|
applog(LOG_ERR, "Failed to malloc pools in add_pool"); |
|
|
|
applog(LOG_ERR, "Failed to malloc pools in add_pool"); |
|
|
|
exit (1); |
|
|
|
exit (1); |
|
|
|
} |
|
|
|
} |
|
|
|
memset(&pools[total_pools - 1], 0, sizeof(struct pool)); |
|
|
|
pool = &pools[total_pools - 1]; |
|
|
|
|
|
|
|
memset(pool, 0, sizeof(struct pool)); |
|
|
|
|
|
|
|
if (unlikely(pthread_mutex_init(&pool->pool_lock, NULL))) { |
|
|
|
|
|
|
|
applog(LOG_ERR, "Failed to pthread_mutex_init in add_pool"); |
|
|
|
|
|
|
|
exit (1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Pool variant of test and set */ |
|
|
|
|
|
|
|
static bool pool_tset(struct pool *pool, bool *var) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&pool->pool_lock); |
|
|
|
|
|
|
|
ret = *var; |
|
|
|
|
|
|
|
*var = true; |
|
|
|
|
|
|
|
pthread_mutex_unlock(&pool->pool_lock); |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool pool_tclear(struct pool *pool, bool *var) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&pool->pool_lock); |
|
|
|
|
|
|
|
ret = *var; |
|
|
|
|
|
|
|
*var = false; |
|
|
|
|
|
|
|
pthread_mutex_unlock(&pool->pool_lock); |
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: Use asprintf for better errors. */ |
|
|
|
/* FIXME: Use asprintf for better errors. */ |
|
|
@ -728,13 +758,13 @@ static bool submit_upstream_work(const struct work *work) |
|
|
|
val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, s, false, false); |
|
|
|
val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, s, false, false); |
|
|
|
if (unlikely(!val)) { |
|
|
|
if (unlikely(!val)) { |
|
|
|
applog(LOG_INFO, "submit_upstream_work json_rpc_call failed"); |
|
|
|
applog(LOG_INFO, "submit_upstream_work json_rpc_call failed"); |
|
|
|
if (!test_and_set(&pool->submit_fail)) { |
|
|
|
if (!pool_tset(pool, &pool->submit_fail)) { |
|
|
|
total_ro++; |
|
|
|
total_ro++; |
|
|
|
pool->remotefail_occasions++; |
|
|
|
pool->remotefail_occasions++; |
|
|
|
applog(LOG_WARNING, "Upstream communication failure, caching submissions"); |
|
|
|
applog(LOG_WARNING, "Upstream communication failure, caching submissions"); |
|
|
|
} |
|
|
|
} |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} else if (test_and_clear(&pool->submit_fail)) |
|
|
|
} else if (pool_tclear(pool, &pool->submit_fail)) |
|
|
|
applog(LOG_WARNING, "Upstream communication resumed, submitting work"); |
|
|
|
applog(LOG_WARNING, "Upstream communication resumed, submitting work"); |
|
|
|
|
|
|
|
|
|
|
|
res = json_object_get(val, "result"); |
|
|
|
res = json_object_get(val, "result"); |
|
|
@ -1368,7 +1398,7 @@ retry: |
|
|
|
uint32_t ntime; |
|
|
|
uint32_t ntime; |
|
|
|
|
|
|
|
|
|
|
|
/* Only print this message once each time we shift to localgen */ |
|
|
|
/* Only print this message once each time we shift to localgen */ |
|
|
|
if (!test_and_set(&pool->localgen)) { |
|
|
|
if (!pool_tset(pool, &pool->localgen)) { |
|
|
|
applog(LOG_WARNING, "Server not providing work fast enough, generating work locally"); |
|
|
|
applog(LOG_WARNING, "Server not providing work fast enough, generating work locally"); |
|
|
|
pool->localgen_occasions++; |
|
|
|
pool->localgen_occasions++; |
|
|
|
total_lo++; |
|
|
|
total_lo++; |
|
|
@ -1404,7 +1434,7 @@ retry: |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* If we make it here we have succeeded in getting fresh work */ |
|
|
|
/* If we make it here we have succeeded in getting fresh work */ |
|
|
|
if (test_and_clear(&pool->localgen)) |
|
|
|
if (pool_tclear(pool, &pool->localgen)) |
|
|
|
applog(LOG_WARNING, "Resuming with work from server"); |
|
|
|
applog(LOG_WARNING, "Resuming with work from server"); |
|
|
|
dec_queued(); |
|
|
|
dec_queued(); |
|
|
|
|
|
|
|
|
|
|
@ -2569,8 +2599,9 @@ int main (int argc, char *argv[]) |
|
|
|
free(gpus); |
|
|
|
free(gpus); |
|
|
|
if (opt_n_threads) |
|
|
|
if (opt_n_threads) |
|
|
|
free(cpus); |
|
|
|
free(cpus); |
|
|
|
|
|
|
|
if (pools) |
|
|
|
|
|
|
|
free(pools); |
|
|
|
|
|
|
|
|
|
|
|
free(pools); |
|
|
|
|
|
|
|
curl_global_cleanup(); |
|
|
|
curl_global_cleanup(); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|