mirror of
https://github.com/GOSTSec/vanitygen
synced 2025-02-07 04:14:15 +00:00
Initial multi-device OpenCL support for oclvanitygen and oclvanityminer.
This commit is contained in:
parent
53903a714c
commit
af42e55a22
101
oclengine.c
101
oclengine.c
@ -50,6 +50,7 @@
|
|||||||
#define round_up_pow2(x, a) (((x) + ((a)-1)) & ~((a)-1))
|
#define round_up_pow2(x, a) (((x) + ((a)-1)) & ~((a)-1))
|
||||||
|
|
||||||
static void vg_ocl_free_args(vg_ocl_context_t *vocp);
|
static void vg_ocl_free_args(vg_ocl_context_t *vocp);
|
||||||
|
static void *vg_opencl_loop(vg_exec_context_t *arg);
|
||||||
|
|
||||||
|
|
||||||
/* OpenCL address searching mode */
|
/* OpenCL address searching mode */
|
||||||
@ -872,6 +873,7 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did,
|
|||||||
|
|
||||||
memset(vocp, 0, sizeof(*vocp));
|
memset(vocp, 0, sizeof(*vocp));
|
||||||
vg_exec_context_init(vcp, &vocp->base);
|
vg_exec_context_init(vcp, &vocp->base);
|
||||||
|
vocp->base.vxc_threadfunc = vg_opencl_loop;
|
||||||
|
|
||||||
pthread_mutex_init(&vocp->voc_lock, NULL);
|
pthread_mutex_init(&vocp->voc_lock, NULL);
|
||||||
pthread_cond_init(&vocp->voc_wait, NULL);
|
pthread_cond_init(&vocp->voc_wait, NULL);
|
||||||
@ -1872,8 +1874,8 @@ out:
|
|||||||
* Address search thread main loop
|
* Address search thread main loop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *
|
static void *
|
||||||
vg_opencl_loop(void *arg)
|
vg_opencl_loop(vg_exec_context_t *arg)
|
||||||
{
|
{
|
||||||
vg_ocl_context_t *vocp = (vg_ocl_context_t *) arg;
|
vg_ocl_context_t *vocp = (vg_ocl_context_t *) arg;
|
||||||
int i;
|
int i;
|
||||||
@ -2397,7 +2399,7 @@ get_platform(int num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enumerate_opencl(void)
|
vg_ocl_enumerate_devices(void)
|
||||||
{
|
{
|
||||||
cl_platform_id *pids;
|
cl_platform_id *pids;
|
||||||
cl_device_id *dids;
|
cl_device_id *dids;
|
||||||
@ -2420,7 +2422,7 @@ enumerate_opencl(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cl_device_id
|
static cl_device_id
|
||||||
get_opencl_device(int platformidx, int deviceidx)
|
get_opencl_device(int platformidx, int deviceidx)
|
||||||
{
|
{
|
||||||
cl_platform_id pid;
|
cl_platform_id pid;
|
||||||
@ -2432,7 +2434,6 @@ get_opencl_device(int platformidx, int deviceidx)
|
|||||||
if (did)
|
if (did)
|
||||||
return did;
|
return did;
|
||||||
}
|
}
|
||||||
enumerate_opencl();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2603,6 +2604,96 @@ out_fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vg_ocl_context_t *
|
||||||
|
vg_ocl_context_new_from_devstr(vg_context_t *vcp, const char *devstr,
|
||||||
|
int safemode, int verify)
|
||||||
|
{
|
||||||
|
int platformidx, deviceidx;
|
||||||
|
int worksize = 0, nthreads = 0, nrows = 0, ncols = 0, invsize = 0;
|
||||||
|
|
||||||
|
char *dsd, *part, *part2, *save, *param;
|
||||||
|
|
||||||
|
dsd = strdup(devstr);
|
||||||
|
if (!dsd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
save = NULL;
|
||||||
|
part = strtok_r(dsd, ",", &save);
|
||||||
|
|
||||||
|
part2 = strchr(part, ':');
|
||||||
|
if (!part2) {
|
||||||
|
fprintf(stderr, "Invalid device specifier '%s'\n", part);
|
||||||
|
free(dsd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*part2 = '\0';
|
||||||
|
platformidx = atoi(part);
|
||||||
|
deviceidx = atoi(part2 + 1);
|
||||||
|
|
||||||
|
while ((part = strtok_r(NULL, ",", &save)) != NULL) {
|
||||||
|
param = strchr(part, '=');
|
||||||
|
if (!param) {
|
||||||
|
fprintf(stderr, "Unrecognized parameter '%s'\n", part);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*param = '\0';
|
||||||
|
param++;
|
||||||
|
|
||||||
|
if (!strcmp(part, "grid")) {
|
||||||
|
ncols = strtol(param, &part2, 0);
|
||||||
|
if (part2 && *part2 == 'x') {
|
||||||
|
nrows = strtol(part2+1, NULL, 0);
|
||||||
|
}
|
||||||
|
if (!nrows || !ncols) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid grid size '%s'\n", param);
|
||||||
|
nrows = 0;
|
||||||
|
ncols = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!strcmp(part, "invsize")) {
|
||||||
|
invsize = atoi(param);
|
||||||
|
if (!invsize) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid modular inverse size '%s'\n",
|
||||||
|
param);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (invsize & (invsize - 1)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Modular inverse size %d must be "
|
||||||
|
"a power of 2\n", invsize);
|
||||||
|
invsize = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!strcmp(part, "threads")) {
|
||||||
|
nthreads = atoi(param);
|
||||||
|
if (nthreads == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid thread count '%s'\n", optarg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Unrecognized parameter '%s'\n", part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dsd);
|
||||||
|
|
||||||
|
return vg_ocl_context_new(vcp, platformidx, deviceidx, safemode,
|
||||||
|
verify, worksize, nthreads, nrows, ncols,
|
||||||
|
invsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vg_ocl_context_free(vg_ocl_context_t *vocp)
|
vg_ocl_context_free(vg_ocl_context_t *vocp)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,10 @@ extern vg_ocl_context_t *vg_ocl_context_new(
|
|||||||
int invsize);
|
int invsize);
|
||||||
extern void vg_ocl_context_free(vg_ocl_context_t *vocp);
|
extern void vg_ocl_context_free(vg_ocl_context_t *vocp);
|
||||||
|
|
||||||
extern void *vg_opencl_loop(void *vocp);
|
extern vg_ocl_context_t *vg_ocl_context_new_from_devstr(
|
||||||
|
vg_context_t *vcp, const char *devstr, int safemode, int verify)
|
||||||
|
;
|
||||||
|
|
||||||
|
extern void vg_ocl_enumerate_devices(void);
|
||||||
|
|
||||||
#endif /* !defined (__VG_OCLENGINE_H__) */
|
#endif /* !defined (__VG_OCLENGINE_H__) */
|
||||||
|
@ -45,6 +45,11 @@ usage(const char *name)
|
|||||||
"location or imported into a bitcoin client to spend any balance received on\n"
|
"location or imported into a bitcoin client to spend any balance received on\n"
|
||||||
"the address.\n"
|
"the address.\n"
|
||||||
"By default, <pattern> is interpreted as an exact prefix.\n"
|
"By default, <pattern> is interpreted as an exact prefix.\n"
|
||||||
|
"By default, if no device is specified, and the system has exactly one OpenCL\n"
|
||||||
|
"device, it will be selected automatically, otherwise if the system has\n"
|
||||||
|
"multiple OpenCL devices and no device is specified, an error will be\n"
|
||||||
|
"reported. To use multiple devices simultaneously, specify the -D option for\n"
|
||||||
|
"each device.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"-v Verbose output\n"
|
"-v Verbose output\n"
|
||||||
@ -58,6 +63,9 @@ usage(const char *name)
|
|||||||
"-E <password> Encrypt private keys with <password> (UNSAFE)\n"
|
"-E <password> Encrypt private keys with <password> (UNSAFE)\n"
|
||||||
"-p <platform> Select OpenCL platform\n"
|
"-p <platform> Select OpenCL platform\n"
|
||||||
"-d <device> Select OpenCL device\n"
|
"-d <device> Select OpenCL device\n"
|
||||||
|
"-D <devstr> Use OpenCL device, identified by device string\n"
|
||||||
|
" Form: <platform>:<devicenumber>[,<options>]\n"
|
||||||
|
" Example: 0:0,grid=1024x1024\n"
|
||||||
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
|
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
|
||||||
"-w <worksize> Set work items per thread in a work unit\n"
|
"-w <worksize> Set work items per thread in a work unit\n"
|
||||||
"-t <threads> Set target thread count per multiprocessor\n"
|
"-t <threads> Set target thread count per multiprocessor\n"
|
||||||
@ -71,6 +79,8 @@ usage(const char *name)
|
|||||||
version, name);
|
version, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_DEVS 32
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -99,9 +109,12 @@ main(int argc, char **argv)
|
|||||||
EC_POINT *pubkey_base = NULL;
|
EC_POINT *pubkey_base = NULL;
|
||||||
const char *result_file = NULL;
|
const char *result_file = NULL;
|
||||||
const char *key_password = NULL;
|
const char *key_password = NULL;
|
||||||
|
char *devstrs[MAX_DEVS];
|
||||||
|
int ndevstrs = 0;
|
||||||
|
int opened = 0;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
while ((opt = getopt(argc, argv,
|
||||||
"vqikNTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:")) != -1) {
|
"vqikNTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:D:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 2;
|
verbose = 2;
|
||||||
@ -188,6 +201,15 @@ main(int argc, char **argv)
|
|||||||
case 'S':
|
case 'S':
|
||||||
safe_mode = 1;
|
safe_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (ndevstrs >= MAX_DEVS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Too many OpenCL devices (limit %d)\n",
|
||||||
|
MAX_DEVS);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
devstrs[ndevstrs++] = optarg;
|
||||||
|
break;
|
||||||
case 'P': {
|
case 'P': {
|
||||||
if (pubkey_base != NULL) {
|
if (pubkey_base != NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -338,14 +360,38 @@ main(int argc, char **argv)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Regular expressions: %ld\n", vcp->vc_npatterns);
|
"Regular expressions: %ld\n", vcp->vc_npatterns);
|
||||||
|
|
||||||
vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
|
if (ndevstrs) {
|
||||||
safe_mode, verify_mode,
|
for (opt = 0; opt < ndevstrs; opt++) {
|
||||||
worksize, nthreads, nrows, ncols, invsize);
|
vocp = vg_ocl_context_new_from_devstr(vcp, devstrs[opt],
|
||||||
if (!vocp) {
|
safe_mode,
|
||||||
|
verify_mode);
|
||||||
|
if (!vocp) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not open device '%s', ignoring\n",
|
||||||
|
devstrs[opt]);
|
||||||
|
} else {
|
||||||
|
opened++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
|
||||||
|
safe_mode, verify_mode,
|
||||||
|
worksize, nthreads,
|
||||||
|
nrows, ncols, invsize);
|
||||||
|
if (vocp)
|
||||||
|
opened++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opened) {
|
||||||
|
vg_ocl_enumerate_devices();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vg_opencl_loop(vocp);
|
opt = vg_context_start_threads(vcp);
|
||||||
|
if (opt)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
vg_context_wait_for_completion(vcp);
|
||||||
vg_ocl_context_free(vocp);
|
vg_ocl_context_free(vocp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -735,6 +735,11 @@ usage(const char *name)
|
|||||||
"generate the address with the best difficulty to reward ratio. Maintains\n"
|
"generate the address with the best difficulty to reward ratio. Maintains\n"
|
||||||
"contact with the bounty pool server and periodically refreshes the bounty\n"
|
"contact with the bounty pool server and periodically refreshes the bounty\n"
|
||||||
"list.\n"
|
"list.\n"
|
||||||
|
"By default, if no device is specified, and the system has exactly one OpenCL\n"
|
||||||
|
"device, it will be selected automatically, otherwise if the system has\n"
|
||||||
|
"multiple OpenCL devices and no device is specified, an error will be\n"
|
||||||
|
"reported. To use multiple devices simultaneously, specify the -D option for\n"
|
||||||
|
"each device.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"-u <URL> Bounty pool URL\n"
|
"-u <URL> Bounty pool URL\n"
|
||||||
@ -744,6 +749,9 @@ usage(const char *name)
|
|||||||
"-q Quiet output\n"
|
"-q Quiet output\n"
|
||||||
"-p <platform> Select OpenCL platform\n"
|
"-p <platform> Select OpenCL platform\n"
|
||||||
"-d <device> Select OpenCL device\n"
|
"-d <device> Select OpenCL device\n"
|
||||||
|
"-D <devstr> Use OpenCL device, identified by device string\n"
|
||||||
|
" Form: <platform>:<devicenumber>[,<options>]\n"
|
||||||
|
" Example: 0:0,grid=1024x1024\n"
|
||||||
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
|
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
|
||||||
"-w <worksize> Set work items per thread in a work unit\n"
|
"-w <worksize> Set work items per thread in a work unit\n"
|
||||||
"-t <threads> Set target thread count per multiprocessor\n"
|
"-t <threads> Set target thread count per multiprocessor\n"
|
||||||
@ -753,6 +761,7 @@ usage(const char *name)
|
|||||||
version, name);
|
version, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_DEVS 32
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
@ -770,12 +779,15 @@ main(int argc, char **argv)
|
|||||||
int invsize = 0;
|
int invsize = 0;
|
||||||
int verify_mode = 0;
|
int verify_mode = 0;
|
||||||
int safe_mode = 0;
|
int safe_mode = 0;
|
||||||
|
|
||||||
|
char *devstrs[MAX_DEVS];
|
||||||
|
int ndevstrs = 0;
|
||||||
|
|
||||||
vg_context_t *vcp = NULL;
|
vg_context_t *vcp = NULL;
|
||||||
vg_ocl_context_t *vocp = NULL;
|
vg_ocl_context_t *vocp = NULL;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
int thread_started = 0;
|
int thread_started = 0;
|
||||||
pthread_t thread;
|
|
||||||
pubkeybatch_t *active_pkb = NULL;
|
pubkeybatch_t *active_pkb = NULL;
|
||||||
|
|
||||||
server_context_t *scp = NULL;
|
server_context_t *scp = NULL;
|
||||||
@ -794,7 +806,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
while ((opt = getopt(argc, argv,
|
||||||
"u:a:vqp:d:w:t:g:b:VSh?i:")) != -1) {
|
"u:a:vqp:d:w:t:g:b:VD:Sh?i:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'u':
|
case 'u':
|
||||||
url = optarg;
|
url = optarg;
|
||||||
@ -871,6 +883,15 @@ main(int argc, char **argv)
|
|||||||
case 'S':
|
case 'S':
|
||||||
safe_mode = 1;
|
safe_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (ndevstrs >= MAX_DEVS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Too many OpenCL devices (limit %d)\n",
|
||||||
|
MAX_DEVS);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
devstrs[ndevstrs++] = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
@ -915,6 +936,34 @@ main(int argc, char **argv)
|
|||||||
if (server_context_getwork(scp))
|
if (server_context_getwork(scp))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Set up OpenCL */
|
||||||
|
res = 0;
|
||||||
|
if (ndevstrs) {
|
||||||
|
for (opt = 0; opt < ndevstrs; opt++) {
|
||||||
|
vocp = vg_ocl_context_new_from_devstr(vcp, devstrs[opt],
|
||||||
|
safe_mode,
|
||||||
|
verify_mode);
|
||||||
|
if (!vocp) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not open device '%s', ignoring\n",
|
||||||
|
devstrs[opt]);
|
||||||
|
} else {
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
|
||||||
|
safe_mode, verify_mode,
|
||||||
|
worksize, nthreads,
|
||||||
|
nrows, ncols, invsize);
|
||||||
|
if (vocp)
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
if (!res) {
|
||||||
|
vg_ocl_enumerate_devices();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (avl_root_empty(&scp->items))
|
if (avl_root_empty(&scp->items))
|
||||||
server_context_getwork(scp);
|
server_context_getwork(scp);
|
||||||
@ -929,10 +978,8 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (thread_started && (!active_pkb || (pkb != active_pkb))) {
|
if (thread_started && (!active_pkb || (pkb != active_pkb))) {
|
||||||
/* If a thread is running, stop it */
|
/* If a thread is running, stop it */
|
||||||
vcp->vc_halt = 1;
|
vg_context_stop_threads(vcp);
|
||||||
pthread_join(thread, NULL);
|
|
||||||
thread_started = 0;
|
thread_started = 0;
|
||||||
vcp->vc_halt = 0;
|
|
||||||
if (active_pkb) {
|
if (active_pkb) {
|
||||||
check_solution(scp, active_pkb);
|
check_solution(scp, active_pkb);
|
||||||
active_pkb = NULL;
|
active_pkb = NULL;
|
||||||
@ -970,18 +1017,9 @@ main(int argc, char **argv)
|
|||||||
assert(vcp->vc_npatterns);
|
assert(vcp->vc_npatterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vocp) {
|
res = vg_context_start_threads(vcp);
|
||||||
vocp = vg_ocl_context_new(vcp,
|
if (res)
|
||||||
platformidx, deviceidx,
|
return 1;
|
||||||
safe_mode, verify_mode,
|
|
||||||
worksize, nthreads, nrows,
|
|
||||||
ncols, invsize);
|
|
||||||
if (!vocp)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = pthread_create(&thread, NULL,
|
|
||||||
vg_opencl_loop, vocp);
|
|
||||||
thread_started = 1;
|
thread_started = 1;
|
||||||
active_pkb = pkb;
|
active_pkb = pkb;
|
||||||
}
|
}
|
||||||
|
70
pattern.c
70
pattern.c
@ -54,16 +54,14 @@ 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_rdcond = PTHREAD_COND_INITIALIZER;
|
||||||
static pthread_cond_t vg_thread_wrcond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t vg_thread_wrcond = PTHREAD_COND_INITIALIZER;
|
||||||
static pthread_cond_t vg_thread_upcond = 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
|
static void
|
||||||
__vg_exec_context_yield(vg_exec_context_t *vxcp)
|
__vg_exec_context_yield(vg_exec_context_t *vxcp)
|
||||||
{
|
{
|
||||||
vxcp->vxc_lockmode = 0;
|
vxcp->vxc_lockmode = 0;
|
||||||
while (vg_thread_excl) {
|
while (vxcp->vxc_vc->vc_thread_excl) {
|
||||||
if (vxcp->vxc_stop) {
|
if (vxcp->vxc_stop) {
|
||||||
assert(vg_thread_excl);
|
assert(vxcp->vxc_vc->vc_thread_excl);
|
||||||
vxcp->vxc_stop = 0;
|
vxcp->vxc_stop = 0;
|
||||||
pthread_cond_signal(&vg_thread_upcond);
|
pthread_cond_signal(&vg_thread_upcond);
|
||||||
}
|
}
|
||||||
@ -78,6 +76,7 @@ int
|
|||||||
vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp)
|
vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp)
|
||||||
{
|
{
|
||||||
vg_exec_context_t *tp;
|
vg_exec_context_t *tp;
|
||||||
|
vg_context_t *vcp;
|
||||||
|
|
||||||
if (vxcp->vxc_lockmode == 2)
|
if (vxcp->vxc_lockmode == 2)
|
||||||
return 0;
|
return 0;
|
||||||
@ -86,20 +85,21 @@ vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp)
|
|||||||
|
|
||||||
assert(vxcp->vxc_lockmode == 1);
|
assert(vxcp->vxc_lockmode == 1);
|
||||||
vxcp->vxc_lockmode = 0;
|
vxcp->vxc_lockmode = 0;
|
||||||
|
vcp = vxcp->vxc_vc;
|
||||||
|
|
||||||
if (vg_thread_excl++) {
|
if (vcp->vc_thread_excl++) {
|
||||||
assert(vxcp->vxc_stop);
|
assert(vxcp->vxc_stop);
|
||||||
vxcp->vxc_stop = 0;
|
vxcp->vxc_stop = 0;
|
||||||
pthread_cond_signal(&vg_thread_upcond);
|
pthread_cond_signal(&vg_thread_upcond);
|
||||||
pthread_cond_wait(&vg_thread_wrcond, &vg_thread_lock);
|
pthread_cond_wait(&vg_thread_wrcond, &vg_thread_lock);
|
||||||
|
|
||||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
for (tp = vcp->vc_threads; tp != NULL; tp = tp->vxc_next) {
|
||||||
assert(!tp->vxc_lockmode);
|
assert(!tp->vxc_lockmode);
|
||||||
assert(!tp->vxc_stop);
|
assert(!tp->vxc_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
for (tp = vcp->vc_threads; tp != NULL; tp = tp->vxc_next) {
|
||||||
if (tp->vxc_lockmode) {
|
if (tp->vxc_lockmode) {
|
||||||
assert(tp->vxc_lockmode != 2);
|
assert(tp->vxc_lockmode != 2);
|
||||||
tp->vxc_stop = 1;
|
tp->vxc_stop = 1;
|
||||||
@ -107,7 +107,9 @@ vg_exec_context_upgrade_lock(vg_exec_context_t *vxcp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
for (tp = vg_threads; tp != NULL; tp = tp->vxc_next) {
|
for (tp = vcp->vc_threads;
|
||||||
|
tp != NULL;
|
||||||
|
tp = tp->vxc_next) {
|
||||||
if (tp->vxc_lockmode) {
|
if (tp->vxc_lockmode) {
|
||||||
assert(tp->vxc_lockmode != 2);
|
assert(tp->vxc_lockmode != 2);
|
||||||
pthread_cond_wait(&vg_thread_upcond,
|
pthread_cond_wait(&vg_thread_upcond,
|
||||||
@ -127,10 +129,9 @@ void
|
|||||||
vg_exec_context_downgrade_lock(vg_exec_context_t *vxcp)
|
vg_exec_context_downgrade_lock(vg_exec_context_t *vxcp)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&vg_thread_lock);
|
pthread_mutex_lock(&vg_thread_lock);
|
||||||
|
|
||||||
assert(vxcp->vxc_lockmode == 2);
|
assert(vxcp->vxc_lockmode == 2);
|
||||||
assert(!vxcp->vxc_stop);
|
assert(!vxcp->vxc_stop);
|
||||||
if (!--vg_thread_excl) {
|
if (!--vxcp->vxc_vc->vc_thread_excl) {
|
||||||
vxcp->vxc_lockmode = 1;
|
vxcp->vxc_lockmode = 1;
|
||||||
pthread_cond_broadcast(&vg_thread_rdcond);
|
pthread_cond_broadcast(&vg_thread_rdcond);
|
||||||
pthread_mutex_unlock(&vg_thread_lock);
|
pthread_mutex_unlock(&vg_thread_lock);
|
||||||
@ -166,8 +167,8 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
|
|||||||
vxcp->vxc_lockmode = 0;
|
vxcp->vxc_lockmode = 0;
|
||||||
vxcp->vxc_stop = 0;
|
vxcp->vxc_stop = 0;
|
||||||
|
|
||||||
vxcp->vxc_next = vg_threads;
|
vxcp->vxc_next = vcp->vc_threads;
|
||||||
vg_threads = vxcp;
|
vcp->vc_threads = vxcp;
|
||||||
__vg_exec_context_yield(vxcp);
|
__vg_exec_context_yield(vxcp);
|
||||||
pthread_mutex_unlock(&vg_thread_lock);
|
pthread_mutex_unlock(&vg_thread_lock);
|
||||||
return 1;
|
return 1;
|
||||||
@ -185,7 +186,7 @@ vg_exec_context_del(vg_exec_context_t *vxcp)
|
|||||||
assert(vxcp->vxc_lockmode == 1);
|
assert(vxcp->vxc_lockmode == 1);
|
||||||
vxcp->vxc_lockmode = 0;
|
vxcp->vxc_lockmode = 0;
|
||||||
|
|
||||||
for (pprev = &vg_threads, tp = *pprev;
|
for (pprev = &vxcp->vxc_vc->vc_threads, tp = *pprev;
|
||||||
(tp != vxcp) && (tp != NULL);
|
(tp != vxcp) && (tp != NULL);
|
||||||
pprev = &tp->vxc_next, tp = *pprev);
|
pprev = &tp->vxc_next, tp = *pprev);
|
||||||
|
|
||||||
@ -634,6 +635,49 @@ vg_context_hash160_sort(vg_context_t *vcp, void *buf)
|
|||||||
return vcp->vc_hash160_sort(vcp, buf);
|
return vcp->vc_hash160_sort(vcp, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vg_context_start_threads(vg_context_t *vcp)
|
||||||
|
{
|
||||||
|
vg_exec_context_t *vxcp;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
for (vxcp = vcp->vc_threads; vxcp != NULL; vxcp = vxcp->vxc_next) {
|
||||||
|
res = pthread_create((pthread_t *) &vxcp->vxc_pthread,
|
||||||
|
NULL,
|
||||||
|
(void *(*)(void *)) vxcp->vxc_threadfunc,
|
||||||
|
vxcp);
|
||||||
|
if (res) {
|
||||||
|
fprintf(stderr, "ERROR: could not create thread: %d\n",
|
||||||
|
res);
|
||||||
|
vg_context_stop_threads(vcp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
vxcp->vxc_thread_active = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vg_context_stop_threads(vg_context_t *vcp)
|
||||||
|
{
|
||||||
|
vcp->vc_halt = 1;
|
||||||
|
vg_context_wait_for_completion(vcp);
|
||||||
|
vcp->vc_halt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vg_context_wait_for_completion(vg_context_t *vcp)
|
||||||
|
{
|
||||||
|
vg_exec_context_t *vxcp;
|
||||||
|
|
||||||
|
for (vxcp = vcp->vc_threads; vxcp != NULL; vxcp = vxcp->vxc_next) {
|
||||||
|
if (!vxcp->vxc_thread_active)
|
||||||
|
continue;
|
||||||
|
pthread_join((pthread_t) vxcp->vxc_pthread, NULL);
|
||||||
|
vxcp->vxc_thread_active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the bignum ranges that produce a given prefix.
|
* Find the bignum ranges that produce a given prefix.
|
||||||
|
61
pattern.h
61
pattern.h
@ -22,6 +22,8 @@
|
|||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "winglue.h"
|
#include "winglue.h"
|
||||||
#else
|
#else
|
||||||
@ -35,11 +37,15 @@
|
|||||||
|
|
||||||
#define VANITYGEN_VERSION "0.20pre"
|
#define VANITYGEN_VERSION "0.20pre"
|
||||||
|
|
||||||
|
|
||||||
typedef struct _vg_context_s vg_context_t;
|
typedef struct _vg_context_s vg_context_t;
|
||||||
|
|
||||||
|
struct _vg_exec_context_s;
|
||||||
|
typedef struct _vg_exec_context_s vg_exec_context_t;
|
||||||
|
|
||||||
|
typedef void *(*vg_exec_context_threadfunc_t)(vg_exec_context_t *);
|
||||||
|
|
||||||
/* Context of one pattern-matching unit within the process */
|
/* Context of one pattern-matching unit within the process */
|
||||||
typedef struct _vg_exec_context_s {
|
struct _vg_exec_context_s {
|
||||||
vg_context_t *vxc_vc;
|
vg_context_t *vxc_vc;
|
||||||
BN_CTX *vxc_bnctx;
|
BN_CTX *vxc_bnctx;
|
||||||
EC_KEY *vxc_key;
|
EC_KEY *vxc_key;
|
||||||
@ -50,23 +56,15 @@ typedef struct _vg_exec_context_s {
|
|||||||
BIGNUM vxc_bntmp;
|
BIGNUM vxc_bntmp;
|
||||||
BIGNUM vxc_bntmp2;
|
BIGNUM vxc_bntmp2;
|
||||||
|
|
||||||
|
vg_exec_context_threadfunc_t vxc_threadfunc;
|
||||||
|
pthread_t vxc_pthread;
|
||||||
|
int vxc_thread_active;
|
||||||
|
|
||||||
/* Thread synchronization */
|
/* Thread synchronization */
|
||||||
struct _vg_exec_context_s *vxc_next;
|
struct _vg_exec_context_s *vxc_next;
|
||||||
int vxc_lockmode;
|
int vxc_lockmode;
|
||||||
int vxc_stop;
|
int vxc_stop;
|
||||||
} vg_exec_context_t;
|
};
|
||||||
|
|
||||||
/* Init/cleanup for common execution context */
|
|
||||||
extern int vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp);
|
|
||||||
extern void vg_exec_context_del(vg_exec_context_t *vxcp);
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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 *);
|
typedef void (*vg_free_func_t)(vg_context_t *);
|
||||||
@ -106,6 +104,9 @@ struct _vg_context_s {
|
|||||||
EC_POINT *vc_pubkey_base;
|
EC_POINT *vc_pubkey_base;
|
||||||
int vc_halt;
|
int vc_halt;
|
||||||
|
|
||||||
|
vg_exec_context_t *vc_threads;
|
||||||
|
int vc_thread_excl;
|
||||||
|
|
||||||
/* Internal methods */
|
/* Internal methods */
|
||||||
vg_free_func_t vc_free;
|
vg_free_func_t vc_free;
|
||||||
vg_add_pattern_func_t vc_add_patterns;
|
vg_add_pattern_func_t vc_add_patterns;
|
||||||
@ -126,26 +127,48 @@ struct _vg_context_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Base context methods */
|
||||||
extern void vg_context_free(vg_context_t *vcp);
|
extern void vg_context_free(vg_context_t *vcp);
|
||||||
extern int vg_context_add_patterns(vg_context_t *vcp,
|
extern int vg_context_add_patterns(vg_context_t *vcp,
|
||||||
const char ** const patterns, int npatterns);
|
const char ** const patterns, int npatterns);
|
||||||
extern void vg_context_clear_all_patterns(vg_context_t *vcp);
|
extern void vg_context_clear_all_patterns(vg_context_t *vcp);
|
||||||
extern int vg_context_hash160_sort(vg_context_t *vcp, void *buf);
|
extern int vg_context_start_threads(vg_context_t *vcp);
|
||||||
extern void vg_context_thread_exit(vg_context_t *vcp);
|
extern void vg_context_stop_threads(vg_context_t *vcp);
|
||||||
|
extern void vg_context_wait_for_completion(vg_context_t *vcp);
|
||||||
|
|
||||||
|
/* Prefix context methods */
|
||||||
extern vg_context_t *vg_prefix_context_new(int addrtype, int privtype,
|
extern vg_context_t *vg_prefix_context_new(int addrtype, int privtype,
|
||||||
int caseinsensitive);
|
int caseinsensitive);
|
||||||
extern double vg_prefix_get_difficulty(int addrtype, const char *pattern);
|
extern double vg_prefix_get_difficulty(int addrtype, const char *pattern);
|
||||||
|
|
||||||
|
/* Regex context methods */
|
||||||
extern vg_context_t *vg_regex_context_new(int addrtype, int privtype);
|
extern vg_context_t *vg_regex_context_new(int addrtype, int privtype);
|
||||||
|
|
||||||
|
/* Utility functions */
|
||||||
extern int vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last);
|
extern int vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last);
|
||||||
|
|
||||||
extern void vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey,
|
extern void vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey,
|
||||||
const char *pattern);
|
const char *pattern);
|
||||||
extern void vg_output_timing_console(vg_context_t *vcp, double count,
|
extern void vg_output_timing_console(vg_context_t *vcp, double count,
|
||||||
unsigned long long rate,
|
unsigned long long rate,
|
||||||
unsigned long long total);
|
unsigned long long total);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal vg_context methods */
|
||||||
|
extern int vg_context_hash160_sort(vg_context_t *vcp, void *buf);
|
||||||
|
extern void vg_context_thread_exit(vg_context_t *vcp);
|
||||||
|
|
||||||
|
/* Internal Init/cleanup for common execution context */
|
||||||
|
extern int vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp);
|
||||||
|
extern void vg_exec_context_del(vg_exec_context_t *vxcp);
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Internal 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);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !defined (__VG_PATTERN_H__) */
|
#endif /* !defined (__VG_PATTERN_H__) */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user