From 2a9a73654257b0dd3b78fb6b353ecf0188dc497b Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 19:32:14 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_UP_unnamed) with portable code. The order of initialization of non-local objects in different compilation units is not specified in C++. Hence special care should be taken to avoid static initialization order fiasco. CLN solved the problem with some evil (GCC specific, and even GCC-version-specific) hack. Replace it with a technique similar to one used in STL to initialize std::cout and friends. --- include/cln/univpoly.h | 1 - src/polynomial/elem/cl_UP_unnamed.cc | 41 ++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/cln/univpoly.h b/include/cln/univpoly.h index 0116827..2ede66f 100644 --- a/include/cln/univpoly.h +++ b/include/cln/univpoly.h @@ -348,7 +348,6 @@ public: // Lookup or create the "standard" univariate polynomial ring over a ring r. extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r); -//CL_REQUIRE(cl_UP_unnamed) // Lookup or create a univariate polynomial ring with a named variable over r. extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname); diff --git a/src/polynomial/elem/cl_UP_unnamed.cc b/src/polynomial/elem/cl_UP_unnamed.cc index 0ca47d2..8b0ef32 100644 --- a/src/polynomial/elem/cl_UP_unnamed.cc +++ b/src/polynomial/elem/cl_UP_unnamed.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_UP_unnamed) - // Specification. #include "cln/univpoly.h" @@ -34,26 +32,46 @@ static bool maygc_htentry (const cl_htentry_from_rcpointer_to_rcpointer& entry) return false; } -static const cl_wht_from_rcpointer_to_rcpointer univpoly_ring_table = cl_wht_from_rcpointer_to_rcpointer(maygc_htentry); +class univpoly_ring_cache +{ + static cl_wht_from_rcpointer_to_rcpointer* univpoly_ring_table; + static int count; +public: + inline cl_univpoly_ring* get_univpoly_ring(const cl_ring& r) + { + return (cl_univpoly_ring*) univpoly_ring_table->get(r); + } + inline void store_univpoly_ring(const cl_univpoly_ring& R) + { + univpoly_ring_table->put(R->basering(), R); + } + univpoly_ring_cache(); + ~univpoly_ring_cache(); +}; + +cl_wht_from_rcpointer_to_rcpointer* univpoly_ring_cache::univpoly_ring_table = 0; +int univpoly_ring_cache::count = 0; -static inline cl_univpoly_ring* get_univpoly_ring (const cl_ring& r) +univpoly_ring_cache::univpoly_ring_cache() { - return (cl_univpoly_ring*) univpoly_ring_table.get(r); + if (count++ == 0) + univpoly_ring_table = new cl_wht_from_rcpointer_to_rcpointer(maygc_htentry); } -static inline void store_univpoly_ring (const cl_univpoly_ring& R) +univpoly_ring_cache::~univpoly_ring_cache() { - univpoly_ring_table.put(R->basering(),R); + if (--count == 0) + delete univpoly_ring_table; } - const cl_univpoly_ring find_univpoly_ring (const cl_ring& r) { - var cl_univpoly_ring* ring_in_table = get_univpoly_ring(r); + static univpoly_ring_cache cache; + var cl_univpoly_ring* ring_in_table = cache.get_univpoly_ring(r); if (!ring_in_table) { var cl_univpoly_ring R = cl_make_univpoly_ring(r); - store_univpoly_ring(R); - ring_in_table = get_univpoly_ring(r); + cache.store_univpoly_ring(R); + ring_in_table = cache.get_univpoly_ring(r); if (!ring_in_table) throw runtime_exception(); } @@ -62,4 +80,3 @@ const cl_univpoly_ring find_univpoly_ring (const cl_ring& r) } // namespace cln -CL_PROVIDE_END(cl_UP_unnamed)