Browse Source

Defer submissions instead of blocking in pop_curl_entry

Luke Dashjr 13 years ago
parent
commit
1487097086
3 changed files with 44 additions and 13 deletions
  1. 1 1
      README
  2. 42 12
      miner.c
  3. 1 0
      miner.h

+ 1 - 1
README

@@ -163,7 +163,7 @@ Options for both config file and command line:
 --shares <arg>      Quit after mining N shares (default: unlimited)
 --shares <arg>      Quit after mining N shares (default: unlimited)
 --skip-security-checks <arg> Skip security checks sometimes to save bandwidth; only check 1/<arg>th of the time (default: never skip)
 --skip-security-checks <arg> Skip security checks sometimes to save bandwidth; only check 1/<arg>th of the time (default: never skip)
 --socks-proxy <arg> Set socks4 proxy (host:port) for all pools without a proxy specified
 --socks-proxy <arg> Set socks4 proxy (host:port) for all pools without a proxy specified
---submit-threads    Maximum number of share submission threads (default: 64)
+--submit-threads    Minimum number of concurrent share submissions (default: 64)
 --syslog            Use system log for output messages (default: standard error)
 --syslog            Use system log for output messages (default: standard error)
 --temp-cutoff <arg> Temperature where a device will be automatically disabled, one value or comma separated list (default: 95)
 --temp-cutoff <arg> Temperature where a device will be automatically disabled, one value or comma separated list (default: 95)
 --temp-hysteresis <arg> Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3)
 --temp-hysteresis <arg> Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3)

+ 42 - 12
miner.c

@@ -1327,7 +1327,7 @@ static struct opt_table opt_config_table[] = {
 	                opt_hidden),
 	                opt_hidden),
 	OPT_WITHOUT_ARG("--submit-threads",
 	OPT_WITHOUT_ARG("--submit-threads",
 	                opt_set_intval, &opt_submit_threads,
 	                opt_set_intval, &opt_submit_threads,
-	                "Maximum number of share submission threads (default: 64)"),
+	                "Minimum number of concurrent share submissions (default: 64)"),
 #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,
@@ -3184,7 +3184,7 @@ static void recruit_curl(struct pool *pool)
  * and there are already 5 curls in circulation. Limit total number to the
  * and there are already 5 curls in circulation. Limit total number to the
  * number of mining threads per pool as well to prevent blasting a pool during
  * number of mining threads per pool as well to prevent blasting a pool during
  * network delays/outages. */
  * network delays/outages. */
