pqc/external/flint-2.4.3/ulong_extras/compute_primes.c
2014-05-24 23:16:06 +02:00

119 lines
3.8 KiB
C

/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2009 Tom Boothby
Copyright (C) 2009 William Hart
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#define ulong ulongxx /* interferes with system includes */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#undef ulong
#include <gmp.h>
#define ulong mp_limb_t
#include "flint.h"
#include "ulong_extras.h"
#if FLINT_REENTRANT && !HAVE_TLS
#include <pthread.h>
static pthread_once_t primes_initialised = PTHREAD_ONCE_INIT;
pthread_mutex_t primes_lock;
#endif
const unsigned int flint_primes_small[] =
{
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,
191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,
281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,
389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,
491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,
607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,
719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,
829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,
953,967,971,977,983,991,997,1009,1013,1019,1021
};
/* _flint_primes[i] holds an array of 2^i primes */
FLINT_TLS_PREFIX mp_limb_t * _flint_primes[FLINT_BITS];
FLINT_TLS_PREFIX double * _flint_prime_inverses[FLINT_BITS];
FLINT_TLS_PREFIX int _flint_primes_used = 0;
#if FLINT_REENTRANT && !HAVE_TLS
void n_compute_primes_init()
{
pthread_mutex_init(&primes_lock, NULL);
}
#endif
void
n_compute_primes(ulong num_primes)
{
int i, m;
ulong num_computed;
#if FLINT_REENTRANT && !HAVE_TLS
pthread_once(&primes_initialised, n_compute_primes_init);
pthread_mutex_lock(&primes_lock);
#endif
m = FLINT_CLOG2(num_primes);
if (_flint_primes_used == 0)
flint_register_cleanup_function(n_cleanup_primes);
if (m >= _flint_primes_used)
{
n_primes_t iter;
num_computed = UWORD(1) << m;
_flint_primes[m] = flint_malloc(sizeof(mp_limb_t) * num_computed);
_flint_prime_inverses[m] = flint_malloc(sizeof(double) * num_computed);
n_primes_init(iter);
for (i = 0; i < num_computed; i++)
{
_flint_primes[m][i] = n_primes_next(iter);
_flint_prime_inverses[m][i] = n_precompute_inverse(_flint_primes[m][i]);
}
n_primes_clear(iter);
/* copy to lower power-of-two slots */
for (i = m - 1; i >= _flint_primes_used; i--)
{
_flint_primes[i] = _flint_primes[m];
_flint_prime_inverses[i] = _flint_prime_inverses[m];
}
_flint_primes_used = m + 1;
}
#if FLINT_REENTRANT && !HAVE_TLS
pthread_mutex_unlock(&primes_lock);
#endif
}