2626#include < cfloat>
2727#include < boost/operators.hpp>
2828
29+ #ifdef CGAL_HAS_THREADS
30+ # include < boost/thread/tss.hpp>
31+ #endif
32+
2933CGAL_BEGIN_NAMESPACE
3034
3135// fwd
3236void force_ieee_double_precision ();
3337
34- namespace CGALi {
38+ #ifdef CGAL_HAS_THREADS
39+ #else
3540
41+ namespace CGALi {
3642struct Modular_arithmetic_needs_ieee_double_precision {
37- Modular_arithmetic_needs_ieee_double_precision (){
38- CGAL::force_ieee_double_precision ();
39- }
43+ Modular_arithmetic_needs_ieee_double_precision (){
44+ CGAL::force_ieee_double_precision ();
45+ }
4046};
41- }
47+ } // namespace CGALi
48+ #endif
4249
4350class Residue ;
4451
@@ -69,15 +76,51 @@ class Residue:
6976
7077private:
7178 static const double CST_CUT;
72- static const CGALi::Modular_arithmetic_needs_ieee_double_precision
73- modular_arithmetic_needs_ieee_double_precision;
74- private:
75-
76- static int prime_int;
77- static double prime;
78- static double prime_inv;
79-
80-
79+
80+ #ifdef CGAL_HAS_THREADS
81+ static boost::thread_specific_ptr<int > prime_int_;
82+ static boost::thread_specific_ptr<double > prime_;
83+ static boost::thread_specific_ptr<double > prime_inv_;
84+
85+ static void init_class_for_thread (){
86+ CGAL_precondition (prime_int_.get () == NULL );
87+ CGAL_precondition (prime_.get () == NULL );
88+ CGAL_precondition (prime_inv_.get () == NULL );
89+ prime_int_.reset (new int (67111067 ));
90+ prime_.reset (new double (67111067.0 ));
91+ prime_inv_.reset (new double (1.0 /67111067.0 ));
92+ CGAL::force_ieee_double_precision ();
93+ }
94+
95+ static inline int get_prime_int (){
96+ if (prime_int_.get () == NULL )
97+ init_class_for_thread ();
98+ return *prime_int_.get ();
99+ }
100+
101+ static inline double get_prime (){
102+ if (prime_.get () == NULL )
103+ init_class_for_thread ();
104+ return *prime_.get ();
105+ }
106+
107+ static inline double get_prime_inv (){
108+ if (prime_inv_.get () == NULL )
109+ init_class_for_thread ();
110+ return *prime_inv_.get ();
111+ }
112+ #else
113+ static int prime_int;
114+ static double prime;
115+ static double prime_inv;
116+ static int get_prime_int (){ return prime_int;}
117+ static double get_prime () { return prime;}
118+ static double get_prime_inv (){ return prime_inv;}
119+ // calls force_ieee_double_precision(); within constructor
120+ static const CGALi::Modular_arithmetic_needs_ieee_double_precision
121+ modular_arithmetic_needs_ieee_double_precision;
122+ #endif
123+
81124 /* Quick integer rounding, valid if a<2^51. for double */
82125 static inline
83126 double RES_round (double a){
@@ -102,13 +145,14 @@ class Residue:
102145 /* Big modular reduction (e.g. after multiplication) */
103146 static inline
104147 double RES_reduce (double a){
105- return a - prime * RES_round (a * prime_inv );
148+ return a - get_prime () * RES_round (a * get_prime_inv () );
106149 }
107150
108151
109152 /* Little modular reduction (e.g. after a simple addition). */
110153 static inline
111154 double RES_soft_reduce (double a){
155+ double prime = get_prime ();
112156 double b = 2 *a;
113157 return (b>prime) ? a-prime :
114158 ((b<-prime) ? a+prime : a);
@@ -142,7 +186,7 @@ class Residue:
142186 double RES_inv (double ri1){
143187 double bi = 0.0 ;
144188 double bi1 = 1.0 ;
145- double ri = prime ;
189+ double ri = get_prime () ;
146190 double p, tmp, tmp2;
147191
148192 Real_embeddable_traits<double >::Abs double_abs;
@@ -175,16 +219,23 @@ class Residue:
175219 *
176220 */
177221 static int
178- set_current_prime (int p){
179- int old_prime = prime_int;
180- prime_int = p;
181- prime = (double )p;
182- prime_inv = (double )1 /prime;
183- return old_prime;
222+ set_current_prime (int p){
223+ int old_prime = get_prime_int ();
224+ #ifdef CGAL_HAS_THREADS
225+ *prime_int_.get () = p;
226+ *prime_.get () = double (p);
227+ *prime_inv_.get () = 1.0 /double (p);
228+ #else
229+ prime_int = p;
230+ prime = double (p);
231+ prime_inv = 1.0 / prime;
232+ #endif
233+ return old_prime;
184234 }
185- /* ! \brief return the current prime. */
235+
236+ /* ! \brief return the current prime. */
186237 static int get_current_prime (){
187- return prime_int ;
238+ return get_prime_int () ;
188239 }
189240 int get_value () const {
190241 return int (x_);
0 commit comments