% Copyright (c) 2000 The PARI Group % % This file is part of the PARI/GP documentation % % Permission is granted to copy, distribute and/or modify this document % under the terms of the GNU General Public License \appendix{PARI and threads} To use PARI in multi-threaded programs, you must configure it using \kbd{Configure --enable-tls}. Your system must implement the \kbd{\_\_thread} storage class. As a major side effect, this breaks the \kbd{libpari} ABI: the resulting library is not compatible with the old one, and \kbd{-tls} is appended to the PARI library \kbd{soname}. On the other hand, this library is now thread-safe. PARI provides some functions to set up PARI subthreads\sidx{threads}. In our model, each concurrent thread needs its own PARI stack. The following scheme is used: \noindent Child thread: \bprog void *child_thread(void *arg) { GEN data = pari_thread_start((struct pari_thread*)arg); GEN result = ...; /* Compute result from data */ pari_thread_close(); return (void*)result; } @eprog \noindent Parent thread: \bprog pthread_t th; struct pari_thread pth; GEN data, result; pari_thread_alloc(&pth, s, data); pthread_create(&th, NULL, &child_thread, (void*)&pth); /* start child */ ... /* do stuff in parent */ pthread_join(th, (void*)&result); /* wait until child terminates */ result = gcopy(result); /* copy result from thread stack to main stack */ pari_thread_free(&pth); /* ... and clean up */ @eprog \fun{void}{pari_thread_alloc}{struct pari_thread *pth, size_t s, GEN arg} Allocate a PARI stack of size \kbd{s} and associate it, together with the argument \kbd{arg}, with the PARI thread data \kbd{pth}. \fun{void}{pari_thread_free}{struct pari_thread *pth} Free the PARI stack associated with the PARI thread data \kbd{pth}. This is called after the child thread terminates, i.e.~after \tet{pthread_join} in the parent. Any \kbd{GEN} objects returned by the child in the thread stack need to be saved before running this command. \fun{void}{pari_thread_init}{void} Initialize the thread-local PARI data structures. This function is called by \kbd{pari\_thread\_start}. \fun{GEN}{pari_thread_start}{struct pari_thread *t} Initialize the thread-local PARI data structures and set up the thread stack using the PARI thread data \kbd{pth}. This function returns the thread argument \kbd{arg} that was given to \kbd{pari\_thread\_alloc}. \fun{void}{pari_thread_close}{void} Free the thread-local PARI data structures, but keeping the thread stack, so that a \kbd{GEN} returned by the thread remains valid. \noindent Under this model, some PARI states are reset in new threads. In particular \item the random number generator is reset to the starting seed; \item the system stack exhaustion checking code, meant to catch infinite recursions, is disabled (use \kbd{pari\_stackcheck\_init()} to reenable it); \item cached real constants (returned by \kbd{mppi}, \kbd{mpeuler} and \kbd{mplog2}) are not shared between threads and will be recomputed as needed; \noindent The following sample program can be compiled using \bprog cc thread.c -o thread.o -lpari -lpthread @eprog\noindent (Add \kbd{-I/-L} paths as necessary.) \noindent\bprogfile{../examples/thread.c} \vfill\eject