TMP_ALLOC in C++

Marc Glisse marc.glisse at inria.fr
Thu Dec 18 21:43:25 UTC 2014


Hello,

this patch moves deallocation of temporary memory to a destructor when GMP 
is compiled with a C++ compiler. This may not be the final form of the 
patch, but I am interested in comments. Most of the patch is adjustments 
to tests/mpn so that temporary memory is freed before calling tests_end.

(for the tal-debug.c patch, it may be simpler to change the type of block 
to void* in gmp-impl.h)

-- 
Marc Glisse
-------------- next part --------------
diff --git a/gmp-impl.h b/gmp-impl.h
--- a/gmp-impl.h
+++ b/gmp-impl.h
@@ -5150,16 +5150,53 @@ mpn_toom54_mul_itch (mp_size_t an, mp_si
 #if 0
 #define mpn_fft_mul mpn_mul_fft_full
 #else
 #define mpn_fft_mul mpn_nussbaumer_mul
 #endif
 
 #ifdef __cplusplus
 
+/* Handle C++ exceptions.  */
+#if !WANT_TMP_DEBUG || __cplusplus >= 201103L
+struct gmp_tmp_salloc_t {
+  /* May warn in pedantic mode when TMP_SDECL is empty.  */
+  TMP_SDECL;
+  gmp_tmp_salloc_t(){ TMP_SMARK; }
+  void*salloc(size_t n){ return TMP_SALLOC(n); }
+  ~gmp_tmp_salloc_t(){ TMP_SFREE; }
+};
+struct gmp_tmp_alloc_t {
+  TMP_DECL;
+  gmp_tmp_alloc_t(){ TMP_MARK; }
+  void*salloc(size_t n){ return TMP_SALLOC(n); }
+  void*balloc(size_t n){ return TMP_BALLOC(n); }
+  void*alloc(size_t n){ return TMP_ALLOC(n); }
+  ~gmp_tmp_alloc_t(){ TMP_FREE; }
+};
+#undef TMP_SDECL
+#undef TMP_DECL
+#undef TMP_SMARK
+#undef TMP_MARK
+#undef TMP_SALLOC
+#undef TMP_BALLOC
+#undef TMP_ALLOC
+#undef TMP_SFREE
+#undef TMP_FREE
+#define TMP_SDECL
+#define TMP_DECL
+#define TMP_SMARK	gmp_tmp_salloc_t gmp_tmp_alloc
+#define TMP_MARK	gmp_tmp_alloc_t gmp_tmp_alloc
+#define TMP_SALLOC(n)	gmp_tmp_alloc.salloc(n)
+#define TMP_BALLOC(n)	gmp_tmp_alloc.balloc(n)
+#define TMP_ALLOC(n)	gmp_tmp_alloc.alloc(n)
+#define TMP_SFREE
+#define TMP_FREE
+#endif
+
 /* A little helper for a null-terminated __gmp_allocate_func string.
    The destructor ensures it's freed even if an exception is thrown.
    The len field is needed by the destructor, and can be used by anyone else
    to avoid a second strlen pass over the data.
 
    Since our input is a C string, using strlen is correct.  Perhaps it'd be
    more C++-ish style to use std::char_traits<char>::length, but char_traits
    isn't available in gcc 2.95.4.  */
diff --git a/mpf/get_str.c b/mpf/get_str.c
--- a/mpf/get_str.c
+++ b/mpf/get_str.c
@@ -175,16 +175,17 @@ mpf_get_str (char *dbuf, mp_exp_t *exp, 
   if (un == 0)
     {
       *exp = 0;
       *dbuf = 0;
       n_digits = 0;
       goto done;
     }
 
+  {
   TMP_MARK;
 
   /* Allocate temporary digit space.  We can't put digits directly in the user
      area, since we generate more digits than requested.  (We allocate
      2 * GMP_LIMB_BITS extra bytes because of the digit block nature of the
      conversion.)  */
   tstr = (unsigned char *) TMP_ALLOC (n_digits + 2 * GMP_LIMB_BITS + 3);
 
@@ -312,16 +313,17 @@ mpf_get_str (char *dbuf, mp_exp_t *exp, 
 
   if (SIZ(u) < 0)
     {
       dbuf[0] = '-';
       n_digits++;
     }
 
   TMP_FREE;
+  }
 
  done:
   /* If the string was alloced then resize it down to the actual space
      required.  */
   if (alloc_size != 0)
     {
       __GMP_REALLOCATE_FUNC_MAYBE_TYPE (dbuf, alloc_size, n_digits + 1, char);
     }
diff --git a/tal-debug.c b/tal-debug.c
--- a/tal-debug.c
+++ b/tal-debug.c
@@ -103,17 +103,17 @@ void *
     {
       __gmp_assert_header (file, line);
       fprintf (stderr, "GNU MP: TMP_ALLOC without TMP_MARK(%s)\n", decl_name);
       abort ();
     }
 
   p = __GMP_ALLOCATE_FUNC_TYPE (1, struct tmp_debug_entry_t);
   p->size = size;
-  p->block = (*__gmp_allocate_func) (size);
+  p->block = (char*) (*__gmp_allocate_func) (size);
   p->next = mark->list;
   mark->list = p;
   return p->block;
 }
 
 void
 __gmp_tmp_debug_free (const char *file, int line, int dummy,
                       struct tmp_debug_t **markp,
diff --git a/tests/mpn/logic.c b/tests/mpn/logic.c
--- a/tests/mpn/logic.c
+++ b/tests/mpn/logic.c
@@ -57,78 +57,80 @@ check_one (mp_srcptr refp, mp_srcptr rp,
 int
 main (int argc, char **argv)
 {
   mpz_t a, b;
   mp_ptr ap, bp, rp, refp;
   mp_size_t max_n, n, i;
   gmp_randstate_ptr rands;
   long test, reps = 1000;
-  TMP_DECL;
-  TMP_MARK;
+  {
+    TMP_DECL;
+    TMP_MARK;
 
-  tests_start ();
-  TESTS_REPS (reps, argv, argc);
+    tests_start ();
+    TESTS_REPS (reps, argv, argc);
 
-  mpz_inits (a, b, NULL);
+    mpz_inits (a, b, NULL);
 
-  rands = RANDS;		/* FIXME: not used */
+    rands = RANDS;		/* FIXME: not used */
 
-  max_n = 100;
+    max_n = 100;
 
-  rp = TMP_ALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
-  refp = TMP_ALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
+    rp = TMP_ALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
+    refp = TMP_ALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
 
-  for (test = 0; test < reps; test++)
-    {
-      for (i = 1; i <= max_n; i++)
-	{
-	  mpz_rrandomb (a, rands, i * 8);
-	  mpz_rrandomb (b, rands, i * 8);
-	  mpz_setbit (a, i * 8 - 1);
-	  mpz_setbit (b, i * 8 - 1);
-	  ap = PTR(a);
-	  bp = PTR(b);
-	  n = SIZ(a);
+    for (test = 0; test < reps; test++)
+      {
+	for (i = 1; i <= max_n; i++)
+	  {
+	    mpz_rrandomb (a, rands, i * 8);
+	    mpz_rrandomb (b, rands, i * 8);
+	    mpz_setbit (a, i * 8 - 1);
+	    mpz_setbit (b, i * 8 - 1);
+	    ap = PTR(a);
+	    bp = PTR(b);
+	    n = SIZ(a);
 
-	  refmpn_and_n (refp, ap, bp, n);
-	  mpn_and_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "and_n");
+	    refmpn_and_n (refp, ap, bp, n);
+	    mpn_and_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "and_n");
 
-	  refmpn_ior_n (refp, ap, bp, n);
-	  mpn_ior_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "ior_n");
+	    refmpn_ior_n (refp, ap, bp, n);
+	    mpn_ior_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "ior_n");
 
-	  refmpn_xor_n (refp, ap, bp, n);
-	  mpn_xor_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "xor_n");
+	    refmpn_xor_n (refp, ap, bp, n);
+	    mpn_xor_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "xor_n");
 
-	  refmpn_andn_n (refp, ap, bp, n);
-	  mpn_andn_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "andn_n");
+	    refmpn_andn_n (refp, ap, bp, n);
+	    mpn_andn_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "andn_n");
 
-	  refmpn_iorn_n (refp, ap, bp, n);
-	  mpn_iorn_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "iorn_n");
+	    refmpn_iorn_n (refp, ap, bp, n);
+	    mpn_iorn_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "iorn_n");
 
