Browse Source

Basic support for concurrency in OpenCL engine.

master
samr7 12 years ago
parent
commit
c21e99a58b
  1. 19
      oclengine.c
  2. 149
      pattern.c
  3. 15
      pattern.h
  4. 177
      vanitygen.c

19
oclengine.c

@ -1571,7 +1571,6 @@ vg_ocl_prefix_check(vg_ocl_context_t *vocp, int slot) @@ -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) @@ -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: @@ -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: @@ -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: @@ -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: @@ -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

@ -45,9 +45,106 @@ vg_exec_context_new_key(void) @@ -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) @@ -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 @@ -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 @@ -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) @@ -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: @@ -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: @@ -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: @@ -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

@ -33,7 +33,7 @@ @@ -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 { @@ -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); @@ -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 { @@ -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

@ -34,169 +34,6 @@ @@ -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) @@ -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) @@ -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) @@ -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) @@ -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…
Cancel
Save