[Gmp-commit] /var/hg/gmp-proj/mini-gmp: 3 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Sat Jan 28 16:39:20 CET 2012


details:   /var/hg/gmp-proj/mini-gmp/rev/c5580a14043b
changeset: 87:c5580a14043b
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 28 16:33:29 2012 +0100
description:
Implemented mp_set_memory_functions and mp_get_memory_functions.

details:   /var/hg/gmp-proj/mini-gmp/rev/4855e2c94996
changeset: 88:4855e2c94996
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 28 16:35:53 2012 +0100
description:
Mention deviations from GMP compatibility.

details:   /var/hg/gmp-proj/mini-gmp/rev/687f1f77a2c2
changeset: 89:687f1f77a2c2
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 28 16:38:26 2012 +0100
description:
More consistent messages for gmp_die.

diffstat:

 README     |   16 +++++++-
 mini-gmp.c |  105 +++++++++++++++++++++++++++++++++++++++++++++---------------
 mini-gmp.h |    8 ++++
 3 files changed, 100 insertions(+), 29 deletions(-)

diffs (290 lines):

diff -r cd34986b819d -r 687f1f77a2c2 README
--- a/README	Sun Jan 15 23:06:30 2012 +0100
+++ b/README	Sat Jan 28 16:38:26 2012 +0100
@@ -9,8 +9,18 @@
 mini-gmp as a fallback when for some reason GMP is not available, or
 not desired as a dependency.
 
-The supported GMP subset is declared in mini-gmp.h. The implementation
-is a single file, mini-gmp.c.
+The supported GMP subset is declared in mini-gmp.h. The implemented
+functions are fully compatible with the corresponding GMP functions,
+as specified in the GMP manual, with a few exceptions:
+
+  mpz_export and mpz_import support only NAILS = 0.
+
+  The REALLOC_FUNC and FREE_FUNC registered with
+  mp_set_memory_functions does not get the correct size of the
+  allocated block in the corresponding argument. mini-gmp always
+  passes zero for these rarely used arguments.
+
+The implementation is a single file, mini-gmp.c.
 
 The performance target for mini-gmp is to be at most 10 times slower
 than the real GMP library, for numbers of size up to a few hundred
@@ -26,7 +36,7 @@
 
 The tests subdirectory contains a testsuite. To use it, you need GMP
 and GNU make. Just run make check in the tests directory. If the
-hardcoded compiler settings are not right, you have to either edit the
+hard-coded compiler settings are not right, you have to either edit the
 Makefile or pass overriding values on the make command line (e.g.,
 make CC=cc check). Testing is not (yet) as thorough as for the real
 GMP.
diff -r cd34986b819d -r 687f1f77a2c2 mini-gmp.c
--- a/mini-gmp.c	Sun Jan 15 23:06:30 2012 +0100
+++ b/mini-gmp.c	Sat Jan 28 16:38:26 2012 +0100
@@ -227,7 +227,7 @@
   } while (0)
 
 
-/* Helper functions. */
+/* Memory allocation and other helper functions. */
 static void
 gmp_die (const char *msg)
 {
@@ -236,7 +236,7 @@
 }
 
 static void *
-gmp_xalloc (size_t size)
+gmp_default_alloc (size_t size)
 {
   void *p;
 
@@ -244,11 +244,72 @@
 
   p = malloc (size);
   if (!p)
-    gmp_die("virtual memory exhausted.");
+    gmp_die("gmp_default_alloc: Virtual memory exhausted.");
 
   return p;
 }
 
+static void *
+gmp_default_realloc (void *old, size_t old_size, size_t new_size)
+{
+  mp_ptr p;
+
+  p = realloc (old, new_size);
+
+  if (!p)
+    gmp_die("gmp_default_realoc: Virtual memory exhausted.");
+
+  return p;
+}
+
+static void
+gmp_default_free (void *p, size_t size)
+{
+  free (p);
+}
+
+static void * (*gmp_allocate_func) (size_t)
+= gmp_default_alloc;
+static void * (*gmp_reallocate_func) (void *, size_t, size_t)
+= gmp_default_realloc;
+static void (*gmp_free_func) (void *, size_t)
+= gmp_default_free;
+
+void
+mp_get_memory_functions (void *(**alloc_func) (size_t),
+			 void *(**realloc_func) (void *, size_t, size_t),
+			 void (**free_func) (void *, size_t))
+{
+  if (alloc_func)
+    *alloc_func = gmp_allocate_func;
+
+  if (realloc_func)
+    *realloc_func = gmp_reallocate_func;
+
+  if (free_func)
+    *free_func = gmp_free_func;
+}
+
+void
+mp_set_memory_functions (void *(*alloc_func) (size_t),
+			 void *(*realloc_func) (void *, size_t, size_t),
+			 void (*free_func) (void *, size_t))
+{
+  if (!alloc_func)
+    alloc_func = gmp_default_alloc;
+  if (!realloc_func)
+    realloc_func = gmp_default_realloc;
+  if (!free_func)
+    free_func = gmp_default_free;
+
+  gmp_allocate_func = alloc_func;
+  gmp_reallocate_func = realloc_func;
+  gmp_free_func = free_func;
+}
+
+#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
+#define gmp_free(p) ((*gmp_free_func) ((p), 0))
+
 static mp_ptr
 gmp_xalloc_limbs (mp_size_t size)
 {
@@ -258,16 +319,8 @@
 static mp_ptr
 gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
 {
-  mp_ptr p;
-
   assert (size > 0);
-
-  p = realloc (old, size * sizeof(mp_limb_t));
-
-  if (!p)
-    gmp_die("virtual memory exhausted.");
-
-  return p;
+  return (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t));
 }
 
 
