[libmath-prime-util-perl] 15/16: Move from mallloc/free to New/Safefree
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:27 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.06
in repository libmath-prime-util-perl.
commit e8a0765cd9de6c5f6e1b72290a797cf4c1a40f22
Author: Dana Jacobsen <dana at acm.org>
Date: Thu Jun 14 09:25:31 2012 -0500
Move from mallloc/free to New/Safefree
---
Changes | 3 +++
MANIFEST | 2 ++
Makefile.PL | 6 ++++-
TODO | 3 +++
XS.xs | 16 ++++++------
cache.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cache.h | 15 +++++++++++
sieve.c | 72 +++-------------------------------------------------
sieve.h | 4 ---
util.c | 21 ++--------------
util.h | 4 ---
11 files changed, 126 insertions(+), 104 deletions(-)
diff --git a/Changes b/Changes
index f845e32..bf0ce81 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
Revision history for Perl extension Math::Prime::Util.
+0.06 18 June 2012
+ - Change to New/Safefree from malloc. Oops.
+
0.05 11 June 2012
- Speed up mulmod: asm for GCC + x86_64, native 64-bit for 32-bit Perl
is uint64_t is available, and range tests for others. This speeds up
diff --git a/MANIFEST b/MANIFEST
index 0fca5aa..7102ba0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -8,6 +8,8 @@ TODO
XS.xs
bitarray.h
ptypes.h
+cache.h
+cache.c
factor.h
factor.c
sieve.h
diff --git a/Makefile.PL b/Makefile.PL
index 752dcef..16d53ac 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -10,7 +10,11 @@ WriteMakefile1(
LIBS => [''], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '', # e.g., '-I/usr/include/other'
- OBJECT => 'factor.o sieve.o util.o XS.o',
+ OBJECT => 'cache.o ' .
+ 'factor.o ' .
+ 'sieve.o ' .
+ 'util.o ' .
+ 'XS.o',
PREREQ_PM => {
'Test::More' => '0.45',
diff --git a/TODO b/TODO
index 6f36135..6134228 100644
--- a/TODO
+++ b/TODO
@@ -24,3 +24,6 @@
1) mutex (holy slowdown, batman)
2) use one cache, and malloc/free if the cache isn't available.
For sieve I think we'll need a counting semaphore.
+
+- Move .c / .h files into separate directory.
+ version does it in a painful way. Something simpler to be had?
diff --git a/XS.xs b/XS.xs
index f1e072d..c43a013 100644
--- a/XS.xs
+++ b/XS.xs
@@ -4,6 +4,7 @@
#include "XSUB.h"
/* We're not using anything for which we need ppport.h */
#include "ptypes.h"
+#include "cache.h"
#include "sieve.h"
#include "util.h"
#include "bitarray.h"
@@ -128,11 +129,9 @@ trial_primes(IN UV low, IN UV high)
RETVAL
SV*
-segment_primes(IN UV low, IN UV high, IN UV segment_size = 65536UL)
+segment_primes(IN UV low, IN UV high);
PREINIT:
AV* av = newAV();
- unsigned char* sieve;
- UV low_d, high_d;
CODE:
if ((low <= 2) && (high >= 2)) { av_push(av, newSVuv( 2 )); }
if ((low <= 3) && (high >= 3)) { av_push(av, newSVuv( 3 )); }
@@ -140,9 +139,11 @@ segment_primes(IN UV low, IN UV high, IN UV segment_size = 65536UL)
if (low < 7) low = 7;
if (low <= high) {
/* Call the segment siever one or more times */
- sieve = (unsigned char*) malloc( segment_size );
+ UV low_d, high_d;
+ UV segment_size = SEGMENT_CHUNK_SIZE;
+ unsigned char* sieve = get_prime_segment();
if (sieve == 0)
- croak("Could not allocate %"UVuf" bytes for segment sieve", segment_size);
+ croak("Could not get segment cache");
/* To protect vs. overflow, work entirely with d. */
low_d = low / 30;
@@ -178,7 +179,6 @@ segment_primes(IN UV low, IN UV high, IN UV segment_size = 65536UL)
low_d += range_d;
low = seghigh+2;
}
- free(sieve);
}
RETVAL = newRV_noinc( (SV*) av );
OUTPUT:
@@ -202,7 +202,7 @@ erat_primes(IN UV low, IN UV high)
START_DO_FOR_EACH_SIEVE_PRIME( sieve, low, high ) {
av_push(av,newSVuv(p));
} END_DO_FOR_EACH_SIEVE_PRIME
- free(sieve);
+ Safefree(sieve);
}
}
RETVAL = newRV_noinc( (SV*) av );
@@ -230,7 +230,7 @@ erat_simple_primes(IN UV low, IN UV high)
av_push(av,newSVuv( 2*s+1 ));
}
}
- free(sieve);
+ Safefree(sieve);
}
}
RETVAL = newRV_noinc( (SV*) av );
diff --git a/cache.c b/cache.c
new file mode 100644
index 0000000..593564f
--- /dev/null
+++ b/cache.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ptypes.h"
+#include "cache.h"
+#include "sieve.h"
+
+
+static unsigned char* prime_cache_sieve = 0;
+static UV prime_cache_size = 0;
+
+/* Get the maximum sieved value of the cached prime sieve. */
+UV get_prime_cache_size(void) { return prime_cache_size; }
+
+/*
+ * Get the size and a pointer to the cached prime sieve.
+ * Returns the maximum sieved value in the sieve.
+ * Allocates and sieves if needed.
+ *
+ * The sieve holds 30 numbers per byte, using a mod-30 wheel.
+ */
+UV get_prime_cache(UV n, const unsigned char** sieve)
+{
+ if (prime_cache_size < n) {
+
+ if (prime_cache_sieve != 0)
+ Safefree(prime_cache_sieve);
+ prime_cache_sieve = 0;
+ prime_cache_size = 0;
+
+ /* Sieve a bit more than asked, to mitigate thrashing */
+ if (n >= (UV_MAX-3840))
+ n = UV_MAX;
+ else
+ n = ((n + 3840)/30)*30;
+ /* TODO: testing near 2^32-1 */
+
+ prime_cache_sieve = sieve_erat30(n);
+
+ if (prime_cache_sieve != 0)
+ prime_cache_size = n;
+ }
+
+ if (sieve != 0)
+ *sieve = prime_cache_sieve;
+ return prime_cache_size;
+}
+
+
+
+static unsigned char* prime_segment = 0;
+unsigned char* get_prime_segment(void) {
+ if (prime_segment == 0)
+ New(0, prime_segment, SEGMENT_CHUNK_SIZE, unsigned char);
+ if (prime_segment == 0)
+ croak("Could not allocate %"UVuf" bytes for segment sieve", SEGMENT_CHUNK_SIZE);
+ return prime_segment;
+}
+void free_prime_segment(void) {
+ if (prime_segment != 0)
+ Safefree(prime_segment);
+ prime_segment = 0;
+}
+
+
+
+void _prime_memfreeall(void)
+{
+ if (prime_cache_sieve != 0)
+ Safefree(prime_cache_sieve);
+ prime_cache_sieve = 0;
+ prime_cache_size = 0;
+
+ free_prime_segment();
+}
+
+void prime_memfree(void)
+{
+ _prime_memfreeall();
+
+ prime_precalc(0);
+}
+
diff --git a/cache.h b/cache.h
new file mode 100644
index 0000000..7423df2
--- /dev/null
+++ b/cache.h
@@ -0,0 +1,15 @@
+#ifndef MPU_CACHE_H
+#define MPU_CACHE_H
+
+#include "EXTERN.h"
+#include "perl.h"
+
+extern UV get_prime_cache_size(void);
+extern UV get_prime_cache(UV n, const unsigned char** sieve);
+
+extern void prime_memfree(void);
+
+#define SEGMENT_CHUNK_SIZE UVCONST(262144)
+extern unsigned char* get_prime_segment(void);
+
+#endif
diff --git a/sieve.c b/sieve.c
index 14092ce..e2b3662 100644
--- a/sieve.c
+++ b/sieve.c
@@ -6,60 +6,13 @@
#include "sieve.h"
#include "ptypes.h"
#include "bitarray.h"
-#include "util.h" /* For freeing the segment cache */
-
-
-static unsigned char* prime_cache_sieve = 0;
-static UV prime_cache_size = 0;
-
-/* Get the maximum sieved value of the cached prime sieve. */
-UV get_prime_cache_size(void) { return prime_cache_size; }
-
-/*
- * Get the size and a pointer to the cached prime sieve.
- * Returns the maximum sieved value in the sieve.
- * Allocates and sieves if needed.
- *
- * The sieve holds 30 numbers per byte, using a mod-30 wheel.
- */
-UV get_prime_cache(UV n, const unsigned char** sieve)
-{
- if (prime_cache_size < n) {
-
- if (prime_cache_sieve != 0)
- free(prime_cache_sieve);
- prime_cache_sieve = 0;
- prime_cache_size = 0;
-
- /* Sieve a bit more than asked, to mitigate thrashing */
- if (n >= (UV_MAX-3840))
- n = UV_MAX;
- else
- n = ((n + 3840)/30)*30;
- /* TODO: testing near 2^32-1 */
-
- prime_cache_sieve = sieve_erat30(n);
-
- if (prime_cache_sieve != 0)
- prime_cache_size = n;
- }
-
- if (sieve != 0)
- *sieve = prime_cache_sieve;
- return prime_cache_size;
-}
-
void prime_precalc(UV n)
{
- if ( (n == 0) && (prime_cache_sieve == 0) ) {
+ if (n == 0) {
/* On initialization, make a few primes (2-30k using 1k memory) */
- UV initial_primes_to = 30 * (1024-8);
- prime_cache_sieve = sieve_erat30(initial_primes_to);
- if (prime_cache_sieve != 0)
- prime_cache_size = initial_primes_to;
- return;
+ n = (1024-16)*30;
}
get_prime_cache(n, 0); /* Sieve to n */
@@ -67,23 +20,6 @@ void prime_precalc(UV n)
/* TODO: should we prealloc the segment here? */
}
-void _prime_memfreeall(void)
-{
- if (prime_cache_sieve != 0)
- free(prime_cache_sieve);
- prime_cache_sieve = 0;
- prime_cache_size = 0;
-
- free_prime_segment();
-}
-
-void prime_memfree(void)
-{
- _prime_memfreeall();
-
- prime_precalc(0);
-}
-
UV* sieve_erat(UV end)
@@ -92,7 +28,7 @@ UV* sieve_erat(UV end)
UV n, s;
UV last = (end+1)/2;
- mem = (UV*) calloc( NWORDS(last), sizeof(UV) );
+ Newz(0, mem, NWORDS(last), UV );
if (mem == 0) {
croak("allocation failure in sieve_erat: could not alloc %"UVuf" bits", last);
return 0;
@@ -121,7 +57,7 @@ unsigned char* sieve_erat30(UV end)
max_buf = (end/30) + ((end%30) != 0);
buffer_words = (max_buf + sizeof(UV) - 1) / sizeof(UV);
- mem = (unsigned char*) calloc( buffer_words, sizeof(UV) );
+ Newz(0, mem, buffer_words*sizeof(UV), unsigned char );
if (mem == 0) {
croak("allocation failure in sieve_erat30: could not alloc %"UVuf" bytes", (buffer_words*sizeof(UV)));
return 0;
diff --git a/sieve.h b/sieve.h
index e693b5b..587627f 100644
--- a/sieve.h
+++ b/sieve.h
@@ -4,11 +4,7 @@
#include "EXTERN.h"
#include "perl.h"
-extern UV get_prime_cache_size(void);
-extern UV get_prime_cache(UV n, const unsigned char** sieve);
-
extern void prime_precalc(UV x);
-extern void prime_memfree(void);
extern UV* sieve_erat(UV end);
extern unsigned char* sieve_erat30(UV end);
extern int sieve_segment(unsigned char* mem, UV startd, UV endd);
diff --git a/util.c b/util.c
index 5ef0459..b85fb21 100644
--- a/util.c
+++ b/util.c
@@ -8,28 +8,11 @@
#define INFINITY (DBL_MAX + DBL_MAX)
#endif
+#include "ptypes.h"
#include "util.h"
#include "sieve.h"
#include "factor.h"
-#include "ptypes.h"
-
-/*
- * I'm undecided as to whether we want this, or just let the functions alloc
- * and free it per call.
- */
-static unsigned char* prime_segment = 0;
-unsigned char* get_prime_segment(void) {
- if (prime_segment == 0)
- prime_segment = (unsigned char*) malloc( SEGMENT_CHUNK_SIZE );
- if (prime_segment == 0)
- croak("Could not allocate %"UVuf" bytes for segment sieve", SEGMENT_CHUNK_SIZE);
- return prime_segment;
-}
-void free_prime_segment(void) {
- if (prime_segment != 0)
- free(prime_segment);
- prime_segment = 0;
-}
+#include "cache.h"
static const unsigned char byte_zeros[256] =
{8,7,7,6,7,6,6,5,7,6,6,5,6,5,5,4,7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3,
diff --git a/util.h b/util.h
index b4eca82..a506ec2 100644
--- a/util.h
+++ b/util.h
@@ -23,10 +23,6 @@ extern double ExponentialIntegral(double x);
extern double LogarithmicIntegral(double x);
extern double RiemannR(double x);
-#define SEGMENT_CHUNK_SIZE UVCONST(262144)
-extern unsigned char* get_prime_segment(void);
-extern void free_prime_segment(void);
-
/* Above this value, is_prime will do deterministic Miller-Rabin */
/* With 64-bit math, we can do much faster mulmods from 2^16-2^32 */
#if (BITS_PER_WORD == 64) || HAVE_STD_U64
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list