Bill Allombert on Sun, 27 Nov 2005 00:26:24 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: pari_init, RE-INIT, and programs using libpari.


On Sat, Nov 26, 2005 at 12:21:05PM -0800, Ilya Zakharevich wrote:
> On Sat, Nov 26, 2005 at 06:47:37PM +0100, Bill Allombert wrote:
> > > BTW, I attach my attempt to make GP/PARI 2.1.7 restartable (this is a
> > > part of Math::Pari now; grep for reset_on_reload in Pari.xs); I still
> > > get segfaults at some moment if I try to reset...
> > 
> > Do you have a test case ?
> 
> Only for Math::Pari:
> 
>   perl -le 'for (1..shift) {delete $INC{q(Math/Pari.pm)};
> 			    require Math::Pari;
> 			    Math::Pari::reset_on_reload(1);
> 			    print sin Math::Pari::PARI(1)}'      3
> 

Ah thanks!

Here two patch for the CVS version:
the first is a better version of the pari_init_opts patch,
the second adds a function pari_close_opts and should fix
this bug at least for

#include <pari/pari.h>
int
main(void)
{
  long i;
  for (i=0;i<10;i++)
  {
    pari_init(400000,500000);
    pariputsf("%Z\n",gsin(gen_1,4));
    pari_close();
  }
  return 0;
}

The first patch might break gp start-up code since it defers
initialisations of default to the call to pari_init which happens
a bit late in gp.c:main(), but it seems to be fine.

Cheers,
Bill.
Index: pari/src/gp/gp.c
===================================================================
--- pari.orig/src/gp/gp.c	2005-11-26 22:37:41.000000000 +0100
+++ pari/src/gp/gp.c	2005-11-27 00:07:12.000000000 +0100
@@ -812,7 +812,7 @@
 {
   free_graph(); freeall();
   kill_all_buffers(NULL);
-  if (INIT_SIG) pari_sig_init(SIG_DFL);
+  pari_sig_init(SIG_DFL);
   term_color(c_NONE);
   pariputs_opt("Goodbye!\n");
   if (GP_DATA->flags & TEXMACS) tm_end_output();
@@ -1825,7 +1825,9 @@
   growarray A;
   long i;
 
-  init_defaults(1);
+  GP_DATA = default_gp_data();
+  initout(1);
+
   for (i=0; i<c_LAST; i++) gp_colors[i] = c_NONE;
   bot = (pari_sp)0;
   top = (pari_sp)(1000000*sizeof(long));
@@ -1845,9 +1847,7 @@
   pari_addfunctions(&pari_oldmodules, functions_oldgp,helpmessages_oldgp);
 
   init_graph();
-  INIT_SIG_off;
-  pari_init(top-bot, GP_DATA->primelimit);
-  INIT_SIG_on;
+  pari_init_opts(top-bot, GP_DATA->primelimit, 0);
   pari_sig_init(gp_sighandler);
 #ifdef READLINE
   init_readline();
Index: pari/src/headers/paricom.h
===================================================================
--- pari.orig/src/headers/paricom.h	2005-11-26 22:37:41.000000000 +0100
+++ pari/src/headers/paricom.h	2005-11-27 00:07:38.000000000 +0100
@@ -422,3 +422,13 @@
   { while (*(d) == DIFFPTR_SKIP) (p) += *(d)++; (p) += *(d)++; } STMT_END
 #define NEXT_PRIME_VIADIFF_CHECK(p,d)  STMT_START \
   { if (!*(d)) err(primer1); NEXT_PRIME_VIADIFF(p,d); } STMT_END
+
+/* For use with pari_init_opts */
+
+#define INIT_JMPm 1
+#define INIT_SIGm 2
+#define INIT_DFTm 4
+#define INIT_JMP     (init_opts & INIT_JMPm)
+#define INIT_SIG     (init_opts & INIT_SIGm)
+#define INIT_DFT     (init_opts & INIT_DFTm)
+
Index: pari/src/headers/paridecl.h
===================================================================
--- pari.orig/src/headers/paridecl.h	2005-11-26 22:37:41.000000000 +0100
+++ pari/src/headers/paridecl.h	2005-11-27 00:07:12.000000000 +0100
@@ -1243,6 +1243,7 @@
 void    msgtimer(char *format, ...);
 GEN     newbloc(long n);
 void    pari_err(long numerr, ...);
+void    pari_init_opts(size_t parisize, ulong maxprime, ulong init_opts);
 void    pari_init(size_t parisize, ulong maxprime);
 void    pari_sig_init(void (*f)(int));
 GEN     reorder(GEN x);
Index: pari/src/language/anal.h
===================================================================
--- pari.orig/src/language/anal.h	2005-11-26 22:37:41.000000000 +0100
+++ pari/src/language/anal.h	2005-11-26 22:39:31.000000000 +0100
@@ -135,17 +135,6 @@
 #define EpPREDEFINED(ep) (EpVALENCE(ep) < EpUSER)
 enum { EpUSER = 100, EpNEW, EpALIAS, EpVAR, EpGVAR, EpMEMBER, EpINSTALL };
 
-/* signals */
-extern ulong init_opts;
-#define INIT_JMPm 1
-#define INIT_SIGm 2
-#define INIT_JMP     (init_opts & INIT_JMPm)
-#define INIT_SIG     (init_opts & INIT_SIGm)
-#define INIT_JMP_on  (init_opts |= INIT_JMPm)
-#define INIT_SIG_on  (init_opts |= INIT_SIGm)
-#define INIT_JMP_off (init_opts &= ~INIT_JMPm)
-#define INIT_SIG_off (init_opts &= ~INIT_SIGm)
-
 /* defaults  */
 char* get_sep(const char *t);
 long get_int(const char *s, long dflt);
Index: pari/src/language/init.c
===================================================================
--- pari.orig/src/language/init.c	2005-11-26 22:39:26.000000000 +0100
+++ pari/src/language/init.c	2005-11-27 00:07:12.000000000 +0100
@@ -47,7 +47,6 @@
 long    *ordvar;
 ulong   DEBUGFILES, DEBUGLEVEL, DEBUGMEM, compatible;
 ulong   precreal, precdl;
-ulong   init_opts = INIT_JMPm | INIT_SIGm;
 pari_sp bot = 0, top = 0, avma;
 size_t memused;
 
@@ -406,15 +405,10 @@
   }
 }
 