@@ -774,7 +827,7 @@
 	qp[nn] = q;
     }
   if (inv->shift > 0)
-    free (tp);
+    gmp_free (tp);
 
   return r >> inv->shift;
 }
@@ -845,7 +898,7 @@
       r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift));
       r1 >>= shift;
 
-      free (tp);
+      gmp_free (tp);
     }
 
   rp[1] = r1;
@@ -884,7 +937,7 @@
   d1 = dp[dn - 1];
   d0 = dp[dn - 2];
 
-  /* Iteration variable is the index if of the q limb.
+  /* Iteration variable is the index of the q limb.
    *
    * We divide <n1, np[dn-1+i], np[dn-2+i], np[dn-3+i],..., np[i]>
    * by            <d1,          d0,        dp[dn-3],  ..., dp[0] >
@@ -979,7 +1032,7 @@
     }
   mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
   if (tp)
-    free (tp);
+    gmp_free (tp);
 }
 
 
@@ -1266,7 +1319,7 @@
 void
 mpz_clear (mpz_t r)
 {
-  free (r->_mp_d);
+  gmp_free (r->_mp_d);
 }
 
 static void *
@@ -1996,7 +2049,7 @@
   ds = d->_mp_size;
 
   if (ds == 0)
-    gmp_die("Divide by zero.");
+    gmp_die("mpz_div_qr: Divide by zero.");
 
   if (ns == 0)
     {
@@ -3047,7 +3100,7 @@
       tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
     }
   if (tp)
-    free (tp);
+    gmp_free (tp);
 
   mpz_swap (r, tr);
   mpz_clear (tr);
@@ -3652,7 +3705,7 @@
       mpn_div_qr_1_preinv (tp, tp, un, &bi);
       un -= (tp[un-1] == 0);
     }
-  free (tp);
+  gmp_free (tp);
   return ndigits;
 }
 
@@ -3711,7 +3764,7 @@
       mpn_copyi (tp, u->_mp_d, un);
 
       sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
-      free (tp);
+      gmp_free (tp);
     }
 
   for (; i < sn; i++)
@@ -3788,7 +3841,7 @@
       else
 	{
 	fail:
-	  free (dp);
+	  gmp_free (dp);
 	  r->_mp_size = 0;
 	  return -1;
 	}
@@ -3816,7 +3869,7 @@
       rn = mpn_set_str_other (rp, dp, dn, base, &info);
     }
   assert (rn <= alloc);
-  free (dp);
+  gmp_free (dp);
 
   r->_mp_size = sign ? - rn : rn;
 
@@ -3832,7 +3885,7 @@
   str = mpz_get_str (NULL, base, x);
   len = strlen (str);
   len = fwrite (str, 1, len, stream);
-  free (str);
+  gmp_free (str);
   return len;
 }
 
@@ -3869,7 +3922,7 @@
   mp_size_t i;
 
   if (nails != 0)
-    gmp_die ("mpz_import: nails not supported.\n");
+    gmp_die ("mpz_import: Nails not supported.");
 
   assert (order == 1 || order == -1);
   assert (endian >= -1 && endian <= 1);
@@ -3933,7 +3986,7 @@
   mp_size_t i;
 
   if (nails != 0)
-    gmp_die ("mpz_import: nails not supported.\n");
+    gmp_die ("mpz_import: Nails not supported.");
 
   assert (order == 1 || order == -1);
   assert (endian >= -1 && endian <= 1);
diff -r cd34986b819d -r 687f1f77a2c2 mini-gmp.h
--- a/mini-gmp.h	Sun Jan 15 23:06:30 2012 +0100
+++ b/mini-gmp.h	Sat Jan 28 16:38:26 2012 +0100
@@ -34,6 +34,14 @@
 extern "C" {
 #endif
 
+void mp_set_memory_functions (void *(*) (size_t),
+			      void *(*) (void *, size_t, size_t),
+			      void (*) (void *, size_t));
+
+void mp_get_memory_functions (void *(**) (size_t),
+			      void *(**) (void *, size_t, size_t),
+			      void (**) (void *, size_t));
+
 typedef unsigned long mp_limb_t;
 typedef long mp_size_t;
 typedef unsigned long mp_bitcnt_t;


More information about the gmp-commit mailing list