-	  refmpn_nand_n (refp, ap, bp, n);
-	  mpn_nand_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "nand_n");
+	    refmpn_nand_n (refp, ap, bp, n);
+	    mpn_nand_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "nand_n");
 
-	  refmpn_nior_n (refp, ap, bp, n);
-	  mpn_nior_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "nior_n");
+	    refmpn_nior_n (refp, ap, bp, n);
+	    mpn_nior_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "nior_n");
 
-	  refmpn_xnor_n (refp, ap, bp, n);
-	  mpn_xnor_n (rp, ap, bp, n);
-	  check_one (refp, rp, ap, bp, n, "xnor_n");
+	    refmpn_xnor_n (refp, ap, bp, n);
+	    mpn_xnor_n (rp, ap, bp, n);
+	    check_one (refp, rp, ap, bp, n, "xnor_n");
 
-	  refmpn_com (refp, ap, n);
-	  mpn_com (rp, ap, n);
-	  check_one (refp, rp, ap, bp, n, "com");
-	}
-    }
+	    refmpn_com (refp, ap, n);
+	    mpn_com (rp, ap, n);
+	    check_one (refp, rp, ap, bp, n, "com");
+	  }
+      }
 
-  TMP_FREE;
+    TMP_FREE;
+  }
   mpz_clears (a, b, NULL);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-bdiv.c b/tests/mpn/t-bdiv.c
