mirror of
https://github.com/GOSTSec/vanitygen
synced 2025-02-07 04:14:15 +00:00
Basic support for concurrency in OpenCL engine.
This commit is contained in:
parent
06af705498
commit
c21e99a58b
19
oclengine.c
19
oclengine.c
@ -1571,7 +1571,6 @@ vg_ocl_prefix_check(vg_ocl_context_t *vocp, int slot)
|
||||
found_delta, orig_delta);
|
||||
res = 1;
|
||||
}
|
||||
vocp->voc_pattern_rewrite = 1;
|
||||
} else {
|
||||
vxcp->vxc_delta += (vocp->voc_ocl_cols * vocp->voc_ocl_rows);
|
||||
}
|
||||
@ -1879,6 +1878,7 @@ vg_opencl_loop(void *arg)
|
||||
vg_ocl_context_t *vocp = (vg_ocl_context_t *) arg;
|
||||
int i;
|
||||
int round, nrows, ncols;
|
||||
int pattern_generation;
|
||||
|
||||
const BN_ULONG rekey_max = 100000000;
|
||||
BN_ULONG npoints, rekey_at;
|
||||
@ -1991,6 +1991,10 @@ l_rekey:
|
||||
!vocp->voc_rekey_func(vocp))
|
||||
goto enomem;
|
||||
|
||||
vg_exec_context_upgrade_lock(vxcp);
|
||||
|
||||
pattern_generation = vcp->vc_pattern_generation;
|
||||
|
||||
/* Generate a new random private key */
|
||||
EC_KEY_generate_key(pkey);
|
||||
npoints = 0;
|
||||
@ -2007,6 +2011,8 @@ l_rekey:
|
||||
|
||||
EC_POINT_copy(ppbase[0], EC_KEY_get0_public_key(pkey));
|
||||
|
||||
vg_exec_context_downgrade_lock(vxcp);
|
||||
|
||||
if (vcp->vc_pubkey_base) {
|
||||
EC_POINT_add(pgroup,
|
||||
ppbase[0],
|
||||
@ -2076,6 +2082,15 @@ l_rekey:
|
||||
vg_output_timing(vcp, c, &tvstart);
|
||||
c = 0;
|
||||
}
|
||||
vg_exec_context_yield(vxcp);
|
||||
|
||||
/* If the patterns changed, reload it to the GPU */
|
||||
if (vocp->voc_rekey_func &&
|
||||
(pattern_generation !=
|
||||
vcp->vc_pattern_generation)) {
|
||||
vocp->voc_pattern_rewrite = 1;
|
||||
rekey_at = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (vcp->vc_halt)
|
||||
@ -2176,6 +2191,8 @@ l_rekey:
|
||||
printf("done!\n");
|
||||
}
|
||||
|
||||
vg_exec_context_yield(vxcp);
|
||||
|
||||
if (ppbase) {
|
||||
for (i = 0; i < (nrows + ncols); i++)
|
||||
if (ppbase[i])
|
||||
|
149
pattern.c
149
pattern.c
@ -45,9 +45,106 @@ vg_exec_context_new_key(void)
|
||||
return EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread synchronization helpers
|
||||
*/
|
||||
|
||||
static pthread_mutex_t vg_thread_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_rdcond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_wrcond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_upcond = PTHREAD_COND_INITIALIZER;
|
||||
static vg_exec_context_t *vg_threads = NULL;
|
||||
static int vg_thread_excl = 0;
|
||||
|
||||
static void
|
||||
__vg_exec_context_yield(vg_exec_context_t *vxcp)
|
||||
{
|
||||
vxcp->vxc_lockmode = 0;
|
||||
while (vg_thread_excl) {
|
||||
if (vxcp->vxc_stop) {
|
||||
assert(vg_thread_excl);
|
||||
vxcp->vxc_stop = 0;
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
}
|
||||
pthread_cond_wait(&vg_thread_rdcond, &vg_thread_lock);
|
||||
}
|
||||
assert(!vxcp->vxc_stop);
|
||||
assert(!vxcp->vxc_lockmode);
|
||||
vxcp->vxc_lockmode = 1;
|
||||
}
|
||||
|
||||
int
|
||||
vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp)
|
||||
{
|
||||
vg_exec_context_t *tp;
|
||||
|
||||
if (vxcp->vxc_lockmode == 2)
|
||||
return 0;
|
||||
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
|
||||
assert(vxcp->vxc_lockmode == 1);
|
||||
vxcp->vxc_lockmode = 0;
|
||||
|
||||
if (vg_thread_excl++) {
|
||||
assert(vxcp->vxc_stop);
|
||||
vxcp->vxc_stop = 0;
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
pthread_cond_wait(&vg_thread_wrcond, &vg_thread_lock);
|
||||
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
||||
assert(!tp->vxc_lockmode);
|
||||
assert(!tp->vxc_stop);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
||||
if (tp->vxc_lockmode) {
|
||||
assert(tp->vxc_lockmode != 2);
|
||||
tp->vxc_stop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
||||
if (tp->vxc_lockmode) {
|
||||
assert(tp->vxc_lockmode != 2);
|
||||
pthread_cond_wait(&vg_thread_upcond,
|
||||
&vg_thread_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (tp);
|
||||
}
|
||||
|
||||
vxcp->vxc_lockmode = 2;
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
vg_exec_context_downgrade_lock(vg_exec_context_t *vxcp)
|
||||
{
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
|
||||
assert(vxcp->vxc_lockmode == 2);
|
||||
assert(!vxcp->vxc_stop);
|
||||
if (!--vg_thread_excl) {
|
||||
vxcp->vxc_lockmode = 1;
|
||||
pthread_cond_broadcast(&vg_thread_rdcond);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
return;
|
||||
}
|
||||
pthread_cond_signal(&vg_thread_wrcond);
|
||||
__vg_exec_context_yield(vxcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
int
|
||||
vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
|
||||
{
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
|
||||
memset(vxcp, 0, sizeof(*vxcp));
|
||||
|
||||
vxcp->vxc_vc = vcp;
|
||||
@ -64,18 +161,62 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
|
||||
vxcp->vxc_key = vg_exec_context_new_key();
|
||||
assert(vxcp->vxc_key);
|
||||
EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
|
||||
|
||||
vxcp->vxc_lockmode = 0;
|
||||
vxcp->vxc_stop = 0;
|
||||
|
||||
vxcp->vxc_next = vg_threads;
|
||||
vg_threads = vxcp;
|
||||
__vg_exec_context_yield(vxcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
vg_exec_context_del(vg_exec_context_t *vxcp)
|
||||
{
|
||||
vg_exec_context_t *tp, **pprev;
|
||||
|
||||
if (vxcp->vxc_lockmode == 2)
|
||||
vg_exec_context_downgrade_lock(vxcp);
|
||||
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
assert(vxcp->vxc_lockmode == 1);
|
||||
vxcp->vxc_lockmode = 0;
|
||||
|
||||
for (pprev = &vg_threads, tp = *pprev;
|
||||
(tp != vxcp) && (tp != NULL);
|
||||
pprev = &tp->vxc_next, tp = *pprev);
|
||||
|
||||
assert(tp == vxcp);
|
||||
*pprev = tp->vxc_next;
|
||||
|
||||
if (tp->vxc_stop)
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
|
||||
BN_clear_free(&vxcp->vxc_bntarg);
|
||||
BN_clear_free(&vxcp->vxc_bnbase);
|
||||
BN_clear_free(&vxcp->vxc_bntmp);
|
||||
BN_clear_free(&vxcp->vxc_bntmp2);
|
||||
BN_CTX_free(vxcp->vxc_bnctx);
|
||||
vxcp->vxc_bnctx = NULL;
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
void
|
||||
vg_exec_context_yield(vg_exec_context_t *vxcp)
|
||||
{
|
||||
if (vxcp->vxc_lockmode == 2)
|
||||
vg_exec_context_downgrade_lock(vxcp);
|
||||
|
||||
else if (vxcp->vxc_stop) {
|
||||
assert(vxcp->vxc_lockmode == 1);
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
__vg_exec_context_yield(vxcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
assert(vxcp->vxc_lockmode == 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -473,6 +614,7 @@ int
|
||||
vg_context_add_patterns(vg_context_t *vcp,
|
||||
const char ** const patterns, int npatterns)
|
||||
{
|
||||
vcp->vc_pattern_generation++;
|
||||
return vcp->vc_add_patterns(vcp, patterns, npatterns);
|
||||
}
|
||||
|
||||
@ -480,6 +622,7 @@ void
|
||||
vg_context_clear_all_patterns(vg_context_t *vcp)
|
||||
{
|
||||
vcp->vc_clear_all_patterns(vcp);
|
||||
vcp->vc_pattern_generation++;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1690,7 +1833,7 @@ vg_prefix_test(vg_exec_context_t *vxcp)
|
||||
research:
|
||||
vp = vg_prefix_avl_search(&vcpp->vcp_avlroot, &vxcp->vxc_bntarg);
|
||||
if (vp) {
|
||||
if (vg_exec_upgrade_lock(vxcp))
|
||||
if (vg_exec_context_upgrade_lock(vxcp))
|
||||
goto research;
|
||||
|
||||
vg_exec_context_consolidate_key(vxcp);
|
||||
@ -1717,6 +1860,7 @@ research:
|
||||
vcpp, &vxcp->vxc_bntmp,
|
||||
&vxcp->vxc_bntmp2,
|
||||
vxcp->vxc_bnctx);
|
||||
vcpp->base.vc_pattern_generation++;
|
||||
}
|
||||
res = 1;
|
||||
}
|
||||
@ -1983,7 +2127,7 @@ restart_loop:
|
||||
|
||||
re = vcrp->vcr_regex[i];
|
||||
|
||||
if (vg_exec_upgrade_lock(vxcp) &&
|
||||
if (vg_exec_context_upgrade_lock(vxcp) &&
|
||||
((i >= vcrp->base.vc_npatterns) ||
|
||||
(vcrp->vcr_regex[i] != re)))
|
||||
goto restart_loop;
|
||||
@ -2008,6 +2152,7 @@ restart_loop:
|
||||
vcrp->vcr_regex_extra[nres];
|
||||
vcrp->vcr_regex_pat[i] = vcrp->vcr_regex_pat[nres];
|
||||
vcrp->base.vc_npatterns = nres;
|
||||
vcrp->base.vc_pattern_generation++;
|
||||
}
|
||||
res = 1;
|
||||
}
|
||||
|
15
pattern.h
15
pattern.h
@ -33,7 +33,7 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define VANITYGEN_VERSION "0.19"
|
||||
#define VANITYGEN_VERSION "0.20pre"
|
||||
|
||||
|
||||
typedef struct _vg_context_s vg_context_t;
|
||||
@ -49,6 +49,11 @@ typedef struct _vg_exec_context_s {
|
||||
BIGNUM vxc_bnbase;
|
||||
BIGNUM vxc_bntmp;
|
||||
BIGNUM vxc_bntmp2;
|
||||
|
||||
/* Thread synchronization */
|
||||
struct _vg_exec_context_s *vxc_next;
|
||||
int vxc_lockmode;
|
||||
int vxc_stop;
|
||||
} vg_exec_context_t;
|
||||
|
||||
/* Init/cleanup for common execution context */
|
||||
@ -58,9 +63,10 @@ extern void vg_exec_context_consolidate_key(vg_exec_context_t *vxcp);
|
||||
extern void vg_exec_context_calc_address(vg_exec_context_t *vxcp);
|
||||
extern EC_KEY *vg_exec_context_new_key(void);
|
||||
|
||||
/* Implementation-specific lock/unlock/consolidate */
|
||||
extern void vg_exec_downgrade_lock(vg_exec_context_t *vxcp);
|
||||
extern int vg_exec_upgrade_lock(vg_exec_context_t *vxcp);
|
||||
/* Execution context lock handling functions */
|
||||
extern void vg_exec_context_downgrade_lock(vg_exec_context_t *vxcp);
|
||||
extern int vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp);
|
||||
extern void vg_exec_context_yield(vg_exec_context_t *vxcp);
|
||||
|
||||
|
||||
typedef void (*vg_free_func_t)(vg_context_t *);
|
||||
@ -89,6 +95,7 @@ struct _vg_context_s {
|
||||
unsigned long vc_npatterns;
|
||||
unsigned long vc_npatterns_start;
|
||||
unsigned long long vc_found;
|
||||
int vc_pattern_generation;
|
||||
double vc_chance;
|
||||
const char *vc_result_file;
|
||||
const char *vc_key_protect_pass;
|
||||
|
177
vanitygen.c
177
vanitygen.c
@ -34,169 +34,6 @@
|
||||
|
||||
const char *version = VANITYGEN_VERSION;
|
||||
|
||||
typedef struct _vg_thread_context_s {
|
||||
vg_exec_context_t base;
|
||||
struct _vg_thread_context_s *vt_next;
|
||||
int vt_mode;
|
||||
int vt_stop;
|
||||
} vg_thread_context_t;
|
||||
|
||||
|
||||
/*
|
||||
* To synchronize pattern lists, we use a special shared-exclusive lock
|
||||
* geared toward being held in shared mode 99.9% of the time.
|
||||
*/
|
||||
|
||||
static pthread_mutex_t vg_thread_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_rdcond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_wrcond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_cond_t vg_thread_upcond = PTHREAD_COND_INITIALIZER;
|
||||
static vg_thread_context_t *vg_threads = NULL;
|
||||
static int vg_thread_excl = 0;
|
||||
|
||||
void
|
||||
__vg_thread_yield(vg_thread_context_t *vtcp)
|
||||
{
|
||||
vtcp->vt_mode = 0;
|
||||
while (vg_thread_excl) {
|
||||
if (vtcp->vt_stop) {
|
||||
assert(vg_thread_excl);
|
||||
vtcp->vt_stop = 0;
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
}
|
||||
pthread_cond_wait(&vg_thread_rdcond, &vg_thread_lock);
|
||||
}
|
||||
assert(!vtcp->vt_stop);
|
||||
assert(!vtcp->vt_mode);
|
||||
vtcp->vt_mode = 1;
|
||||
}
|
||||
|
||||
void
|
||||
vg_thread_context_init(vg_context_t *vcp, vg_thread_context_t *vtcp)
|
||||
{
|
||||
vtcp->vt_mode = 0;
|
||||
vtcp->vt_stop = 0;
|
||||
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
vg_exec_context_init(vcp, &vtcp->base);
|
||||
vtcp->vt_next = vg_threads;
|
||||
vg_threads = vtcp;
|
||||
__vg_thread_yield(vtcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
void
|
||||
vg_thread_context_del(vg_thread_context_t *vtcp)
|
||||
{
|
||||
vg_thread_context_t *tp, **pprev;
|
||||
|
||||
if (vtcp->vt_mode == 2)
|
||||
vg_exec_downgrade_lock(&vtcp->base);
|
||||
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
assert(vtcp->vt_mode == 1);
|
||||
vtcp->vt_mode = 0;
|
||||
|
||||
for (pprev = &vg_threads, tp = *pprev;
|
||||
(tp != vtcp) && (tp != NULL);
|
||||
pprev = &tp->vt_next, tp = *pprev);
|
||||
|
||||
assert(tp == vtcp);
|
||||
*pprev = tp->vt_next;
|
||||
|
||||
if (tp->vt_stop)
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
|
||||
vg_exec_context_del(&vtcp->base);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
void
|
||||
vg_thread_yield(vg_thread_context_t *vtcp)
|
||||
{
|
||||
if (vtcp->vt_mode == 2)
|
||||
vg_exec_downgrade_lock(&vtcp->base);
|
||||
|
||||
else if (vtcp->vt_stop) {
|
||||
assert(vtcp->vt_mode == 1);
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
__vg_thread_yield(vtcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
assert(vtcp->vt_mode == 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
vg_exec_downgrade_lock(vg_exec_context_t *vxcp)
|
||||
{
|
||||
vg_thread_context_t *vtcp = (vg_thread_context_t *) vxcp;
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
|
||||
assert(vtcp->vt_mode == 2);
|
||||
assert(!vtcp->vt_stop);
|
||||
if (!--vg_thread_excl) {
|
||||
vtcp->vt_mode = 1;
|
||||
pthread_cond_broadcast(&vg_thread_rdcond);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
return;
|
||||
}
|
||||
pthread_cond_signal(&vg_thread_wrcond);
|
||||
__vg_thread_yield(vtcp);
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
}
|
||||
|
||||
int
|
||||
vg_exec_upgrade_lock(vg_exec_context_t *vxcp)
|
||||
{
|
||||
vg_thread_context_t *vtcp = (vg_thread_context_t *) vxcp;
|
||||
vg_thread_context_t *tp;
|
||||
|
||||
if (vtcp->vt_mode == 2)
|
||||
return 0;
|
||||
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
|
||||
assert(vtcp->vt_mode == 1);
|
||||
vtcp->vt_mode = 0;
|
||||
|
||||
if (vg_thread_excl++) {
|
||||
assert(vtcp->vt_stop);
|
||||
vtcp->vt_stop = 0;
|
||||
pthread_cond_signal(&vg_thread_upcond);
|
||||
pthread_cond_wait(&vg_thread_wrcond, &vg_thread_lock);
|
||||
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vt_next) {
|
||||
assert(!tp->vt_mode);
|
||||
assert(!tp->vt_stop);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vt_next) {
|
||||
if (tp->vt_mode) {
|
||||
assert(tp->vt_mode != 2);
|
||||
tp->vt_stop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
for (tp = vg_threads; tp != NULL; tp = tp->vt_next) {
|
||||
if (tp->vt_mode) {
|
||||
assert(tp->vt_mode != 2);
|
||||
pthread_cond_wait(&vg_thread_upcond,
|
||||
&vg_thread_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (tp);
|
||||
}
|
||||
|
||||
vtcp->vt_mode = 2;
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Address search thread main loop
|
||||
@ -224,16 +61,16 @@ vg_thread_loop(void *arg)
|
||||
EC_POINT *pbatchinc;
|
||||
|
||||
vg_test_func_t test_func = vcp->vc_test;
|
||||
vg_thread_context_t ctx;
|
||||
vg_exec_context_t ctx;
|
||||
vg_exec_context_t *vxcp;
|
||||
|
||||
struct timeval tvstart;
|
||||
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
vxcp = &ctx.base;
|
||||
vxcp = &ctx;
|
||||
|
||||
vg_thread_context_init(vcp, &ctx);
|
||||
vg_exec_context_init(vcp, &ctx);
|
||||
|
||||
pkey = vxcp->vxc_key;
|
||||
pgroup = EC_KEY_get0_group(pkey);
|
||||
@ -282,7 +119,7 @@ vg_thread_loop(void *arg)
|
||||
|
||||
while (!vcp->vc_halt) {
|
||||
if (++npoints >= rekey_at) {
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
vg_exec_context_upgrade_lock(vxcp);
|
||||
/* Generate a new random private key */
|
||||
EC_KEY_generate_key(pkey);
|
||||
npoints = 0;
|
||||
@ -299,7 +136,7 @@ vg_thread_loop(void *arg)
|
||||
assert(rekey_at > 0);
|
||||
|
||||
EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey));
|
||||
pthread_mutex_unlock(&vg_thread_lock);
|
||||
vg_exec_context_downgrade_lock(vxcp);
|
||||
|
||||
npoints++;
|
||||
vxcp->vxc_delta = 0;
|
||||
@ -387,11 +224,11 @@ vg_thread_loop(void *arg)
|
||||
c = 0;
|
||||
}
|
||||
|
||||
vg_thread_yield(&ctx);
|
||||
vg_exec_context_yield(vxcp);
|
||||
}
|
||||
|
||||
out:
|
||||
vg_thread_context_del(&ctx);
|
||||
vg_exec_context_del(&ctx);
|
||||
vg_context_thread_exit(vcp);
|
||||
|
||||
for (i = 0; i < ptarraysize; i++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user