diff --git a/src/pow_avx.c b/src/pow_avx.c index ad73c87..f224325 100644 --- a/src/pow_avx.c +++ b/src/pow_avx.c @@ -485,28 +485,24 @@ static void *pworkThread(void *pitem) static int8_t *tx_to_cstate(Trytes_t *tx) { - Curl *c = initCurl(); - if (!c) - return NULL; - - int8_t *c_state = (int8_t *) malloc(c->state->len); - if (!c_state) - return NULL; - + Trytes_t *inn = NULL; + Trits_t *tr = NULL; int8_t tyt[(transactionTrinarySize - HashSize) / 3] = {0}; + Curl *c = initCurl(); + int8_t *c_state = (int8_t *) malloc(STATE_TRITS_LENGTH); + if (!c || !c_state) goto fail; + /* Copy tx->data[:(transactionTrinarySize - HashSize) / 3] to tyt */ memcpy(tyt, tx->data, (transactionTrinarySize - HashSize) / 3); - Trytes_t *inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); - if (!inn) - return NULL; + inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); + if (!inn) goto fail; Absorb(c, inn); - Trits_t *tr = trits_from_trytes(tx); - if (!tr) - return NULL; + tr = trits_from_trytes(tx); + if (!tr) goto fail; /* Prepare an array storing tr[transactionTrinarySize - HashSize:] */ memcpy(c_state, tr->data + transactionTrinarySize - HashSize, @@ -518,8 +514,13 @@ static int8_t *tx_to_cstate(Trytes_t *tx) freeTrobject(inn); freeTrobject(tr); freeCurl(c); - return c_state; +fail: + freeTrobject(inn); + freeTrobject(tr); + freeCurl(c); + free(c_state); + return NULL; } static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) @@ -533,9 +534,12 @@ static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) bool PowAVX(void *pow_ctx) { - PoW_AVX_Context *ctx = (PoW_AVX_Context *) pow_ctx; + bool res = true; + Trits_t *nonce_trit = NULL; + Trytes_t *tx_tryte = NULL, *nonce_tryte = NULL; /* Initialize the context */ + PoW_AVX_Context *ctx = (PoW_AVX_Context *) pow_ctx; ctx->stopPoW = 0; pthread_mutex_init(&ctx->lock, NULL); pthread_t *threads = ctx->threads; @@ -543,11 +547,14 @@ bool PowAVX(void *pow_ctx) int8_t **nonce_array = ctx->nonce_array; /* Prepare the input trytes for algorithm */ - Trytes_t *trytes_t = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + tx_tryte = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + if (!tx_tryte) return false; - int8_t *c_state = tx_to_cstate(trytes_t); - if (!c_state) - return false; + int8_t *c_state = tx_to_cstate(tx_tryte); + if (!c_state) { + res = false; + goto fail; + } /* Prepare arguments for pthread */ for (int i = 0; i < ctx->num_threads; i++) { @@ -568,55 +575,75 @@ bool PowAVX(void *pow_ctx) completedIndex = i; } - Trits_t *nonce_t = initTrits(nonce_array[completedIndex], NonceTrinarySize); - if (!nonce_t) - return false; + nonce_trit = initTrits(nonce_array[completedIndex], NonceTrinarySize); + if (!nonce_trit) { + res = false; + goto fail; + } - Trytes_t *nonce = trytes_from_trits(nonce_t); - if (!nonce) - return false; + nonce_tryte = trytes_from_trits(nonce_trit); + if (!nonce_tryte) { + res = false; + goto fail; + } - nonce_to_result(trytes_t, nonce, ctx->output_trytes); + nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); +fail: /* Free memory */ free(c_state); - freeTrobject(trytes_t); - freeTrobject(nonce_t); - freeTrobject(nonce); + freeTrobject(tx_tryte); + freeTrobject(nonce_trit); + freeTrobject(nonce_tryte); - return true; + return res; } static bool PoWAVX_Context_Initialize(ImplContext *impl_ctx) { int nproc = get_avail_nprocs(); + if (impl_ctx->num_max_thread <= 0 || nproc <= 0) return false; + PoW_AVX_Context *ctx = (PoW_AVX_Context *) malloc(sizeof(PoW_AVX_Context) * impl_ctx->num_max_thread); if (!ctx) return false; + + /* Pre-allocate Memory Chunk for each field */ + void *threads_chunk = malloc(impl_ctx->num_max_thread * sizeof(pthread_t) * nproc); + void *pitem_chunk = malloc(impl_ctx->num_max_thread * sizeof(Pwork_struct) * nproc); + void *nonce_ptr_chunk = malloc(impl_ctx->num_max_thread * sizeof(int8_t *) * nproc); + void *nonce_chunk = malloc(impl_ctx->num_max_thread * NonceTrinarySize * nproc); + if (!threads_chunk || !pitem_chunk || !nonce_ptr_chunk || !nonce_chunk) goto fail; + for (int i = 0; i < impl_ctx->num_max_thread; i++) { - ctx[i].threads = (pthread_t *) malloc(sizeof(pthread_t) * nproc); - ctx[i].pitem = (Pwork_struct *) malloc(sizeof(Pwork_struct) * nproc); - ctx[i].nonce_array = (int8_t **) malloc(sizeof(int *) * nproc); - void *chunk = malloc(NonceTrinarySize * nproc); - if (!ctx[i].threads || !ctx[i].pitem || !ctx[i].nonce_array || !chunk) return false; + ctx[i].threads = (pthread_t *) (threads_chunk + i * sizeof(pthread_t) * nproc); + ctx[i].pitem = (Pwork_struct *) (pitem_chunk + i * sizeof(Pwork_struct) * nproc); + ctx[i].nonce_array = (int8_t **) (nonce_ptr_chunk + i * sizeof(int8_t *) * nproc); for (int j = 0; j < nproc; j++) - ctx[i].nonce_array[j] = (int8_t *) (chunk + j * NonceTrinarySize); + ctx[i].nonce_array[j] = (int8_t *) (nonce_chunk + i * NonceTrinarySize * nproc + + j * NonceTrinarySize); ctx[i].num_threads = nproc; impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1; } impl_ctx->context = ctx; pthread_mutex_init(&impl_ctx->lock, NULL); return true; + +fail: + free(ctx); + free(threads_chunk); + free(pitem_chunk); + free(nonce_ptr_chunk); + free(nonce_chunk); + return false; } static void PoWAVX_Context_Destroy(ImplContext *impl_ctx) { PoW_AVX_Context *ctx = (PoW_AVX_Context *) impl_ctx->context; - for (int i = 0; i < impl_ctx->num_max_thread; i++) { - free(ctx[i].threads); - free(ctx[i].pitem); - free(ctx[i].nonce_array[0]); - free(ctx[i].nonce_array); - } + free(ctx[0].threads); + free(ctx[0].pitem); + free(ctx[0].nonce_array[0]); + free(ctx[0].nonce_array); free(ctx); } diff --git a/src/pow_c.c b/src/pow_c.c index 569a30f..fc624a3 100644 --- a/src/pow_c.c +++ b/src/pow_c.c @@ -246,28 +246,24 @@ static void *pworkThread(void *pitem) static int8_t *tx_to_cstate(Trytes_t *tx) { - Curl *c = initCurl(); - if (!c) - return NULL; - - int8_t *c_state = (int8_t *) malloc(c->state->len); - if (!c_state) - return NULL; - + Trytes_t *inn = NULL; + Trits_t *tr = NULL; int8_t tyt[(transactionTrinarySize - HashSize) / 3] = {0}; + Curl *c = initCurl(); + int8_t *c_state = (int8_t *) malloc(STATE_TRITS_LENGTH); + if (!c || !c_state) goto fail; + /* Copy tx->data[:(transactionTrinarySize - HashSize) / 3] to tyt */ memcpy(tyt, tx->data, (transactionTrinarySize - HashSize) / 3); - Trytes_t *inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); - if (!inn) - return NULL; + inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); + if (!inn) goto fail; Absorb(c, inn); - Trits_t *tr = trits_from_trytes(tx); - if (!tr) - return NULL; + tr = trits_from_trytes(tx); + if (!tr) goto fail; /* Prepare an array storing tr[transactionTrinarySize - HashSize:] */ memcpy(c_state, tr->data + transactionTrinarySize - HashSize, @@ -279,8 +275,13 @@ static int8_t *tx_to_cstate(Trytes_t *tx) freeTrobject(inn); freeTrobject(tr); freeCurl(c); - return c_state; +fail: + freeTrobject(inn); + freeTrobject(tr); + freeCurl(c); + free(c_state); + return NULL; } static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) @@ -294,9 +295,12 @@ static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) bool PowC(void *pow_ctx) { - PoW_C_Context *ctx = (PoW_C_Context *) pow_ctx; + bool res = true; + Trits_t *nonce_trit = NULL; + Trytes_t *tx_tryte = NULL, *nonce_tryte = NULL; /* Initialize the context */ + PoW_C_Context *ctx = (PoW_C_Context *) pow_ctx; ctx->stopPoW = 0; pthread_mutex_init(&ctx->lock, NULL); pthread_t *threads = ctx->threads; @@ -304,11 +308,14 @@ bool PowC(void *pow_ctx) int8_t **nonce_array = ctx->nonce_array; /* Prepare the input trytes for algorithm */ - Trytes_t *trytes_t = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + tx_tryte = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + if (!tx_tryte) return false; - int8_t *c_state = tx_to_cstate(trytes_t); - if (!c_state) - return false; + int8_t *c_state = tx_to_cstate(tx_tryte); + if (!c_state) { + res = false; + goto fail; + } /* Prepare arguments for pthread */ for (int i = 0; i < ctx->num_threads; i++) { @@ -329,55 +336,74 @@ bool PowC(void *pow_ctx) completedIndex = i; } - Trits_t *nonce_t = initTrits(nonce_array[completedIndex], NonceTrinarySize); - if (!nonce_t) - return false; + nonce_trit = initTrits(nonce_array[completedIndex], NonceTrinarySize); + if (!nonce_trit) { + res = false; + goto fail; + } - Trytes_t *nonce = trytes_from_trits(nonce_t); - if (!nonce) - return false; + nonce_tryte = trytes_from_trits(nonce_trit); + if (!nonce_tryte) { + res = false; + goto fail; + } - nonce_to_result(trytes_t, nonce, ctx->output_trytes); + nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); +fail: /* Free memory */ free(c_state); - freeTrobject(trytes_t); - freeTrobject(nonce_t); - freeTrobject(nonce); - - return true; + freeTrobject(tx_tryte); + freeTrobject(nonce_trit); + freeTrobject(nonce_tryte); + return res; } static bool PoWC_Context_Initialize(ImplContext *impl_ctx) { int nproc = get_avail_nprocs(); + if (impl_ctx->num_max_thread <= 0 || nproc <= 0) return false; + PoW_C_Context *ctx = (PoW_C_Context *) malloc(sizeof(PoW_C_Context) * impl_ctx->num_max_thread); if (!ctx) return false; + + /* Pre-allocate Memory Chunk for each field */ + void *threads_chunk = malloc(impl_ctx->num_max_thread * sizeof(pthread_t) * nproc); + void *pitem_chunk = malloc(impl_ctx->num_max_thread * sizeof(Pwork_struct) * nproc); + void *nonce_ptr_chunk = malloc(impl_ctx->num_max_thread * sizeof(int8_t *) * nproc); + void *nonce_chunk = malloc(impl_ctx->num_max_thread * NonceTrinarySize * nproc); + if (!threads_chunk || !pitem_chunk || !nonce_ptr_chunk || !nonce_chunk) goto fail; + for (int i = 0; i < impl_ctx->num_max_thread; i++) { - ctx[i].threads = (pthread_t *) malloc(sizeof(pthread_t) * nproc); - ctx[i].pitem = (Pwork_struct *) malloc(sizeof(Pwork_struct) * nproc); - ctx[i].nonce_array = (int8_t **) malloc(sizeof(int *) * nproc); - void *chunk = malloc(NonceTrinarySize * nproc); - if (!ctx[i].threads || !ctx[i].pitem || !ctx[i].nonce_array || !chunk) return false; + ctx[i].threads = (pthread_t *) (threads_chunk + i * sizeof(pthread_t) * nproc); + ctx[i].pitem = (Pwork_struct *) (pitem_chunk + i * sizeof(Pwork_struct) * nproc); + ctx[i].nonce_array = (int8_t **) (nonce_ptr_chunk + i * sizeof(int8_t *) * nproc); for (int j = 0; j < nproc; j++) - ctx[i].nonce_array[j] = (int8_t *) (chunk + j * NonceTrinarySize); + ctx[i].nonce_array[j] = (int8_t *) (nonce_chunk + i * NonceTrinarySize * nproc + + j * NonceTrinarySize); ctx[i].num_threads = nproc; impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1; } impl_ctx->context = ctx; pthread_mutex_init(&impl_ctx->lock, NULL); return true; + +fail: + free(ctx); + free(threads_chunk); + free(pitem_chunk); + free(nonce_ptr_chunk); + free(nonce_chunk); + return false; } static void PoWC_Context_Destroy(ImplContext *impl_ctx) { PoW_C_Context *ctx = (PoW_C_Context *) impl_ctx->context; - for (int i = 0; i < impl_ctx->num_max_thread; i++) { - free(ctx[i].threads); - free(ctx[i].pitem); - free(ctx[i].nonce_array[0]); - free(ctx[i].nonce_array); - } + free(ctx[0].threads); + free(ctx[0].pitem); + free(ctx[0].nonce_array[0]); + free(ctx[0].nonce_array); free(ctx); } diff --git a/src/pow_cl.c b/src/pow_cl.c index eb28037..5f029a0 100644 --- a/src/pow_cl.c +++ b/src/pow_cl.c @@ -151,27 +151,24 @@ static int8_t *pwork(int8_t *state, int mwm, CLContext *ctx) static int8_t *tx_to_cstate(Trytes_t *tx) { - Curl *c = initCurl(); - if (!c) - return NULL; - - int8_t *c_state = (int8_t *) malloc(c->state->len); - if (!c_state) - return NULL; - + Trytes_t *inn = NULL; + Trits_t *tr = NULL; int8_t tyt[(transactionTrinarySize - HashSize) / 3] = {0}; + Curl *c = initCurl(); + int8_t *c_state = (int8_t *) malloc(STATE_TRITS_LENGTH); + if (!c || !c_state) goto fail; + /* Copy tx->data[:(transactionTrinarySize - HashSize) / 3] to tyt */ memcpy(tyt, tx->data, (transactionTrinarySize - HashSize) / 3); - Trytes_t *inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); - if (!inn) - return NULL; + + inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); + if (!inn) goto fail; Absorb(c, inn); - Trits_t *tr = trits_from_trytes(tx); - if (!tr) - return NULL; + tr = trits_from_trytes(tx); + if (!tr) goto fail; /* Prepare an array storing tr[transactionTrinarySize - HashSize:] */ memcpy(c_state, tr->data + transactionTrinarySize - HashSize, @@ -183,41 +180,61 @@ static int8_t *tx_to_cstate(Trytes_t *tx) freeTrobject(inn); freeTrobject(tr); freeCurl(c); - return c_state; +fail: + freeTrobject(inn); + freeTrobject(tr); + freeCurl(c); + free(c_state); + return NULL; } bool PowCL(void *pow_ctx) { + bool res = true; + int8_t *c_state = NULL, *pow_result = NULL; + Trits_t *tx_trit = NULL; + Trytes_t *tx_tryte = NULL, *res_tryte = NULL; + PoW_CL_Context *ctx = (PoW_CL_Context *) pow_ctx; - Trytes_t *trytes_t = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); - Trits_t *tr = trits_from_trytes(trytes_t); - if (!tr) - return false; + tx_tryte = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + if (!tx_tryte) return false; - int8_t *c_state = tx_to_cstate(trytes_t); - if (!c_state) - return false; + tx_trit = trits_from_trytes(tx_tryte); + if (!tx_trit) { + res = false; + goto fail; + } - int8_t *ret = pwork(c_state, ctx->mwm, ctx->clctx); - if (!ret) - return false; + c_state = tx_to_cstate(tx_tryte); + if (!c_state) { + res = false; + goto fail; + } - memcpy(&tr->data[TRANSACTION_TRITS_LENGTH - HASH_TRITS_LENGTH], ret, + pow_result = pwork(c_state, ctx->mwm, ctx->clctx); + if (!pow_result) { + res = false; + goto fail; + } + memcpy(&tx_trit->data[TRANSACTION_TRITS_LENGTH - HASH_TRITS_LENGTH], pow_result, HASH_TRITS_LENGTH * sizeof(int8_t)); - Trytes_t *last = trytes_from_trits(tr); - memcpy(ctx->output_trytes, last->data, TRANSACTION_TRYTES_LENGTH); + res_tryte = trytes_from_trits(tx_trit); + if (!res_tryte) { + res = false; + goto fail; + } + memcpy(ctx->output_trytes, res_tryte->data, TRANSACTION_TRYTES_LENGTH); - freeTrobject(tr); - freeTrobject(trytes_t); - freeTrobject(last); - /* hack */ +fail: + freeTrobject(tx_trit); + freeTrobject(tx_tryte); + freeTrobject(res_tryte); free(c_state); - free(ret); - - return true; + free(pow_result); + return res; } static bool PoWCL_Context_Initialize(ImplContext *impl_ctx) diff --git a/src/pow_fpga_accel.c b/src/pow_fpga_accel.c index 771e9b8..74d1479 100644 --- a/src/pow_fpga_accel.c +++ b/src/pow_fpga_accel.c @@ -28,56 +28,73 @@ static bool PoWFPGAAccel(void *pow_ctx) { PoW_FPGA_Accel_Context *ctx = (PoW_FPGA_Accel_Context *) pow_ctx; - int8_t fpga_out_nonce_trits[NonceTrinarySize]; + int8_t fpga_out_nonce_trit[NonceTrinarySize]; char result[4]; char buf[4]; + bool res = true; - Trytes_t *object_trytes = + Trytes_t *object_tryte = NULL, nonce_tryte = NULL; + Trits_t *object_trit = NULL, *object_nonce_trit = NULL; + + object_tryte = initTrytes(ctx->input_trytes, (transactionTrinarySize) / 3); - if (!object_trytes) - return false; + if (!object_tryte) return false; - Trits_t *object_trits = trits_from_trytes(object_trytes); - if (!object_trits) - return false; + object_trit = trits_from_trytes(object_tryte); + if (!object_trit) { + res = false; + goto fail; + } lseek(ctx->in_fd, 0, 0); lseek(ctx->ctrl_fd, 0, 0); lseek(ctx->out_fd, 0, 0); if (write(ctx->in_fd, (char *) object_trits->data, transactionTrinarySize) < - 0) - return false; + 0) { + res = false; + goto fail; + } INT2STRING(ctx->mwm, buf); - if (write(ctx->ctrl_fd, buf, sizeof(buf)) < 0) - return false; - if (read(ctx->ctrl_fd, result, sizeof(result)) < 0) - return false; + if (write(ctx->ctrl_fd, buf, sizeof(buf)) < 0) { + res = false; + goto fail; + } + if (read(ctx->ctrl_fd, result, sizeof(result)) < 0) { + res = false; + goto fail; + } - if (read(ctx->out_fd, (char *) fpga_out_nonce_trits, NonceTrinarySize) < 0) - return false; + if (read(ctx->out_fd, (char *) fpga_out_nonce_trit, NonceTrinarySize) < 0) { + res = false; + goto fail; + } - Trits_t *object_nonce_trits = - initTrits(fpga_out_nonce_trits, NonceTrinarySize); - if (!object_nonce_trits) - return false; + object_nonce_trit = + initTrits(fpga_out_nonce_trit, NonceTrinarySize); + if (!object_nonce_trit) { + res = false; + goto fail; + } - Trytes_t *nonce_trytes = trytes_from_trits(object_nonce_trits); - if (!nonce_trytes) - return false; + nonce_tryte = trytes_from_trits(object_nonce_trit); + if (!nonce_tryte) { + res = false; + goto fail; + } memcpy(ctx->output_trytes, ctx->input_trytes, (NonceTrinaryOffset) / 3); memcpy(ctx->output_trytes + ((NonceTrinaryOffset) / 3), nonce_trytes->data, ((transactionTrinarySize) - (NonceTrinaryOffset)) / 3); - freeTrobject(object_trytes); - freeTrobject(object_trits); - freeTrobject(object_nonce_trits); - freeTrobject(nonce_trytes); - - return true; +fail: + freeTrobject(object_tryte); + freeTrobject(object_trit); + freeTrobject(object_nonce_trit); + freeTrobject(nonce_tryte); + return res; } static bool PoWFPGAAccel_Context_Initialize(ImplContext *impl_ctx) diff --git a/src/pow_sse.c b/src/pow_sse.c index 0c8c3ba..83f0c0f 100644 --- a/src/pow_sse.c +++ b/src/pow_sse.c @@ -262,28 +262,24 @@ static void *pworkThread(void *pitem) static int8_t *tx_to_cstate(Trytes_t *tx) { - Curl *c = initCurl(); - if (!c) - return NULL; - - int8_t *c_state = (int8_t *) malloc(c->state->len); - if (!c_state) - return NULL; - + Trytes_t *inn = NULL; + Trits_t *tr = NULL; int8_t tyt[(transactionTrinarySize - HashSize) / 3] = {0}; + Curl *c = initCurl(); + int8_t *c_state = (int8_t *) malloc(STATE_TRITS_LENGTH); + if (!c || !c_state) goto fail; + /* Copy tx->data[:(transactionTrinarySize - HashSize) / 3] to tyt */ memcpy(tyt, tx->data, (transactionTrinarySize - HashSize) / 3); - Trytes_t *inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); - if (!inn) - return NULL; + inn = initTrytes(tyt, (transactionTrinarySize - HashSize) / 3); + if (!inn) goto fail; Absorb(c, inn); - Trits_t *tr = trits_from_trytes(tx); - if (!tr) - return NULL; + tr = trits_from_trytes(tx); + if (!tr) goto fail; /* Prepare an array storing tr[transactionTrinarySize - HashSize:] */ memcpy(c_state, tr->data + transactionTrinarySize - HashSize, @@ -295,8 +291,13 @@ static int8_t *tx_to_cstate(Trytes_t *tx) freeTrobject(inn); freeTrobject(tr); freeCurl(c); - return c_state; +fail: + freeTrobject(inn); + freeTrobject(tr); + freeCurl(c); + free(c_state); + return NULL; } static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) @@ -310,9 +311,12 @@ static void nonce_to_result(Trytes_t *tx, Trytes_t *nonce, int8_t *ret) bool PowSSE(void *pow_ctx) { - PoW_SSE_Context *ctx = (PoW_SSE_Context *) pow_ctx; + bool res = true; + Trits_t *nonce_trit = NULL; + Trytes_t *tx_tryte = NULL, *nonce_tryte = NULL; /* Initialize the context */ + PoW_SSE_Context *ctx = (PoW_SSE_Context *) pow_ctx; ctx->stopPoW = 0; pthread_mutex_init(&ctx->lock, NULL); pthread_t *threads = ctx->threads; @@ -320,11 +324,14 @@ bool PowSSE(void *pow_ctx) int8_t **nonce_array = ctx->nonce_array; /* Prepare the input trytes for algorithm */ - Trytes_t *trytes_t = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + tx_tryte = initTrytes(ctx->input_trytes, TRANSACTION_TRYTES_LENGTH); + if (!tx_tryte) return false; - int8_t *c_state = tx_to_cstate(trytes_t); - if (!c_state) - return false; + int8_t *c_state = tx_to_cstate(tx_tryte); + if (!c_state) { + res = false; + goto fail; + } /* Prepare arguments for pthread */ for (int i = 0; i < ctx->num_threads; i++) { @@ -345,55 +352,74 @@ bool PowSSE(void *pow_ctx) completedIndex = i; } - Trits_t *nonce_t = initTrits(nonce_array[completedIndex], NonceTrinarySize); - if (!nonce_t) - return false; + nonce_trit = initTrits(nonce_array[completedIndex], NonceTrinarySize); + if (!nonce_trit) { + res = false; + goto fail; + } - Trytes_t *nonce = trytes_from_trits(nonce_t); - if (!nonce) - return false; + nonce_tryte = trytes_from_trits(nonce_trit); + if (!nonce_tryte) { + res = false; + goto fail; + } - nonce_to_result(trytes_t, nonce, ctx->output_trytes); + nonce_to_result(tx_tryte, nonce_tryte, ctx->output_trytes); +fail: /* Free memory */ free(c_state); - freeTrobject(trytes_t); - freeTrobject(nonce_t); - freeTrobject(nonce); - - return true; + freeTrobject(tx_tryte); + freeTrobject(nonce_trit); + freeTrobject(nonce_tryte); + return res; } static bool PoWSSE_Context_Initialize(ImplContext *impl_ctx) { int nproc = get_avail_nprocs(); + if (impl_ctx->num_max_thread <= 0 || nproc <= 0) return false; + PoW_SSE_Context *ctx = (PoW_SSE_Context *) malloc(sizeof(PoW_SSE_Context) * impl_ctx->num_max_thread); - if(!ctx) return false; + if (!ctx) return false; + + /* Pre-allocate Memory Chunk for each field */ + void *threads_chunk = malloc(impl_ctx->num_max_thread * sizeof(pthread_t) * nproc); + void *pitem_chunk = malloc(impl_ctx->num_max_thread * sizeof(Pwork_struct) * nproc); + void *nonce_ptr_chunk = malloc(impl_ctx->num_max_thread * sizeof(int8_t *) * nproc); + void *nonce_chunk = malloc(impl_ctx->num_max_thread * NonceTrinarySize * nproc); + if (!threads_chunk || !pitem_chunk || !nonce_ptr_chunk || !nonce_chunk) goto fail; + for (int i = 0; i < impl_ctx->num_max_thread; i++) { - ctx[i].threads = (pthread_t *) malloc(sizeof(pthread_t) * nproc); - ctx[i].pitem = (Pwork_struct *) malloc(sizeof(Pwork_struct) * nproc); - ctx[i].nonce_array = (int8_t **) malloc(sizeof(int *) * nproc); - void *chunk = malloc(NonceTrinarySize * nproc); - if (!ctx[i].threads || !ctx[i].pitem || !ctx[i].nonce_array || !chunk) return false; + ctx[i].threads = (pthread_t *) (threads_chunk + i * sizeof(pthread_t) * nproc); + ctx[i].pitem = (Pwork_struct *) (pitem_chunk + i * sizeof(Pwork_struct) * nproc); + ctx[i].nonce_array = (int8_t **) (nonce_ptr_chunk + i * sizeof(int8_t *) * nproc); for (int j = 0; j < nproc; j++) - ctx[i].nonce_array[j] = (int8_t *) (chunk + j * NonceTrinarySize); + ctx[i].nonce_array[j] = (int8_t *) (nonce_chunk + i * NonceTrinarySize * nproc + + j * NonceTrinarySize); ctx[i].num_threads = nproc; impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1; } impl_ctx->context = ctx; pthread_mutex_init(&impl_ctx->lock, NULL); return true; + +fail: + free(ctx); + free(threads_chunk); + free(pitem_chunk); + free(nonce_ptr_chunk); + free(nonce_chunk); + return false; } static void PoWSSE_Context_Destroy(ImplContext *impl_ctx) { PoW_SSE_Context *ctx = (PoW_SSE_Context *) impl_ctx->context; - for (int i = 0; i < impl_ctx->num_max_thread; i++) { - free(ctx[i].threads); - free(ctx[i].pitem); - free(ctx[i].nonce_array[0]); - free(ctx[i].nonce_array); - } + free(ctx[0].threads); + free(ctx[0].pitem); + free(ctx[0].nonce_array[0]); + free(ctx[0].nonce_array); free(ctx); }