Skip to content

Commit 909c7ed

Browse files
author
Michael Hemmer
committed
made CGAL::Residue thread safe using
boost thread_specific_ptr from <boost/thread/tss.hpp>
1 parent 36ba068 commit 909c7ed

File tree

2 files changed

+85
-28
lines changed

2 files changed

+85
-28
lines changed

Modular_arithmetic/include/CGAL/Modular_arithmetic/Residue_type.h

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,26 @@
2626
#include <cfloat>
2727
#include <boost/operators.hpp>
2828

29+
#ifdef CGAL_HAS_THREADS
30+
# include <boost/thread/tss.hpp>
31+
#endif
32+
2933
CGAL_BEGIN_NAMESPACE
3034

3135
// fwd
3236
void force_ieee_double_precision();
3337

34-
namespace CGALi{
38+
#ifdef CGAL_HAS_THREADS
39+
#else
3540

41+
namespace CGALi{
3642
struct 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

4350
class Residue;
4451

@@ -69,15 +76,51 @@ class Residue:
6976

7077
private:
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_);

Modular_arithmetic/src/CGAL/Residue_type.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@
2121
#include <CGAL/Modular_arithmetic/Residue_type.h>
2222

2323
namespace CGAL{
24-
24+
#ifdef CGAL_HAS_THREADS
25+
boost::thread_specific_ptr<int> Residue::prime_int_;
26+
boost::thread_specific_ptr<double> Residue::prime_;
27+
boost::thread_specific_ptr<double> Residue::prime_inv_;
28+
#else
2529
int Residue::prime_int = 67111067;
26-
double Residue::prime =67111067.0;
30+
double Residue::prime = 67111067.0;
2731
double Residue::prime_inv =1/67111067.0;
28-
const double Residue::CST_CUT = std::ldexp( 3., 51 );
29-
3032
const CGALi::Modular_arithmetic_needs_ieee_double_precision
3133
Residue::modular_arithmetic_needs_ieee_double_precision
3234
= CGALi::Modular_arithmetic_needs_ieee_double_precision();
35+
#endif
36+
37+
const double Residue::CST_CUT = std::ldexp( 3., 51 );
38+
3339
}

0 commit comments

Comments
 (0)