diff --git a/src/pow_avx.c b/src/pow_avx.c index faa5cec..1e789e4 100644 --- a/src/pow_avx.c +++ b/src/pow_avx.c @@ -159,12 +159,15 @@ static int loop256(__m256i *lmid, __m256i *hmid, int m, int8_t *nonce, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { int i = 0, n = 0; __m256i lcpy[STATE_TRITS_LENGTH * 2], hcpy[STATE_TRITS_LENGTH * 2]; + uv_rwlock_rdlock(lock); for (i = 0; !incr256(lmid, hmid) && !*stopPoW; i++) { + uv_rwlock_rdunlock(lock); for (int j = 0; j < STATE_TRITS_LENGTH; j++) { lcpy[j] = lmid[j]; hcpy[j] = hmid[j]; @@ -175,7 +178,9 @@ static int loop256(__m256i *lmid, seri256(lmid, hmid, n, nonce); return i * 256; } + uv_rwlock_rdlock(lock); } + uv_rwlock_rdunlock(lock); return -i * 256 - 1; } @@ -183,7 +188,8 @@ static int64_t pwork256(int8_t mid[], int mwm, int8_t nonce[], int n, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { __m256i lmid[STATE_TRITS_LENGTH], hmid[STATE_TRITS_LENGTH]; int offset = HASH_TRITS_LENGTH - NONCE_TRITS_LENGTH; @@ -202,7 +208,7 @@ static int64_t pwork256(int8_t mid[], hmid[offset + 5] = _mm256_set_epi64x(HIGH50, HIGH51, HIGH52, HIGH53); incrN256(n, lmid, hmid); - return loop256(lmid, hmid, mwm, nonce, stopPoW); + return loop256(lmid, hmid, mwm, nonce, stopPoW, lock); } #else /* AVX1 */ @@ -360,12 +366,15 @@ static int loop256(__m256d *lmid, __m256d *hmid, int m, int8_t *nonce, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { int i = 0, n = 0, j = 0; __m256d lcpy[STATE_TRITS_LENGTH * 2], hcpy[STATE_TRITS_LENGTH * 2]; + uv_rwlock_rdlock(lock); for (i = 0; !incr256(lmid, hmid) && !*stopPoW; i++) { + uv_rwlock_rdunlock(lock); for (j = 0; j < STATE_TRITS_LENGTH; j++) { lcpy[j] = lmid[j]; hcpy[j] = hmid[j]; @@ -376,7 +385,9 @@ static int loop256(__m256d *lmid, seri256(lmid, hmid, n, nonce); return i * 256; } + uv_rwlock_rdlock(lock); } + uv_rwlock_rdunlock(lock); return -i * 256 - 1; } @@ -384,7 +395,8 @@ static long long int pwork256(int8_t mid[], int mwm, int8_t nonce[], int n, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { __m256d lmid[STATE_TRITS_LENGTH], hmid[STATE_TRITS_LENGTH]; int offset = HASH_TRITS_LENGTH - NONCE_TRITS_LENGTH; @@ -403,7 +415,7 @@ static long long int pwork256(int8_t mid[], hmid[offset + 5] = _mm256_set_pd(HIGH50, HIGH51, HIGH52, HIGH53); incrN256(n, lmid, hmid); - return loop256(lmid, hmid, mwm, nonce, stopPoW); + return loop256(lmid, hmid, mwm, nonce, stopPoW, lock); } #endif /* __AVX2__ */ @@ -411,16 +423,17 @@ static long long int pwork256(int8_t mid[], static void work_cb(uv_work_t *req) { Pwork_struct *pworkInfo = (Pwork_struct *) req->data; - pworkInfo->ret = pwork256(pworkInfo->mid, pworkInfo->mwm, pworkInfo->nonce, - pworkInfo->n, pworkInfo->stopPoW); + pworkInfo->ret = + pwork256(pworkInfo->mid, pworkInfo->mwm, pworkInfo->nonce, pworkInfo->n, + pworkInfo->stopPoW, pworkInfo->lock); - pthread_mutex_lock(pworkInfo->lock); + uv_rwlock_wrlock(pworkInfo->lock); if (pworkInfo->ret >= 0) { *pworkInfo->stopPoW = 1; /* This means this thread got the result */ pworkInfo->n = -1; } - pthread_mutex_unlock(pworkInfo->lock); + uv_rwlock_wrunlock(pworkInfo->lock); } static int8_t *tx_to_cstate(Trytes_t *tx) @@ -490,7 +503,7 @@ static bool PowAVX(void *pow_ctx) ctx->stopPoW = 0; ctx->pow_info.time = 0; ctx->pow_info.hash_count = 0; - pthread_mutex_init(&ctx->lock, NULL); + uv_rwlock_init(&ctx->lock); uv_loop_t *loop_ptr = &ctx->loop; uv_work_t *work_req = ctx->work_req; Pwork_struct *pitem = ctx->pitem; @@ -548,7 +561,8 @@ static bool PowAVX(void *pow_ctx) nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); fail: - /* Free memory */ + /* Free resource */ + uv_rwlock_destroy(&ctx->lock); free(c_state); freeTrobject(tx_tryte); freeTrobject(nonce_trit); diff --git a/src/pow_avx.h b/src/pow_avx.h index 809ecd9..6103e51 100644 --- a/src/pow_avx.h +++ b/src/pow_avx.h @@ -16,7 +16,7 @@ struct _pwork_struct { int mwm; int8_t *nonce; int n; - pthread_mutex_t *lock; + uv_rwlock_t *lock; int *stopPoW; int64_t ret; }; @@ -25,7 +25,7 @@ typedef struct _pow_avx_context PoW_AVX_Context; struct _pow_avx_context { /* Resource of computing */ - pthread_mutex_t lock; + uv_rwlock_t lock; /* Data type of libtuv */ uv_loop_t loop; uv_work_t *work_req; diff --git a/src/pow_c.c b/src/pow_c.c index 9f11fd2..10f6cd9 100644 --- a/src/pow_c.c +++ b/src/pow_c.c @@ -105,13 +105,16 @@ static long long int loop_cpu(uint64_t *lmid, uint64_t *hmid, int m, int8_t *nonce, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { int n = 0; long long int i = 0; uint64_t lcpy[STATE_TRITS_LENGTH * 2], hcpy[STATE_TRITS_LENGTH * 2]; + uv_rwlock_rdlock(lock); for (i = 0; !incr(lmid, hmid) && !*stopPoW; i++) { + uv_rwlock_rdunlock(lock); memcpy(lcpy, lmid, STATE_TRITS_LENGTH * sizeof(uint64_t)); memcpy(hcpy, hmid, STATE_TRITS_LENGTH * sizeof(uint64_t)); transform64(lcpy, hcpy); @@ -120,7 +123,9 @@ static long long int loop_cpu(uint64_t *lmid, seri(lmid, hmid, n, nonce); return i * 64; } + uv_rwlock_rdlock(lock); } + uv_rwlock_rdunlock(lock); return -i * 64 - 1; } @@ -157,7 +162,12 @@ static void incrN(int n, uint64_t *mid_low, uint64_t *mid_high) } } -static int64_t pwork(int8_t mid[], int mwm, int8_t nonce[], int n, int *stopPoW) +static int64_t pwork(int8_t mid[], + int mwm, + int8_t nonce[], + int n, + int *stopPoW, + uv_rwlock_t *lock) { uint64_t lmid[STATE_TRITS_LENGTH] = {0}, hmid[STATE_TRITS_LENGTH] = {0}; para(mid, lmid, hmid); @@ -173,22 +183,22 @@ static int64_t pwork(int8_t mid[], int mwm, int8_t nonce[], int n, int *stopPoW) hmid[offset + 3] = HIGH3; incrN(n, lmid, hmid); - return loop_cpu(lmid, hmid, mwm, nonce, stopPoW); + return loop_cpu(lmid, hmid, mwm, nonce, stopPoW, lock); } static void work_cb(uv_work_t *req) { Pwork_struct *pworkInfo = (Pwork_struct *) req->data; pworkInfo->ret = pwork(pworkInfo->mid, pworkInfo->mwm, pworkInfo->nonce, - pworkInfo->n, pworkInfo->stopPoW); + pworkInfo->n, pworkInfo->stopPoW, pworkInfo->lock); - pthread_mutex_lock(pworkInfo->lock); + uv_rwlock_wrlock(pworkInfo->lock); if (pworkInfo->ret >= 0) { *pworkInfo->stopPoW = 1; /* This means this thread got the result */ pworkInfo->n = -1; } - pthread_mutex_unlock(pworkInfo->lock); + uv_rwlock_wrunlock(pworkInfo->lock); } static int8_t *tx_to_cstate(Trytes_t *tx) @@ -258,7 +268,7 @@ bool PowC(void *pow_ctx) ctx->stopPoW = 0; ctx->pow_info.time = 0; ctx->pow_info.hash_count = 0; - pthread_mutex_init(&ctx->lock, NULL); + uv_rwlock_init(&ctx->lock); uv_loop_t *loop_ptr = &ctx->loop; uv_work_t *work_req = ctx->work_req; Pwork_struct *pitem = ctx->pitem; @@ -316,7 +326,8 @@ bool PowC(void *pow_ctx) nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); fail: - /* Free memory */ + /* Free resource */ + uv_rwlock_destroy(&ctx->lock); free(c_state); freeTrobject(tx_tryte); freeTrobject(nonce_trit); diff --git a/src/pow_c.h b/src/pow_c.h index 3a6af1a..842c290 100644 --- a/src/pow_c.h +++ b/src/pow_c.h @@ -16,7 +16,7 @@ struct _pwork_struct { int mwm; int8_t *nonce; int n; - pthread_mutex_t *lock; + uv_rwlock_t *lock; int *stopPoW; int index; int64_t ret; @@ -26,7 +26,7 @@ typedef struct _pow_c_context PoW_C_Context; struct _pow_c_context { /* Resource of computing */ - pthread_mutex_t lock; + uv_rwlock_t lock; /* Data type of libtuv */ uv_loop_t loop; uv_work_t *work_req; diff --git a/src/pow_sse.c b/src/pow_sse.c index da0dc1e..e0131c6 100644 --- a/src/pow_sse.c +++ b/src/pow_sse.c @@ -115,13 +115,16 @@ static int64_t loop128(__m128i *lmid, __m128i *hmid, int m, int8_t *nonce, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { int n = 0; int64_t i = 0; __m128i lcpy[STATE_TRITS_LENGTH * 2], hcpy[STATE_TRITS_LENGTH * 2]; + uv_rwlock_rdlock(lock); for (i = 0; !incr128(lmid, hmid) && !*stopPoW; i++) { + uv_rwlock_rdunlock(lock); for (int j = 0; j < STATE_TRITS_LENGTH; j++) { lcpy[j] = lmid[j]; hcpy[j] = hmid[j]; @@ -134,7 +137,9 @@ static int64_t loop128(__m128i *lmid, seri128(lmid, hmid, n, nonce); return i * 128; } + uv_rwlock_rdlock(lock); } + uv_rwlock_rdunlock(lock); return -i * 128 - 1; } @@ -176,7 +181,8 @@ static int64_t pwork128(int8_t mid[], int mwm, int8_t nonce[], int n, - int *stopPoW) + int *stopPoW, + uv_rwlock_t *lock) { __m128i lmid[STATE_TRITS_LENGTH], hmid[STATE_TRITS_LENGTH]; para128(mid, lmid, hmid); @@ -194,22 +200,23 @@ static int64_t pwork128(int8_t mid[], hmid[offset + 4] = _mm_set_epi64x(HIGH40, HIGH41); incrN128(n, lmid, hmid); - return loop128(lmid, hmid, mwm, nonce, stopPoW); + return loop128(lmid, hmid, mwm, nonce, stopPoW, lock); } static void work_cb(uv_work_t *req) { Pwork_struct *pworkInfo = (Pwork_struct *) req->data; - pworkInfo->ret = pwork128(pworkInfo->mid, pworkInfo->mwm, pworkInfo->nonce, - pworkInfo->n, pworkInfo->stopPoW); + pworkInfo->ret = + pwork128(pworkInfo->mid, pworkInfo->mwm, pworkInfo->nonce, pworkInfo->n, + pworkInfo->stopPoW, pworkInfo->lock); - pthread_mutex_lock(pworkInfo->lock); + uv_rwlock_wrlock(pworkInfo->lock); if (pworkInfo->ret >= 0) { *pworkInfo->stopPoW = 1; /* This means this thread got the result */ pworkInfo->n = -1; } - pthread_mutex_unlock(pworkInfo->lock); + uv_rwlock_wrunlock(pworkInfo->lock); } static int8_t *tx_to_cstate(Trytes_t *tx) @@ -279,7 +286,7 @@ static bool PowSSE(void *pow_ctx) ctx->stopPoW = 0; ctx->pow_info.time = 0; ctx->pow_info.hash_count = 0; - pthread_mutex_init(&ctx->lock, NULL); + uv_rwlock_init(&ctx->lock); uv_loop_t *loop_ptr = &ctx->loop; uv_work_t *work_req = ctx->work_req; Pwork_struct *pitem = ctx->pitem; @@ -337,7 +344,8 @@ static bool PowSSE(void *pow_ctx) nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); fail: - /* Free memory */ + /* Free resource */ + uv_rwlock_destroy(&ctx->lock); free(c_state); freeTrobject(tx_tryte); freeTrobject(nonce_trit); diff --git a/src/pow_sse.h b/src/pow_sse.h index e84a527..160e12c 100644 --- a/src/pow_sse.h +++ b/src/pow_sse.h @@ -16,7 +16,7 @@ struct _pwork_struct { int mwm; int8_t *nonce; int n; - pthread_mutex_t *lock; + uv_rwlock_t *lock; int *stopPoW; int64_t ret; }; @@ -25,7 +25,7 @@ typedef struct _pow_sse_context PoW_SSE_Context; struct _pow_sse_context { /* Resource of computing */ - pthread_mutex_t lock; + uv_rwlock_t lock; /* Data type of libtuv */ uv_loop_t loop; uv_work_t *work_req;