Commit 5179d224636ff357420dd11af46ad33cb5e9e8d8

Con Kolivas 2012-01-20T15:36:42

Introduce a --net-delay option which guarantees at least 250ms between any networking requests to not overload slow routers.

diff --git a/README b/README
index 12386bb..8c1c519 100644
--- a/README
+++ b/README
@@ -131,6 +131,7 @@ Options for both config file and command line:
 --load-balance      Change multipool strategy from failover to even load balance
 --log|-l <arg>      Interval in seconds between log output (default: 5)
 --monitor|-m <arg>  Use custom pipe cmd for output messages
+--net-delay         Impose small delays in networking to not overload slow routers
 --no-longpoll       Disable X-Long-Polling support
 --pass|-p <arg>     Password for bitcoin JSON-RPC server
 --per-device-stats  Force verbose mode and output per-device statistics
diff --git a/main.c b/main.c
index 585d21f..69d69e1 100644
--- a/main.c
+++ b/main.c
@@ -239,6 +239,7 @@ char *opt_api_description = PACKAGE_STRING;
 int opt_api_port = 4028;
 bool opt_api_listen = false;
 bool opt_api_network = false;
+bool opt_delaynet = false;
 
 char *opt_kernel_path;
 char *cgminer_path;
@@ -262,6 +263,8 @@ static pthread_mutex_t qd_lock;
 static pthread_mutex_t *stgd_lock;
 static pthread_mutex_t curses_lock;
 static pthread_rwlock_t blk_lock;
+pthread_rwlock_t netacc_lock;
+
 double total_mhashes_done;
 static struct timeval total_tv_start, total_tv_end;
 
@@ -1631,6 +1634,9 @@ static struct opt_table opt_config_table[] = {
 		     opt_set_charp, NULL, &opt_stderr_cmd,
 		     "Use custom pipe cmd for output messages"),
 #endif // defined(unix)
+	OPT_WITHOUT_ARG("--net-delay",
+			opt_set_bool, &opt_delaynet,
+			"Impose small delays in networking to not overload slow routers"),
 #ifdef HAVE_ADL
 	OPT_WITHOUT_ARG("--no-adl",
 			opt_set_bool, &opt_noadl,
@@ -5875,6 +5881,7 @@ int main (int argc, char *argv[])
 	mutex_init(&curses_lock);
 	mutex_init(&control_lock);
 	rwlock_init(&blk_lock);
+	rwlock_init(&netacc_lock);
 
 	sprintf(packagename, "%s %s", PACKAGE, VERSION);
 
diff --git a/miner.h b/miner.h
index a21de5f..9743fd6 100644
--- a/miner.h
+++ b/miner.h
@@ -415,6 +415,9 @@ extern char *opt_api_description;
 extern int opt_api_port;
 extern bool opt_api_listen;
 extern bool opt_api_network;
+extern bool opt_delaynet;
+
+extern pthread_rwlock_t netacc_lock;
 
 extern const uint32_t sha256_init_state[];
 extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
diff --git a/util.c b/util.c
index 48bcf5e..2314339 100644
--- a/util.c
+++ b/util.c
@@ -42,6 +42,7 @@
 #endif
 
 bool successful_connect = false;
+struct timeval nettime;
 
 struct data_buffer {
 	void		*buf;
@@ -286,6 +287,21 @@ int json_rpc_call_sockopt_cb(void *userdata, curl_socket_t fd, curlsocktype purp
 }
 #endif
 
+static void last_nettime(struct timeval *last)
+{
+	rd_lock(&netacc_lock);
+	last->tv_sec = nettime.tv_sec;
+	last->tv_usec = nettime.tv_usec;
+	rd_unlock(&netacc_lock);
+}
+
+static void set_nettime(void)
+{
+	wr_lock(&netacc_lock);
+	gettimeofday(&nettime, NULL);
+	wr_unlock(&netacc_lock);
+}
+
 json_t *json_rpc_call(CURL *curl, const char *url,
 		      const char *userpass, const char *rpc_req,
 		      bool probe, bool longpoll, bool *rolltime,
@@ -358,6 +374,25 @@ json_t *json_rpc_call(CURL *curl, const char *url,
 
 	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
+	if (opt_delaynet) {
+		long long now_msecs, last_msecs;
+		struct timeval now, last;
+
+		gettimeofday(&now, NULL);
+		last_nettime(&last);
+		now_msecs = (long long)now.tv_sec * 1000;
+		now_msecs += now.tv_usec / 1000;
+		last_msecs = (long long)last.tv_sec * 1000;
+		last_msecs += last.tv_usec / 1000;
+		if (now_msecs > last_msecs && now_msecs - last_msecs < 250) {
+			struct timespec rgtp;
+
+			rgtp.tv_sec = 0;
+			rgtp.tv_nsec = (250 - (now_msecs - last_msecs)) * 1000000;
+			nanosleep(&rgtp, NULL);
+		}
+		set_nettime();
+	}
 	rc = curl_easy_perform(curl);
 	if (rc) {
 		applog(LOG_INFO, "HTTP request failed: %s", curl_err_str);