Bill Allombert on Sat, 17 Jun 2006 20:40:32 +0200


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

Re: PARI and POSIX threads


Hello PARI-dev,

I have commited a patch that add a new _experimental_ Configure option
--enable-tls that implement thread-local PARI stack.

This option:
1) Break the libpari ABI (the resulting library will not be compatible
with the old one.
2) Only work on system that implement the __thread storage class 
3) add 2 public functions pari_thread_init() and pari_thread_close()
that should be called when starting (resp. closing) a thread 
and allocate/deallocate the local stack and local cached universal
constants. The functions are provided even if --enable-tls is not set
but do not do anyting interesting.

Here an commented example of multi-threaded PARI program:

#include <pari/pari.h> // Include PARI headers
#include <pthread.h>   // Include POSIX threads headers

void * mydet(void * arg)
{
  GEN M=(GEN)arg;
  GEN F;
  pari_thread_init(8000000); // Initialize a local PARI stack for this
                             // thread of 8000000 bytes.
  F=gclone(det(M));          // compute the determinant using the local
                             // stack
                             // clone the result so we can free the
                             // stack
  pari_thread_close();       // Free the PARI stack
  pthread_exit((void *)F);   // End the thread and return F.
  return F;                  // spurious
}

void * myfactor(void * arg)  //exactly the same as above.
{
  GEN N=(GEN)arg;
  GEN F;
  pari_thread_init(4000000);
  F=gclone(factor(N));
  pari_thread_close();
  pthread_exit((void *)F);
  return F;
}

int main(void)
{
  GEN M,N1,N2, F1,F2,D;
  pthread_t th1, th2, th3;           // Allocate POSIX-thread variables.
  pari_init(4000000,500000);         //Initialise the main PARI stack
                                     //and global objects (gen_0, etc.)
  N1=addis(gpowgs(gen_2,256),1);     //do computation in the main PARI
                                     //stack
  N2=subis(gpowgs(gen_2,193),1);
  M=mathilbert(80);
  // The functions pthread_create and pthread_create are standard 
  // POSIX-thread functions to start and get the result of threads.
  pthread_create(&th1,NULL,&myfactor,(void*)N1);//Start threads
  pthread_create(&th2,NULL,&myfactor,(void*)N2);
  pthread_create(&th3,NULL,&mydet,(void*)M);
  pthread_join(th1,(void*)&F1);//Wait until they terminate and get
                               //theirs results
  pthread_join(th2,(void*)&F2);
  pthread_join(th3,(void*)&D);
  pariputsf("F1=%Z\nF2=%Z\nlog(D)=%Z\n",F1,F2,glog(D,3));
                                            //display the results.
  return 0;
}

If this program is called thread.c, you can compile it the following
way: 

cc thread.c -o thread.o -lpari -lpthread

(Add any -I/-L path as necessary).

Cheers,
Bill