Allocate work struct once, on stack, rather than alloc+free for each getwork.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
diff --git a/Makefile.am b/Makefile.am
index 8032eec..b0f5a61 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
-INCLUDES = -pthread
+INCLUDES = -pthread -fno-strict-aliasing
bin_PROGRAMS = minerd
diff --git a/cpu-miner.c b/cpu-miner.c
index 4985a07..a2c9569 100644
--- a/cpu-miner.c
+++ b/cpu-miner.c
@@ -82,11 +82,12 @@ struct upload_buffer {
};
struct work {
- unsigned char midstate[32];
unsigned char data[128];
- unsigned char hash[32];
unsigned char hash1[64];
+ unsigned char midstate[32];
unsigned char target[32];
+
+ unsigned char hash[32];
};
static void databuf_free(struct data_buffer *db)
@@ -141,8 +142,7 @@ static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb,
return len;
}
-static json_t *json_rpc_call(const char *url, const char *userpass,
- const char *rpc_req)
+static json_t *json_rpc_call(const char *url, const char *rpc_req)
{
CURL *curl;
json_t *val;
@@ -282,22 +282,8 @@ static bool jobj_binary(const json_t *obj, const char *key,
return true;
}
-static void work_free(struct work *work)
+static bool work_decode(const json_t *val, struct work *work)
{
- if (!work)
- return;
-
- free(work);
-}
-
-static struct work *work_decode(const json_t *val)
-{
- struct work *work;
-
- work = calloc(1, sizeof(*work));
- if (!work)
- return NULL;
-
if (!jobj_binary(val, "midstate",
work->midstate, sizeof(work->midstate))) {
fprintf(stderr, "JSON inval midstate\n");
@@ -319,11 +305,12 @@ static struct work *work_decode(const json_t *val)
goto err_out;
}
- return work;
+ memset(work->hash, 0, sizeof(work->hash));
+
+ return true;
err_out:
- work_free(work);
- return NULL;
+ return false;
}
static void inc_stats(uint64_t n_hashes)
@@ -415,7 +402,7 @@ static void submit_work(struct work *work)
fprintf(stderr, "DBG: sending RPC call:\n%s", s);
/* issue JSON-RPC request */
- val = json_rpc_call(rpc_url, userpass, s);
+ val = json_rpc_call(rpc_url, s);
if (!val) {
fprintf(stderr, "submit_work json_rpc_call failed\n");
goto out;
@@ -440,19 +427,20 @@ static void *miner_thread(void *dummy)
while (1) {
json_t *val;
- struct work *work;
+ struct work work __attribute__((aligned(128)));
uint32_t nonce;
+ bool rc;
/* obtain new work from bitcoin */
- val = json_rpc_call(rpc_url, userpass, rpc_req);
+ val = json_rpc_call(rpc_url, rpc_req);
if (!val) {
fprintf(stderr, "json_rpc_call failed\n");
return NULL;
}
/* decode result into work state struct */
- work = work_decode(json_object_get(val, "result"));
- if (!work) {
+ rc = work_decode(json_object_get(val, "result"), &work);
+ if (!rc) {
fprintf(stderr, "work decode failed\n");
return NULL;
}
@@ -460,14 +448,12 @@ static void *miner_thread(void *dummy)
json_decref(val);
/* scan nonces for a proof-of-work hash */
- nonce = scanhash(work->midstate, work->data + 64,
- work->hash1, work->hash);
+ nonce = scanhash(work.midstate, work.data + 64,
+ work.hash1, work.hash);
/* if nonce found, submit work */
if (nonce)
- submit_work(work);
-
- work_free(work);
+ submit_work(&work);
}
return NULL;