[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