Bill Allombert on Sun, 17 Sep 2006 20:35:00 +0200


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

Re: PARI_stack_limit


On Sat, Sep 16, 2006 at 05:05:17PM +0200, Bernard Parisse wrote:
> 
> >Could you write a stand-alone test case ? It would help.
> >
> 
> That would be too long, it's faster that you compile giac with -g

I doubt that...

Please find a test case in attachement.

It fails with
%./thread

  ***   deep recursion: factor(2^128+1)
                        ^---------------
  ***   Error in the PARI system. End of program.

If you uncomment the call to pari_init_stackcheck(), it works fine.

So I would propose we:

1) make stack-checking optional through a init_opts options.
2) make pari_init_stackcheck public and document it.

At this point the question is whether pari_thread_init should call
pari_init_stackcheck itself

Cheers,
Bill.
PS:
flisexpr() was renamed to gp_read_str() in PARI/GP 2.3
#include <pari/pari.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

extern void *PARI_stack_limit;

/* extracted from PARI */
void
pari_init_stackcheck(void *stack_base)
{
  struct rlimit rip;
  ulong size;

  if (getrlimit(RLIMIT_STACK, &rip)) return;
  size = rip.rlim_cur;
  if (size == (ulong)RLIM_INFINITY || size > (ulong)stack_base)
    PARI_stack_limit = (void*)(((ulong)stack_base) / 16);
  else
    PARI_stack_limit = (void*)((ulong)stack_base - (size/16)*15);
}

GEN pari_exec(void *v)
{
    ulong l;
    long av=avma;
    char **s=v;
    GEN gres;
//    pari_init_stackcheck(&l);
    gres=gp_read_str(*s);
    gres=gclone(gres);
    avma=av;
    return gres;
}

GEN thread_eval(char *v)
{
  void * ptr;
  pthread_t eval_thread;
  pthread_create (&eval_thread, NULL, (void *(*)(void*)) pari_exec,(void *)&v);
  pthread_join(eval_thread,&ptr);
  return ptr;
}

int main(void)
{
  pari_init(4000000,500000);
  output(thread_eval("factor(2^128+1)"));
  output(thread_eval("factor(2^193-1)"));
  output(thread_eval("bnfinit(x^4+21).clgp"));
  return 0;
}