-void
-init_defaults(int force)
+static void
+init_defaults(void)
 {
-  static int done=0;
-
-  if (done && !force) return;
-  done = 1;
 
-  GP_DATA = default_gp_data();
 #ifdef LONG_IS_64BIT
   precreal = 4;
 #else
@@ -638,12 +632,14 @@
 /* initialize PARI data. You can call pari_addfunctions() first to add other
  * routines to the default set */
 void
-pari_init(size_t parisize, ulong maxprime)
+pari_init_opts(size_t parisize, ulong maxprime, ulong init_opts)
 {
   ulong u;
 
   STACK_CHECK_INIT(&u);
-  init_defaults(0);
+  if (INIT_DFT)
+    GP_DATA = default_gp_data();
+  init_defaults();
   if (INIT_JMP && setjmp(GP_DATA->env))
   {
     fprintferr("  ***   Error in the PARI system. End of program.\n");
@@ -689,6 +685,12 @@
   try_to_recover = 1;
 }
 
+void
+pari_init(size_t parisize, ulong maxprime)
+{
+  pari_init_opts(parisize, maxprime, INIT_JMPm | INIT_SIGm | INIT_DFTm);
+}
+
 static void
 delete_hist(gp_hist *h)
 {
Index: pari/src/headers/paripriv.h
===================================================================
--- pari.orig/src/headers/paripriv.h	2005-11-26 22:39:26.000000000 +0100
+++ pari/src/headers/paripriv.h	2005-11-26 22:40:03.000000000 +0100
@@ -298,7 +298,6 @@
 GEN   geni(void);
 void* get_stack(double fraction, long min);
 GEN   gpreadseq(char *c, int strict);
-void  init_defaults(int force);
 void  initout(int initerr);
 void  init80col(long n);
 char* itostr(GEN x, int minus);
Index: pari/src/gp/gp.c
===================================================================
--- pari.orig/src/gp/gp.c	2005-11-26 23:19:38.000000000 +0100
+++ pari/src/gp/gp.c	2005-11-26 23:24:54.000000000 +0100
@@ -810,9 +810,9 @@
 void
 gp_quit(void)
 {
-  free_graph(); freeall();
+  free_graph();
+  pari_close();
   kill_all_buffers(NULL);
-  pari_sig_init(SIG_DFL);
   term_color(c_NONE);
   pariputs_opt("Goodbye!\n");
   if (GP_DATA->flags & TEXMACS) tm_end_output();
@@ -1842,13 +1842,15 @@
 #endif
   grow_init(&A);
   read_opt(&A, argc,argv);
+
+  pari_init_opts(top-bot, GP_DATA->primelimit, 0);
+  pari_sig_init(gp_sighandler);
+
   pari_addfunctions(&pari_modules, functions_gp,helpmessages_gp);
   pari_addfunctions(&pari_modules, functions_highlevel,helpmessages_highlevel);
   pari_addfunctions(&pari_oldmodules, functions_oldgp,helpmessages_oldgp);
 
   init_graph();
-  pari_init_opts(top-bot, GP_DATA->primelimit, 0);
-  pari_sig_init(gp_sighandler);
 #ifdef READLINE
   init_readline();
 #endif
Index: pari/src/graph/plotQt.c
===================================================================
--- pari.orig/src/graph/plotQt.c	2005-11-26 23:19:38.000000000 +0100
+++ pari/src/graph/plotQt.c	2005-11-26 23:24:54.000000000 +0100
@@ -573,9 +573,7 @@
 {
     if (fork()) return;  // parent process returns
 
-    pari_sig_init(SIG_IGN); /* disable interrupt handler */
-
-    freeall();  // PARI stack isn't needed anymore, keep rectgraph
+    pari_close();
     PARI_get_plot(1);
 
     // launch Qt window
Index: pari/src/graph/plotX.c
===================================================================
--- pari.orig/src/graph/plotX.c	2005-11-26 23:19:38.000000000 +0100
+++ pari/src/graph/plotX.c	2005-11-26 23:24:54.000000000 +0100
@@ -177,10 +177,9 @@
 
   if (fork()) return;  /* parent process returns */
 
-  pari_sig_init(SIG_IGN); /* disable interrupt handler */
-
-  freeall();  /* PARI stack isn't needed anymore, keep rectgraph */
+  pari_close();
   PARI_get_plot(1);
+
   display = XOpenDisplay(NULL);
   font_info = XLoadQueryFont(display, "9x15");
   if (!font_info) exiterr("cannot open 9x15 font");
Index: pari/src/graph/plotfltk.c
===================================================================
--- pari.orig/src/graph/plotfltk.c	2005-11-26 23:19:38.000000000 +0100
+++ pari/src/graph/plotfltk.c	2005-11-26 23:24:54.000000000 +0100
@@ -182,9 +182,7 @@
     Plotter *win;
     if (fork()) return;  // parent process returns
 
-    pari_sig_init(SIG_IGN); /* disable interrupt handler */
-
-    freeall();  // PARI stack isn't needed anymore, keep rectgraph
+    pari_close();
     PARI_get_plot(1);
 
     Fl::visual(FL_DOUBLE|FL_INDEX);
Index: pari/src/headers/paridecl.h
===================================================================
--- pari.orig/src/headers/paridecl.h	2005-11-26 23:19:38.000000000 +0100
+++ pari/src/headers/paridecl.h	2005-11-26 23:24:54.000000000 +0100
@@ -1219,7 +1219,6 @@
 void*   err_catch(long errnum, jmp_buf *penv);
 void    err_leave(void **v);
 GEN     forcecopy(GEN x);
-void    freeall(void);
 GEN     gclone(GEN x);
 GEN     gcopy(GEN x);
 GEN     gcopy_i(GEN x, long lx);
@@ -1243,6 +1242,8 @@
 void    msgtimer(char *format, ...);
 GEN     newbloc(long n);
 void    pari_err(long numerr, ...);
+void    pari_close(void);
+void    pari_close_opts(ulong init_opts);
 void    pari_init_opts(size_t parisize, ulong maxprime, ulong init_opts);
 void    pari_init(size_t parisize, ulong maxprime);
 void    pari_sig_init(void (*f)(int));
Index: pari/src/language/init.c
===================================================================
--- pari.orig/src/language/init.c	2005-11-26 23:19:59.000000000 +0100
+++ pari/src/language/init.c	2005-11-27 00:04:22.000000000 +0100
@@ -31,15 +31,15 @@
 const long functions_tblsz = 135; /* size of functions_hash          */
 /*      Variables statiques communes :         */
 FILE    *pari_outfile, *errfile, *logfile, *infile;
-ulong   logstyle = logstyle_none;
+ulong   logstyle;
 GEN     *pol_1, *pol_x;
 GEN     gnil, gen_0, gen_1, gen_m1, gen_2, ghalf, polvar, gi;
-GEN     gpi=NULL, geuler=NULL, bernzone=NULL;
+GEN     gpi, geuler, bernzone;
 GEN     primetab; /* private primetable */
 byteptr diffptr;
-char    *current_logfile, *current_psfile, *pari_datadir = NULL;
+char    *current_logfile, *current_psfile, *pari_datadir;
 long    gp_colors[c_LAST];
-int     disable_color = 1;
+int     disable_color;
 
 entree  **varentries;
 
@@ -47,10 +47,10 @@
 long    *ordvar;
 ulong   DEBUGFILES, DEBUGLEVEL, DEBUGMEM, compatible;
 ulong   precreal, precdl;
-pari_sp bot = 0, top = 0, avma;
+pari_sp bot, top, avma;
 size_t memused;
 
-gp_data *GP_DATA = NULL;
+gp_data *GP_DATA;
 
 void *foreignHandler; 	              /* Handler for foreign commands.   */
 char foreignExprSwitch = 3; 	      /* Just some unprobable char.      */
@@ -67,7 +67,7 @@
   long flag;
 } cell;
 
-static stack *err_catch_stack = NULL;
+static stack *err_catch_stack;
 static char **dft_handler;
 
 void
@@ -418,6 +418,8 @@
   precdl = 16;
   compatible = NONE;
   DEBUGFILES = DEBUGLEVEL = DEBUGMEM = 0;
+  disable_color = 1;
+  logstyle = logstyle_none;
 
   current_psfile = pari_strdup("pari.ps");
   current_logfile= pari_strdup("pari.log");
@@ -492,12 +494,12 @@
   return (hash == functions_hash);
 }
 
-module *pari_modules    = NULL;
-module *pari_oldmodules = NULL;
-module *pari_membermodules = NULL;
-entree **functions_hash = NULL;
-entree **funct_old_hash = NULL;
-entree **members_hash   = NULL;
+module *pari_modules;
+module *pari_oldmodules;
+module *pari_membermodules;
+entree **functions_hash;
+entree **funct_old_hash;
+entree **members_hash;
 
 /* add to modlist the functions in func, with helpmsg help */
 void
@@ -640,12 +642,14 @@
   if (INIT_DFT)
     GP_DATA = default_gp_data();
   init_defaults();
+  err_catch_stack=NULL;
   if (INIT_JMP && setjmp(GP_DATA->env))
   {
     fprintferr("  ***   Error in the PARI system. End of program.\n");
     exit(1);
   }
   if (INIT_SIG) pari_sig_init(pari_sighandler);
+  bot = top = 0;
   (void)init_stack(parisize);
   diffptr = initprimes(maxprime);
   init_universal_constants();
@@ -657,11 +661,15 @@
   pol_x  = (GEN*) gpmalloc((MAXVARN+1)*sizeof(GEN));
   pol_1 = (GEN*) gpmalloc((MAXVARN+1)*sizeof(GEN));
   polvar[0] = evaltyp(t_VEC) | evallg(1);
+  gpi=NULL; geuler=NULL; bernzone=NULL;
   for (u=0; u <= MAXVARN; u++) { ordvar[u] = u; varentries[u] = NULL; }
 
   (void)fetch_var(); /* create pol_x/pol_1[MAXVARN] */
   primetab = (GEN) gpmalloc(1 * sizeof(long));
   primetab[0] = evaltyp(t_VEC) | evallg(1);
+  pari_modules    = NULL;
+  pari_oldmodules = NULL;
+  pari_membermodules = NULL;
 
   pari_addfunctions(&pari_modules, functions_basic,helpmessages_basic);
   pari_addfunctions(&pari_oldmodules, oldfonctions,oldhelpmessage);
@@ -718,11 +726,13 @@
 }
 
 void
-freeall(void)
+pari_close_opts(ulong init_opts)
 {
   long i;
   entree *ep,*ep1;
 
+  if (INIT_SIG) pari_sig_init(SIG_DFL);
+
   while (delete_var()) /* empty */;
   for (i = 0; i < functions_tblsz; i++)
   {
@@ -749,7 +759,13 @@
   free(current_logfile);
   free(current_psfile);
   if (pari_datadir) free(pari_datadir);
-  free_gp_data(GP_DATA);
+  if (INIT_DFT) free_gp_data(GP_DATA);
+}
+
+void
+pari_close(void)
+{
+  pari_close_opts(INIT_JMPm | INIT_SIGm | INIT_DFTm);
 }
 
 GEN