aboutsummaryrefslogtreecommitdiff
path: root/src/invalid/invalid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/invalid/invalid.c')
-rw-r--r--src/invalid/invalid.c143
1 files changed, 106 insertions, 37 deletions
diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c
index b495958..1dd4fee 100644
--- a/src/invalid/invalid.c
+++ b/src/invalid/invalid.c
@@ -4,6 +4,7 @@
*/
#include "invalid.h"
#include "exhaustive/exhaustive.h"
+#include "invalid_thread.h"
#include "io/output.h"
#include "math/curve.h"
#include "math/equation.h"
@@ -12,7 +13,7 @@
#include "math/order.h"
#include "math/point.h"
-static void invalid_ginit(gen_t *generators, config_t *cfg) {
+static void invalid_original_ginit(gen_t *generators, const config_t *cfg) {
generators[OFFSET_SEED] = &gen_skip;
if (cfg->random) {
generators[OFFSET_FIELD] = &field_random;
@@ -28,6 +29,20 @@ static void invalid_ginit(gen_t *generators, config_t *cfg) {
generators[OFFSET_ORDER] = &order_any;
}
+static void invalid_invalid_ginit(gen_t *generators, const config_t *cfg) {
+ generators[OFFSET_FIELD] = &gen_skip;
+ generators[OFFSET_A] = &gen_skip;
+ generators[OFFSET_B] = &b_random;
+ generators[OFFSET_CURVE] = &curve_nonzero;
+ generators[OFFSET_ORDER] = &order_any;
+ if (cfg->unique) {
+ generators[OFFSET_GENERATORS] = &gens_one;
+ } else {
+ generators[OFFSET_GENERATORS] = &gens_any;
+ }
+ generators[OFFSET_POINTS] = &points_trial;
+}
+
static size_t invalid_primes(GEN order, pari_ulong **primes) {
pari_sp ltop = avma;
@@ -71,30 +86,10 @@ static size_t invalid_primes(GEN order, pari_ulong **primes) {
}
static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
- size_t nprimes, curve_t ***curves) {
- gen_t invalid_gen[OFFSET_END];
- invalid_gen[OFFSET_FIELD] = &gen_skip;
- invalid_gen[OFFSET_A] = &gen_skip;
- invalid_gen[OFFSET_B] = &b_random;
- invalid_gen[OFFSET_CURVE] = &curve_nonzero;
- invalid_gen[OFFSET_ORDER] = &order_any;
- if (cfg->unique) {
- invalid_gen[OFFSET_GENERATORS] = &gens_one;
- } else {
- invalid_gen[OFFSET_GENERATORS] = &gens_any;
- }
- invalid_gen[OFFSET_POINTS] = &points_trial;
-
+ size_t nprimes, curve_t **curves,
+ gen_t invalid_gen[OFFSET_END]) {
arg_t *invalid_argss[OFFSET_END];
- // We will have nprimes curves in the end
- *curves = pari_malloc(nprimes * sizeof(curve_t *));
- if (!(*curves)) {
- perror("Couldn't malloc.");
- return 0;
- }
- memset(*curves, 0, nprimes * sizeof(curve_t *));
-
// Alloc a curve, and only alloc a new one when this pointer is saved into
// **curves
curve_t *invalid = curve_new();
@@ -113,7 +108,7 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
// if so how many?
size_t total = 0;
for (size_t i = nprimes; i-- > 0;) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
// whoo we have a new invalid curve
if (!total && cfg->verbose) {
fprintf(
@@ -132,7 +127,7 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
size_t j = 0;
pari_ulong dprimes[total];
for (size_t i = 0; i < nprimes; ++i) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
if (cfg->verbose) {
fprintf(debug, "prime %lu divides curve order.\n",
primes[i]);
@@ -150,16 +145,15 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
size_t count = 0;
for (size_t i = nprimes; i-- > 0;) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
if (count == 0) {
// save a copy on first prime divisor from range
- (*curves)[i] = invalid;
+ curves[i] = invalid;
} else {
// copy if pointer already assigned
- (*curves)[i] = curve_new();
- (*curves)[i] = curve_copy(invalid, (*curves)[i]);
+ curves[i] = curve_new_copy(invalid);
}
- output_o((*curves)[i], cfg);
+ output_o(curves[i], cfg);
ncurves++;
count++;
}
@@ -194,14 +188,71 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
return ncurves;
}
+static size_t invalid_curves_threaded(curve_t *curve, config_t *cfg,
+ pari_ulong *primes, size_t nprimes,
+ curve_t **curves,
+ gen_t invalid_gen[OFFSET_END]) {
+ pthread_t pthreads[cfg->threads];
+ thread_t threads[cfg->threads];
+ struct pari_thread pari_threads[cfg->threads];
+ pari_thread_sync();
+
+ size_t generated = 0;
+ state_e states[nprimes];
+ curve_t *local_curves[nprimes];
+ for (size_t i = 0; i < nprimes; ++i) {
+ states[i] = STATE_FREE;
+ }
+ pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_t curves_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t generated_cond = PTHREAD_COND_INITIALIZER;
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ threads[i].original_curve = curve;
+ threads[i].nprimes = nprimes;
+ threads[i].primes = primes;
+ threads[i].states = states;
+ threads[i].curves = local_curves;
+ threads[i].generated = &generated;
+ threads[i].mutex_state = &state_mutex;
+ threads[i].mutex_curves = &curves_mutex;
+ threads[i].cond_generated = &generated_cond;
+ threads[i].cfg = cfg;
+ threads[i].gens = invalid_gen;
+
+ pari_thread_alloc(&pari_threads[i], cfg->thread_memory,
+ (GEN)&threads[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pthread_create(&pthreads[i], NULL, &invalid_thread,
+ (void *)&pari_threads[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pthread_join(pthreads[i], NULL);
+ }
+
+ for (size_t i = 0; i < nprimes; ++i) {
+ curves[i] = curve_new_copy(local_curves[i]);
+ curve_free(&local_curves[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pari_thread_free(&pari_threads[i]);
+ }
+
+ return generated;
+}
+
int invalid_do(config_t *cfg) {
- // create the curve to invalidate
- // Either from input or random with -r
- curve_t *curve = curve_new();
gen_t gen[OFFSET_END];
arg_t *argss[OFFSET_END];
- invalid_ginit(gen, cfg);
+ invalid_original_ginit(gen, cfg);
+ // create the curve to invalidate
+ // Either from input or random with -
+ curve_t *curve = curve_new();
// actually generate the curve
if (!exhaustive_gen_retry(curve, cfg, gen, argss, OFFSET_FIELD,
OFFSET_POINTS, 1)) {
@@ -213,14 +264,32 @@ int invalid_do(config_t *cfg) {
// now, generate primes upto order^2
pari_ulong *primes;
size_t nprimes = invalid_primes(curve->order, &primes);
-
if (cfg->verbose) {
fprintf(debug, "primes upto: p_max = %lu, n = %lu\n",
primes[nprimes - 1], nprimes);
}
- curve_t **curves;
- size_t ncurves = invalid_curves(curve, cfg, primes, nprimes, &curves);
+ // Alloc enough curves
+ curve_t **curves = pari_malloc(nprimes * sizeof(curve_t *));
+ if (!(curves)) {
+ perror("Couldn't malloc.");
+ return 0;
+ }
+ memset(curves, 0, nprimes * sizeof(curve_t *));
+
+ // init the invalid curve gen_t
+ gen_t invalid_gen[OFFSET_END];
+ invalid_invalid_ginit(invalid_gen, cfg);
+
+ // now, generate the invalid curves for all primes
+ size_t ncurves;
+ if (cfg->threads == 1) {
+ ncurves =
+ invalid_curves(curve, cfg, primes, nprimes, curves, invalid_gen);
+ } else {
+ ncurves = invalid_curves_threaded(curve, cfg, primes, nprimes, curves,
+ invalid_gen);
+ }
for (size_t i = 0; i < ncurves; ++i) {
curve_free(&curves[i]);