-static struct curl_ent *pop_curl_entry(struct pool *pool)
+static struct curl_ent *pop_curl_entry2(struct pool *pool, bool blocking)
 {
 {
 	int curl_limit = opt_delaynet ? 5 : (mining_threads + opt_queue) * 2;
 	int curl_limit = opt_delaynet ? 5 : (mining_threads + opt_queue) * 2;
 	struct curl_ent *ce;
 	struct curl_ent *ce;
@@ -3194,7 +3194,11 @@ retry:
 	if (!pool->curls)
 	if (!pool->curls)
 		recruit_curl(pool);
 		recruit_curl(pool);
 	else if (list_empty(&pool->curlring)) {
 	else if (list_empty(&pool->curlring)) {
-		if (pool->curls >= curl_limit) {
+		if (pool->curls >= curl_limit && (blocking || pool->curls >= opt_submit_threads)) {
+			if (!blocking) {
+				mutex_unlock(&pool->pool_lock);
+				return NULL;
+			}
 			pthread_cond_wait(&pool->cr_cond, &pool->pool_lock);
 			pthread_cond_wait(&pool->cr_cond, &pool->pool_lock);
 			goto retry;
 			goto retry;
 		} else
 		} else
@@ -3207,6 +3211,11 @@ retry:
 	return ce;
 	return ce;
 }
 }
 
 
+static struct curl_ent *pop_curl_entry(struct pool *pool)
+{
+	return pop_curl_entry2(pool, true);
+}
+
 static void push_curl_entry(struct curl_ent *ce, struct pool *pool)
 static void push_curl_entry(struct curl_ent *ce, struct pool *pool)
 {
 {
 	mutex_lock(&pool->pool_lock);
 	mutex_lock(&pool->pool_lock);
@@ -3657,6 +3666,14 @@ static int my_curl_timer_set(__maybe_unused CURLM *curlm, long timeout_ms, void
 	return 0;
 	return 0;
 }
 }
 
 
+static void sws_has_ce(struct submit_work_state *sws)
+{
+	struct pool *pool = sws->work->pool;
+	sws->s = submit_upstream_work_request(sws->work);
+	gettimeofday(&sws->tv_submit, NULL);
+	json_rpc_call_async(sws->ce->curl, pool->rpc_url, pool->rpc_userpass, sws->s, false, pool, true, sws);
+}
+
 static struct submit_work_state *begin_submission(struct workio_cmd *wc)
 static struct submit_work_state *begin_submission(struct workio_cmd *wc)
 {
 {
 	struct work *work;
 	struct work *work;
@@ -3709,11 +3726,17 @@ static struct submit_work_state *begin_submission(struct workio_cmd *wc)
 		sws->s = s;
 		sws->s = s;
 	} else {
 	} else {
 		/* submit solution to bitcoin via JSON-RPC */
 		/* submit solution to bitcoin via JSON-RPC */
-		sws->ce = pop_curl_entry(pool);
-		sws->s = submit_upstream_work_request(work);
-
-		gettimeofday(&sws->tv_submit, NULL);
-		json_rpc_call_async(sws->ce->curl, pool->rpc_url, pool->rpc_userpass, sws->s, false, pool, true, sws);
+		sws->ce = pop_curl_entry2(pool, false);
+		if (sws->ce) {
+			sws_has_ce(sws);
+		} else {
+			sws->next = pool->sws_waiting_on_curl;
+			pool->sws_waiting_on_curl = sws;
+			if (sws->next)
+				applog(LOG_DEBUG, "submit_thread queuing submission");
+			else
+				applog(LOG_WARNING, "submit_thread queuing submissions (see --submit-threads)");
+		}
 	}
 	}
 
 
 	wc->work = NULL;
 	wc->work = NULL;
@@ -3769,8 +3792,6 @@ static bool retry_submission(struct submit_work_state *sws)
 
 
 static void free_sws(struct submit_work_state *sws)
 static void free_sws(struct submit_work_state *sws)
 {
 {
-	if (sws->ce)
-		push_curl_entry(sws->ce, sws->work->pool);
 	free(sws->s);
 	free(sws->s);
 	free_work(sws->work);
 	free_work(sws->work);
 	free(sws);
 	free(sws);
@@ -3799,6 +3820,7 @@ static void *submit_work_thread(void *userdata)
 		if (sws->ce)
 		if (sws->ce)
 			curl_multi_add_handle(curlm, sws->ce->curl);
 			curl_multi_add_handle(curlm, sws->ce->curl);
 		else
 		else
+		if (sws->s)
 			write_sws = sws;
 			write_sws = sws;
 		++wip;
 		++wip;
 	}
 	}
@@ -3821,7 +3843,7 @@ static void *submit_work_thread(void *userdata)
 			if ( (sws = begin_submission(wc)) ) {
 			if ( (sws = begin_submission(wc)) ) {
 				if (sws->ce)
 				if (sws->ce)
 					curl_multi_add_handle(curlm, sws->ce->curl);
 					curl_multi_add_handle(curlm, sws->ce->curl);
-				else {
+				else if (sws->s) {
 					sws->next = write_sws;
 					sws->next = write_sws;
 					write_sws = sws;
 					write_sws = sws;
 				}
 				}
@@ -3896,7 +3918,15 @@ static void *submit_work_thread(void *userdata)
 				json_t *val = json_rpc_call_completed(cm->easy_handle, cm->data.result, false, NULL, &sws);
 				json_t *val = json_rpc_call_completed(cm->easy_handle, cm->data.result, false, NULL, &sws);
 				if (submit_upstream_work_completed(sws->work, sws->resubmit, &sws->tv_submit, val) || !retry_submission(sws)) {
 				if (submit_upstream_work_completed(sws->work, sws->resubmit, &sws->tv_submit, val) || !retry_submission(sws)) {
 					--wip;
 					--wip;
-					curl_multi_remove_handle(curlm, cm->easy_handle);
+					struct pool *pool = sws->work->pool;
+					if (pool->sws_waiting_on_curl) {
+						pool->sws_waiting_on_curl->ce = sws->ce;
+						sws_has_ce(pool->sws_waiting_on_curl);
+						pool->sws_waiting_on_curl = pool->sws_waiting_on_curl->next;
+					} else {
+						curl_multi_remove_handle(curlm, cm->easy_handle);
+						push_curl_entry(sws->ce, sws->work->pool);
+					}
 					free_sws(sws);
 					free_sws(sws);
 				}
 				}
 			}
 			}

+ 1 - 0
miner.h

@@ -980,6 +980,7 @@ struct pool {
 	int curls;
 	int curls;
 	pthread_cond_t cr_cond;
 	pthread_cond_t cr_cond;
 	struct list_head curlring;
 	struct list_head curlring;
+	struct submit_work_state *sws_waiting_on_curl;
 
 
 	time_t last_share_time;
 	time_t last_share_time;
 	double last_share_diff;
 	double last_share_diff;