--- a/tests/mpn/t-bdiv.c
+++ b/tests/mpn/t-bdiv.c
@@ -127,50 +127,36 @@ random_word (gmp_randstate_ptr rs)
 
   MPZ_TMP_INIT (x, 2);
   mpz_urandomb (x, rs, 32);
   r = mpz_get_ui (x);
   TMP_FREE;
   return r;
 }
 
-int
-main (int argc, char **argv)
+void
+check_bdiv (int count)
 {
   gmp_randstate_ptr rands;
   unsigned long maxnbits, maxdbits, nbits, dbits;
   mpz_t n, d, tz;
   mp_size_t maxnn, maxdn, nn, dn, clearn, i;
   mp_ptr np, dp, qp, rp;
   mp_limb_t rh;
   mp_limb_t t;
   mp_limb_t dinv;
-  int count = COUNT;
   mp_ptr scratch;
   mp_limb_t ran;
   mp_size_t alloc, itch;
   mp_limb_t rran0, rran1, qran0, qran1;
   TMP_DECL;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-
   maxdbits = MAX_DN;
   maxnbits = MAX_NN;
 
-  tests_start ();
   rands = RANDS;
 
   mpz_init (n);
   mpz_init (d);
   mpz_init (tz);
 
   maxnn = maxnbits / GMP_NUMB_BITS + 1;
   maxdn = maxdbits / GMP_NUMB_BITS + 1;
@@ -357,12 +343,30 @@ main (int argc, char **argv)
 
   __GMP_FREE_FUNC_LIMBS (scratch, alloc);
 
   TMP_FREE;
 
   mpz_clear (n);
   mpz_clear (d);
   mpz_clear (tz);
+}
 
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_bdiv (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-broot.c b/tests/mpn/t-broot.c
--- a/tests/mpn/t-broot.c
+++ b/tests/mpn/t-broot.c
@@ -22,40 +22,25 @@ the GNU MP Library test suite.  If not, 
 #include "gmp.h"
 #include "gmp-impl.h"
 #include "longlong.h"
 #include "tests/tests.h"
 
 #define MAX_LIMBS 150
 #define COUNT 500
 
-int
-main (int argc, char **argv)
+void
+check_broot (int count)
 {
   gmp_randstate_ptr rands;
 
   mp_ptr ap, rp, pp, scratch;
-  int count = COUNT;
   unsigned i;
   TMP_DECL;
-
   TMP_MARK;
-
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
   rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
   pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
   scratch = TMP_ALLOC_LIMBS (3*MAX_LIMBS); /* For mpn_powlo */
 
   for (i = 0; i < count; i++)
@@ -95,11 +80,30 @@ main (int argc, char **argv)
 	  gmp_fprintf (stderr, "k   = %Mx\n", k);
 	  gmp_fprintf (stderr, "a   = %Nx\n", ap, n);
 	  gmp_fprintf (stderr, "r   = %Nx\n", rp, n);
 	  gmp_fprintf (stderr, "r^n = %Nx\n", pp, n);
 	  abort ();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_broot (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-brootinv.c b/tests/mpn/t-brootinv.c
--- a/tests/mpn/t-brootinv.c
+++ b/tests/mpn/t-brootinv.c
@@ -22,40 +22,27 @@ the GNU MP Library test suite.  If not, 
 #include "gmp.h"
 #include "gmp-impl.h"
 #include "longlong.h"
 #include "tests/tests.h"
 
 #define MAX_LIMBS 150
 #define COUNT 500
 
-int
-main (int argc, char **argv)
+void
+check_brootinv (int count)
 {
   gmp_randstate_ptr rands;
 
   mp_ptr ap, rp, pp, app, scratch;
-  int count = COUNT;
   unsigned i;
   TMP_DECL;
 
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
   rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
   pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
   app = TMP_ALLOC_LIMBS (MAX_LIMBS);
   scratch = TMP_ALLOC_LIMBS (5*MAX_LIMBS);
 
@@ -96,11 +83,30 @@ main (int argc, char **argv)
 	  gmp_fprintf (stderr, "a     = %Nx\n", ap, n);
 	  gmp_fprintf (stderr, "r     = %Nx\n", rp, n);
 	  gmp_fprintf (stderr, "r^n   = %Nx\n", pp, n);
 	  gmp_fprintf (stderr, "a r^n = %Nx\n", app, n);
 	  abort ();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_brootinv (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-div.c b/tests/mpn/t-div.c
--- a/tests/mpn/t-div.c
+++ b/tests/mpn/t-div.c
@@ -117,48 +117,35 @@ check_one (mp_ptr qp, mp_srcptr rp,
 #ifndef SIZE_LOG
 #define SIZE_LOG 17
 #endif
 #define MAX_DN (1L << SIZE_LOG)
 #define MAX_NN (1L << (SIZE_LOG + 1))
 
 #define COUNT 200
 
-int
-main (int argc, char **argv)
+void
+check_div (long count)
 {
   gmp_randstate_ptr rands;
   unsigned long maxnbits, maxdbits, nbits, dbits;
   mpz_t n, d, q, r, tz, junk;
   mp_size_t maxnn, maxdn, nn, dn, clearn, i;
   mp_ptr np, dup, dnp, qp, rp, junkp;
   mp_limb_t t;
   gmp_pi1_t dinv;
-  long count = COUNT;
   mp_ptr scratch;
   mp_limb_t ran;
   mp_size_t alloc, itch;
   mp_limb_t rran0, rran1, qran0, qran1;
   TMP_DECL;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
   maxdbits = MAX_DN;
   maxnbits = MAX_NN;
 
-  tests_start ();
   rands = RANDS;
 
   mpz_init (n);
   mpz_init (d);
   mpz_init (q);
   mpz_init (r);
   mpz_init (tz);
   mpz_init (junk);
@@ -494,12 +481,30 @@ main (int argc, char **argv)
   TMP_FREE;
 
   mpz_clear (n);
   mpz_clear (d);
   mpz_clear (q);
   mpz_clear (r);
   mpz_clear (tz);
   mpz_clear (junk);
+}
 
+int
+main (int argc, char **argv)
+{
+  long count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_div (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-invert.c b/tests/mpn/t-invert.c
--- a/tests/mpn/t-invert.c
+++ b/tests/mpn/t-invert.c
@@ -57,38 +57,25 @@ invert_valid (mp_srcptr ip, mp_srcptr dp
 
   return (cy == -1);
 }
 
 /*
   Check the result of the mpn_invert function in the library.
 */
 
-int
-main (int argc, char **argv)
+void
+check_invert (int count)
 {
   mp_ptr ip, dp, scratch;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   dp = TMP_ALLOC_LIMBS (MAX_N);
   ip = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
   scratch
     = 1+TMP_ALLOC_LIMBS (mpn_invert_itch (MAX_N) + 2);
 
   for (test = 0; test < count; test++)
@@ -151,11 +138,30 @@ main (int argc, char **argv)
 	    }
 	  mpn_dump (dp, n);
 	  mpn_dump (ip, n);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_invert (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-minvert.c b/tests/mpn/t-minvert.c
--- a/tests/mpn/t-minvert.c
+++ b/tests/mpn/t-minvert.c
@@ -48,53 +48,39 @@ mpz_eq_mpn (mp_ptr ap, mp_size_t an, con
 
 static mp_bitcnt_t
 bit_size (mp_srcptr xp, mp_size_t n)
 {
   MPN_NORMALIZE (xp, n);
   return n > 0 ? mpn_sizeinbase (xp, n, 2) : 0;
 }
 
-int
-main (int argc, char **argv)
+void
+check_minvert (int count)
 {
   gmp_randstate_ptr rands;
-  long count = COUNT;
   mp_ptr mp;
   mp_ptr ap;
   mp_ptr vp;
   mp_ptr tp;
   mp_ptr scratch;
   mpz_t m, a, r, g;
   int test;
   mp_limb_t ran;
   mp_size_t itch;
   TMP_DECL;
 
-  tests_start ();
   rands = RANDS;
 
-
   TMP_MARK;
   mpz_init (m);
   mpz_init (a);
   mpz_init (r);
   mpz_init (g);
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
   mp = TMP_ALLOC_LIMBS (MAX_SIZE);
   ap = TMP_ALLOC_LIMBS (MAX_SIZE);
   vp = TMP_ALLOC_LIMBS (MAX_SIZE);
   tp = TMP_ALLOC_LIMBS (MAX_SIZE);
   scratch = TMP_ALLOC_LIMBS (mpn_sec_invert_itch (MAX_SIZE) + 1);
 
   for (test = 0; test < count; test++)
     {
@@ -168,12 +154,30 @@ main (int argc, char **argv)
     }
 
   TMP_FREE;
 
   mpz_clear (m);
   mpz_clear (a);
   mpz_clear (r);
   mpz_clear (g);
+}
 
+int
+main (int argc, char **argv)
+{
+  long count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_minvert (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-mul.c b/tests/mpn/t-mul.c
--- a/tests/mpn/t-mul.c
+++ b/tests/mpn/t-mul.c
@@ -50,52 +50,54 @@ isqrt (unsigned t)
 int
 main (int argc, char **argv)
 {
   mp_ptr ap, bp, rp, refp;
   mp_size_t max_n, an, bn, rn;
   gmp_randstate_ptr rands;
   int reps;
   TMP_DECL;
-  TMP_MARK;
+  {
+    TMP_MARK;
 
-  reps = 1;
+    reps = 1;
 
-  tests_start ();
-  TESTS_REPS (reps, argv, argc);
+    tests_start ();
+    TESTS_REPS (reps, argv, argc);
 
-  rands = RANDS;
+    rands = RANDS;
 
-  /* Re-interpret reps argument as a size argument.  */
-  max_n = isqrt (reps * 25000);
+    /* Re-interpret reps argument as a size argument.  */
+    max_n = isqrt (reps * 25000);
 
-  ap = TMP_ALLOC_LIMBS (max_n + 1);
-  bp = TMP_ALLOC_LIMBS (max_n + 1);
-  rp = TMP_ALLOC_LIMBS (2 * max_n);
-  refp = TMP_ALLOC_LIMBS (2 * max_n);
+    ap = TMP_ALLOC_LIMBS (max_n + 1);
+    bp = TMP_ALLOC_LIMBS (max_n + 1);
+    rp = TMP_ALLOC_LIMBS (2 * max_n);
+    refp = TMP_ALLOC_LIMBS (2 * max_n);
 
-  for (an = 1; an <= max_n; an += 1)
-    {
-      for (bn = 1; bn <= an; bn += 1)
-	{
-	  mpn_random2 (ap, an + 1);
-	  mpn_random2 (bp, bn + 1);
+    for (an = 1; an <= max_n; an += 1)
+      {
+	for (bn = 1; bn <= an; bn += 1)
+	  {
+	    mpn_random2 (ap, an + 1);
+	    mpn_random2 (bp, bn + 1);
 
-	  refmpn_mul (refp, ap, an, bp, bn);
-	  mpn_mul (rp, ap, an, bp, bn);
+	    refmpn_mul (refp, ap, an, bp, bn);
+	    mpn_mul (rp, ap, an, bp, bn);
 
-	  rn = an + bn;
-	  if (mpn_cmp (refp, rp, rn))
-	    {
-	      printf ("ERROR, an = %d, bn = %d, rn = %d\n",
-		      (int) an, (int) bn, (int) rn);
-	      printf ("a: "); mpn_dump (ap, an);
-	      printf ("b: "); mpn_dump (bp, bn);
-	      printf ("r:   "); mpn_dump (rp, rn);
-	      printf ("ref: "); mpn_dump (refp, rn);
-	      abort();
-	    }
-	}
-    }
-  TMP_FREE;
+	    rn = an + bn;
+	    if (mpn_cmp (refp, rp, rn))
+	      {
+		printf ("ERROR, an = %d, bn = %d, rn = %d\n",
+			(int) an, (int) bn, (int) rn);
+		printf ("a: "); mpn_dump (ap, an);
+		printf ("b: "); mpn_dump (bp, bn);
+		printf ("r:   "); mpn_dump (rp, rn);
+		printf ("ref: "); mpn_dump (refp, rn);
+		abort();
+	      }
+	  }
+      }
+    TMP_FREE;
+  }
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-mullo.c b/tests/mpn/t-mullo.c
--- a/tests/mpn/t-mullo.c
+++ b/tests/mpn/t-mullo.c
@@ -32,38 +32,25 @@ the GNU MP Library test suite.  If not, 
 
 #ifndef COUNT
 #define COUNT 10000
 #endif
 
 #define MAX_N (1L << SIZE_LOG)
 #define MIN_N (1)
 
-int
-main (int argc, char **argv)
+void
+check_mullo (int count)
 {
   mp_ptr ap, bp, refp, pp, scratch;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
 #define mpn_mullo_itch(n) (0)
 
   ap = TMP_ALLOC_LIMBS (MAX_N);
   bp = TMP_ALLOC_LIMBS (MAX_N);
   refp = TMP_ALLOC_LIMBS (MAX_N * 2);
   pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
@@ -132,11 +119,30 @@ main (int argc, char **argv)
 	  mpn_dump (bp, n);
 	  mpn_dump (pp, n);
 	  mpn_dump (refp, n);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_mullo (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-mulmid.c b/tests/mpn/t-mulmid.c
--- a/tests/mpn/t-mulmid.c
+++ b/tests/mpn/t-mulmid.c
@@ -31,26 +31,25 @@ the GNU MP Library test suite.  If not, 
 #endif
 
 #ifndef COUNT
 #define COUNT 5000
 #endif
 
 #define MAX_N (1L << SIZE_LOG)
 
-int
-main (int argc, char **argv)
+void
+check_mulmid (void)
 {
   mp_ptr ap, bp, rp, refp;
   gmp_randstate_ptr rands;
   int test;
   TMP_DECL;
   TMP_MARK;
 
-  tests_start ();
   rands = RANDS;
 
   ap = TMP_ALLOC_LIMBS (MAX_N);
   bp = TMP_ALLOC_LIMBS (MAX_N);
   rp = TMP_ALLOC_LIMBS (MAX_N + 2);
   refp = TMP_ALLOC_LIMBS (MAX_N + 2);
 
   for (test = 0; test < COUNT; test++)
@@ -83,11 +82,18 @@ main (int argc, char **argv)
 	  printf("b: "); mpn_dump (bp, bn);
 	  printf("r:   "); mpn_dump (rp, rn);
 	  printf("ref: "); mpn_dump (refp, rn);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  tests_start ();
+  check_mulmid ();
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-mulmod_bnm1.c b/tests/mpn/t-mulmod_bnm1.c
--- a/tests/mpn/t-mulmod_bnm1.c
+++ b/tests/mpn/t-mulmod_bnm1.c
@@ -70,38 +70,25 @@ ref_mulmod_bnm1 (mp_ptr rp, mp_size_t rn
   }
 }
 
 /*
   Compare the result of the mpn_mulmod_bnm1 function in the library
   with the reference function above.
 */
 
-int
-main (int argc, char **argv)
+void
+check_mulmod_bnm1 (int count)
 {
   mp_ptr ap, bp, refp, pp, scratch;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   ASSERT_ALWAYS (mpn_mulmod_bnm1_next_size (MAX_N) == MAX_N);
 
   ap = TMP_ALLOC_LIMBS (MAX_N);
   bp = TMP_ALLOC_LIMBS (MAX_N);
   refp = TMP_ALLOC_LIMBS (MAX_N * 4);
   pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
@@ -208,11 +195,30 @@ main (int argc, char **argv)
 	  mpn_dump (bp, bn);
 	  mpn_dump (pp, rn);
 	  mpn_dump (refp, rn);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_mulmod_bnm1 (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-sizeinbase.c b/tests/mpn/t-sizeinbase.c
--- a/tests/mpn/t-sizeinbase.c
+++ b/tests/mpn/t-sizeinbase.c
@@ -31,39 +31,26 @@ the GNU MP Library test suite.  If not, 
 #endif
 
 #ifndef COUNT
 #define COUNT 30
 #endif
 
 #define MAX_N (1<<SIZE_LOG)
 
-int
-main (int argc, char **argv)
+void
+check_sizeinbase (int count)
 {
   mp_limb_t a;
   mp_ptr pp, scratch;
   mp_limb_t max_b;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   TMP_MARK;
   rands = RANDS;
 
   pp = TMP_ALLOC_LIMBS (MAX_N);
   scratch = TMP_ALLOC_LIMBS (MAX_N);
   max_b = numberof (mp_bases);
 
   ASSERT_ALWAYS (max_b > 62);
@@ -98,11 +85,30 @@ main (int argc, char **argv)
 	  {
 	    printf ("ERROR in -1 test %d, base = %d, exp = %d, res = %d\n",
 		    test, (int) a, (int) exp, (int) res);
 	    abort();
 	  }
       }
 
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_sizeinbase (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/t-sqrmod_bnm1.c b/tests/mpn/t-sqrmod_bnm1.c
--- a/tests/mpn/t-sqrmod_bnm1.c
+++ b/tests/mpn/t-sqrmod_bnm1.c
@@ -66,38 +66,25 @@ ref_sqrmod_bnm1 (mp_ptr rp, mp_size_t rn
   }
 }
 
 /*
   Compare the result of the mpn_sqrmod_bnm1 function in the library
   with the reference function above.
 */
 
-int
-main (int argc, char **argv)
+void
+check_sqrmod_bnm1 (int count)
 {
   mp_ptr ap, refp, pp, scratch;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   ASSERT_ALWAYS (mpn_sqrmod_bnm1_next_size (MAX_N) == MAX_N);
 
   ap = TMP_ALLOC_LIMBS (MAX_N);
   refp = TMP_ALLOC_LIMBS (MAX_N * 4);
   pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
   scratch
@@ -181,11 +168,30 @@ main (int argc, char **argv)
 	  mpn_dump (ap, an);
 	  mpn_dump (pp, rn);
 	  mpn_dump (refp, rn);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
+
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_sqrmod_bnm1 (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/toom-shared.h b/tests/mpn/toom-shared.h
--- a/tests/mpn/toom-shared.h
+++ b/tests/mpn/toom-shared.h
@@ -46,38 +46,25 @@ the GNU MP Library test suite.  If not, 
 
 /* For general toomMN_mul, we need
  *
  * MIN_BN(an) = N + floor(((N-1)*an + M - N)/M)
  *
  * MAX_BN(an) = floor(N*(an-1)/(M-1)) - N + 1
  */
 
-int
-main (int argc, char **argv)
+void
+check_toom (int count)
 {
   mp_ptr ap, bp, refp, pp, scratch;
-  int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
   TMP_MARK;
 
-  if (argc > 1)
-    {
-      char *end;
-      count = strtol (argv[1], &end, 0);
-      if (*end || count <= 0)
-	{
-	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
-	  return 1;
-	}
-    }
-
-  tests_start ();
   rands = RANDS;
 
   ap = TMP_ALLOC_LIMBS (MAX_AN);
   bp = TMP_ALLOC_LIMBS (MAX_BN(MAX_AN));
   refp = TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN));
   pp = 1+TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)+2);
   scratch
     = 1+TMP_ALLOC_LIMBS (mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN))
@@ -147,12 +134,31 @@ main (int argc, char **argv)
 	  mpn_dump (bp, bn);
 	  mpn_dump (pp, an + bn);
 	  mpn_dump (refp, an + bn);
 
 	  abort();
 	}
     }
   TMP_FREE;
+}
 
+int
+main (int argc, char **argv)
+{
+  int count = COUNT;
+
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  check_toom (count);
   tests_end ();
   return 0;
 }
diff --git a/tests/mpn/toom-sqr-shared.h b/tests/mpn/toom-sqr-shared.h
--- a/tests/mpn/toom-sqr-shared.h
+++ b/tests/mpn/toom-sqr-shared.h
@@ -35,33 +35,33 @@ the GNU MP Library test suite.  If not, 
 int
 main (int argc, char **argv)
 {
   mp_ptr ap, refp, pp, scratch;
   int count = COUNT;
   int test;
   gmp_randstate_ptr rands;
   TMP_DECL;
-  TMP_MARK;
 
   if (argc > 1)
     {
       char *end;
       count = strtol (argv[1], &end, 0);
       if (*end || count <= 0)
 	{
 	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
 	  return 1;
 	}
     }
 
   tests_start ();
 
   if (MAX_AN > MIN_AN) {
     rands = RANDS;
+    TMP_MARK;
 
     ap = TMP_ALLOC_LIMBS (MAX_AN);
     refp = TMP_ALLOC_LIMBS (MAX_AN * 2);
     pp = 1 + TMP_ALLOC_LIMBS (MAX_AN * 2 + 2);
     scratch
       = 1+TMP_ALLOC_LIMBS (mpn_toomN_sqr_itch (MAX_AN) + 2);
 
     for (test = 0; test < count; test++)


More information about the gmp-devel mailing list