Bill Allombert on Sun, 16 Apr 2017 15:33:41 +0200


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

Re: libpari: threads and argument passing


On Sun, Apr 16, 2017 at 03:01:38PM +0200, Jan Jancar wrote:
> Hello PARI developers,
> looking at the "PARI and threads" part of the libpari

Hello Jan,
Thanks for for reviewing the documentation!

> manual suggests that the only way to pass an argument
> to a PARI thread is if it is a GEN.

I assume you speak of pari_thread_alloc/pari_thread_start ?

> However it could be quite useful to be able to pass an
> arbitrary void* as the pthread API allows. A void* is
> guaranteed to be able to hold a pointer to any type, 
> so passing a GEN is still possible, while a long* 
> (what a GEN really is) is not guaranteed to be able to
> hold a pointer to any type. This generally makes passing
> a pointer to a custom structure and casting it to a GEN
> risky business on architectures where it doesn't fit
> (are there any?).

Maybe I am wrong but as I understand it, the C standard only
differentiate pointers to data and pointers to functions.
So as far as I am concerned, you are welcome to cast your void*
to a GEN and pass it to pari_thread_alloc.

> Is there some reason I'm not seeing as to why the
> argument is restricted to a GEN type?

I did it that way because it saves a lot of casts in the common case when
the argument is a GEN.
But actually, the API does not require pthread_create() to be called with
the output of pari_thread_alloc().
You can create a struct:
struct my_pari_thread
{
  struct pari_thread pth;
  void * args; /* Or whatever */
} my_pth;

pari_thread_alloc(&my_pth.pth,4000000,NULL);
pthread_create(&th,NULL,&myfun,(void*)&my_pth);

and then do

void *
myfun(void *arg)
{
  GEN F, M;
  struct my_pari_thread *marg = (struct my_pari_thread) arg; 
  /* Set up thread stack and get thread parameter */
  (void) pari_thread_start(&marg.pth);
  ... do something with marg.args ...
}

Cheers,
Bill.