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