Browse Source

SSM: Split stratum work division into 2D work manager ("work2d")

Luke Dashjr 12 years ago
parent
commit
02b9400c20
4 changed files with 72 additions and 16 deletions
  1. 4 0
      Makefile.am
  2. 7 16
      driver-stratum.c
  3. 47 0
      work2d.c
  4. 14 0
      work2d.h

+ 4 - 0
Makefile.am

@@ -198,6 +198,10 @@ if NEED_DYNCLOCK
 bfgminer_SOURCES += dynclock.c dynclock.h
 endif
 
+if USE_LIBEVENT
+bfgminer_SOURCES  += work2d.c work2d.h
+endif
+
 if HAS_FPGA
 dist_doc_DATA += README.FPGA
 endif

+ 7 - 16
driver-stratum.c

@@ -30,12 +30,10 @@
 #include "driver-proxy.h"
 #include "miner.h"
 #include "util.h"
+#include "work2d.h"
 
-#define MAX_CLIENTS 255
-
-static bool _ssm_xnonce1s[MAX_CLIENTS + 1] = { true };
-static uint8_t _ssm_client_octets;
-static uint8_t _ssm_client_xnonce2sz;
+#define _ssm_client_octets     work2d_xnonce1sz
+#define _ssm_client_xnonce2sz  work2d_xnonce2sz
 static char *_ssm_notify;
 static int _ssm_notify_sz;
 static struct event *ev_notify;
@@ -368,12 +366,8 @@ void stratumsrv_mining_subscribe(struct bufferevent *bev, json_t *params, const
 	
 	if (!*xnonce1_p)
 	{
-		uint32_t xnonce1;
-		for (xnonce1 = MAX_CLIENTS; _ssm_xnonce1s[xnonce1]; --xnonce1)
-			if (!xnonce1)
-				return_stratumsrv_failure(20, "Maximum clients already connected");
-		_ssm_xnonce1s[xnonce1] = true;
-		*xnonce1_p = htole32(xnonce1);
+		if (!reserve_work2d_(xnonce1_p))
+			return_stratumsrv_failure(20, "Maximum clients already connected");
 	}
 	
 	bin2hex(xnonce1x, xnonce1_p, _ssm_client_octets);
@@ -540,12 +534,11 @@ static
 void stratumsrv_client_close(struct stratumsrv_conn * const conn)
 {
 	struct bufferevent * const bev = conn->bev;
-	uint32_t xnonce1 = le32toh(conn->xnonce1_le);
 	
 	bufferevent_free(bev);
 	LL_DELETE(_ssm_connections, conn);
+	release_work2d_(conn->xnonce1_le);
 	free(conn);
-	_ssm_xnonce1s[xnonce1] = false;
 }
 
 static
@@ -626,9 +619,7 @@ void *stratumsrv_thread(__maybe_unused void *p)
 	pthread_detach(pthread_self());
 	RenameThread("stratumsrv");
 	
-	for (uint64_t n = MAX_CLIENTS; n; n >>= 8)
-		++_ssm_client_octets;
-	_ssm_client_xnonce2sz = 2;
+	work2d_init();
 	
 	struct event_base *evbase = event_base_new();
 	_smm_evbase = evbase;

+ 47 - 0
work2d.c

@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013-2014 Luke Dashjr
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#include "config.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "miner.h"
+
+#define MAX_DIVISIONS 255
+
+static bool work2d_reserved[MAX_DIVISIONS + 1] = { true };
+int work2d_xnonce1sz;
+int work2d_xnonce2sz;
+
+void work2d_init()
+{
+	RUNONCE();
+	
+	for (uint64_t n = MAX_DIVISIONS; n; n >>= 8)
+		++work2d_xnonce1sz;
+	work2d_xnonce2sz = 2;
+}
+
+bool reserve_work2d_(uint32_t * const xnonce1_p)
+{
+	uint32_t xnonce1;
+	for (xnonce1 = MAX_DIVISIONS; work2d_reserved[xnonce1]; --xnonce1)
+		if (!xnonce1)
+			return false;
+	work2d_reserved[xnonce1] = true;
+	*xnonce1_p = htole32(xnonce1);
+	return true;
+}
+
+void release_work2d_(uint32_t xnonce1)
+{
+	xnonce1 = le32toh(xnonce1);
+	work2d_reserved[xnonce1] = false;
+}

+ 14 - 0
work2d.h

@@ -0,0 +1,14 @@
+#ifndef BFG_WORK2D_H
+#define BFG_WORK2D_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+extern int work2d_xnonce1sz;
+extern int work2d_xnonce2sz;
+
+extern void work2d_init();
+extern bool reserve_work2d_(uint32_t *xnonce1_p);
+extern void release_work2d_(uint32_t xnonce1);
+
+#endif