1 #ifndef CoCoA_GlobalManager_H
2 #define CoCoA_GlobalManager_H
3 
4 //   Copyright (c)  2007,2009-2011,2016,2017  John Abbott
5 
6 //   This file is part of the source of CoCoALib, the CoCoA Library.
7 
8 //   CoCoALib is free software: you can redistribute it and/or modify
9 //   it under the terms of the GNU General Public License as published by
10 //   the Free Software Foundation, either version 3 of the License, or
11 //   (at your option) any later version.
12 
13 //   CoCoALib is distributed in the hope that it will be useful,
14 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //   GNU General Public License for more details.
17 
18 //   You should have received a copy of the GNU General Public License
19 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
20 
21 #include "CoCoA/FractionField.H"
22 #include "CoCoA/MemPool.H"
23 #include "CoCoA/random.H"
24 
25 #include <memory>
26 // using std::unique_ptr;
27 #include <stack>
28 // using std::stack;
29 
30 namespace CoCoA
31 {
32 
33   class DenseUPolyRing; // fwd decl -- defined in DenseUPolyRing.H
34 
35   // This class simply manages the parameters for the GlobalManager ctor.
36   class GlobalSettings
37   {
38   public:
39     enum ResidueSetting {SymmResidues, NonNegResidues};
40     enum AllocatorSetting {GMPAllocator, SystemAllocator};
41     enum ObsolescentFnSetting {ObsolescentFnsForbidden, ObsolescentFnsAllowed};
42 
43   public:
44     GlobalSettings();
45     GlobalSettings& mySetResidueSetting(ResidueSetting r);
46     GlobalSettings& mySetAllocatorSetting(AllocatorSetting a);
47     GlobalSettings& mySetSliceSize(std::size_t SliceSize);
48     GlobalSettings& mySetObsolescentFnsSetting(ObsolescentFnSetting a);
49     GlobalSettings operator()(std::size_t SliceSize) const; // NB creates a new object!!
50 
51   private: // data members
52     bool myResidueSettingHasBeenSet;
53     bool myAllocatorSettingHasBeenSet;
54     bool mySliceSizeHasBeenSet;
55     bool myObsolescentFnSettingHasBeenSet;
56     ResidueSetting myResidueSetting;
57     AllocatorSetting myAllocatorSetting;
58     std::size_t mySliceSize;
59     ObsolescentFnSetting myObsolescentFnSetting;
60     static const std::size_t ourDefaultSliceSize;
61     static const ResidueSetting ourDefaultResidueSetting;
62     static const AllocatorSetting ourDefaultAllocatorSetting;
63 
64     friend GlobalSettings operator+(const GlobalSettings& arg1, const GlobalSettings& arg2);
65 
66     friend class GlobalManager;
67   };
68 
69   GlobalSettings operator+(const GlobalSettings& arg1, const GlobalSettings& arg2);
70 
71   extern const GlobalSettings UseSymmResidues;
72   extern const GlobalSettings UseNonNegResidues;
73   extern const GlobalSettings UseSystemAllocatorForGMP;
74   extern const GlobalSettings UseGMPAllocator;
75   extern const GlobalSettings ForbidObsolescentFns;
76   extern const GlobalSettings AllowObsolescentFns;
77 
78 
79   // At most one instance of this class may exist at any given time.
80   class GlobalManager // : private BOOST::noncopyable ???
81   {
82   public:
83     GlobalManager(const GlobalSettings& settings = GlobalSettings());
84     ~GlobalManager();
myRingZZ()85     const ring& myRingZZ() const { return myZZQQMgr.myRingZZ; }
myRingQQ()86     const FractionField& myRingQQ() const { return myZZQQMgr.myRingQQ; }
87     static GlobalManager* ptr(const char* const FnName);
88 
89   private: // disable copy ctor and assignment
90     GlobalManager(const GlobalManager&);            ///< NEVER DEFINED -- disable copy ctor
91     GlobalManager& operator=(const GlobalManager&); ///< NEVER DEFINED -- disable assignment
92   private:
93     static void DtorError();
94     static bool DtorFailed; // set iff DtorError was called
95     friend bool GlobalManagerDtorFailed();
96   private: // the true global variables
97     static std::size_t GMPSliceSize;          // size in bytes of slices in the GMP MemPool
98     static MemPool* GMPPoolPtr;               // raw ptr to GMP MemPool (or nullptr if there is none)
99     static GlobalManager* ourGlobalDataPtr; ///< nullptr or addr of unique existing GlobalManager
100     friend bool IsInitialized();
101     friend bool IsAllowedObsolescentFnCall();
102 
103     friend class GMPMemMgr;  // so it can set GMPPoolPtr and GMPSliceSize.
104     friend std::size_t GlobalGMPSliceSize();  // accessor fn
105     friend MemPool* GlobalGMPPoolPtr();       // accessor fn
106   private:
107     friend const ring& RingZZ();              ///< defined in RingZZ.C
108     friend const FractionField& RingQQ();     ///< defined in RingQQ.C
109     friend GlobalSettings::ResidueSetting DefaultResidueSetting();     ///< called by ctors for rings of the form Z/(nZ)
110     friend RandomSource& GlobalRandomSource();
111 
112     //-- for Hilbert-Poincare' series --
113     friend void MakeGlobalHPPowerList(const DenseUPolyRing& HSRing);
114     friend int HPPowerListMaxDeg();
115     friend ConstRefRingElem HPPowerList(int exp);
116     void CopyHPPower(RingElem& res, int exp);
117   private:
118     class GMPMemMgr
119     {
120     public:
121       GMPMemMgr(GlobalSettings::AllocatorSetting choice, std::size_t SliceSize);
122       ~GMPMemMgr();
123     private: // data members of GMPMemMgr
124       std::unique_ptr<MemPool> myPoolPtr;
125       void *(*myPrevAlloc) (std::size_t);
126       void *(*myPrevRealloc) (void *, std::size_t, std::size_t);
127       void (*myPrevFree) (void *, std::size_t);
128     };
129   private:
130     class ZZQQMgr
131     {
132     public:
133       ZZQQMgr();
134       ~ZZQQMgr(); // prints rude message if ZZ or QQ still have external references
135     public: // data members of ZZQQMgr
136       ring myRingZZ;                 // Must come before RingQQ
137       FractionField myRingQQ;
138     };
139   private: // data members of GlobalManager
140     const GlobalSettings::ResidueSetting myResidueSetting; ///< default value used for creating rings Z/(nZ)
141     GMPMemMgr myGMPMemMgr;        // Must come before myZZQQMgr
142     ZZQQMgr myZZQQMgr;            // Must come IMMEDIATELY after myGMPMemMgr
143     RandomSource myRandomSource;  // for global random source (must come after myZZQQMgr)
144     static bool ourAllowObsolescentFnsFlag; // flag to allow obsolescent fns to be called
145     // Parts related to registration of pseudo-dtors for globals
146     class PseudoDtor
147     {
148     public:
149       PseudoDtor(void (*dtor)());
150       PseudoDtor(void (*dtor)(void*), void* ptr);  // OBSOLESCENT?
151       void RunDtor();
152     private: // data members
153       void (*Dtor0arg)();
154       void (*Dtor1arg)(void*);
155       void* ObjPtr;
156     };
157     std::stack<PseudoDtor> myDtorStack;
158     friend void RegisterDtorForGlobal(void (*dtor)());
159     friend void RegisterDtorForGlobal(void (*dtor)(void*), void* ptr);  // OBSOLESCENT?
160 
161     //-- for Hilbert-Poincare' series --
162     static std::size_t ourHPMaxPower; // ??? static?
163     std::vector<RingElem> myHPPowerList;
164   };
165 
166 
IsInitialized()167   inline bool IsInitialized()
168   {
169     return (GlobalManager::ourGlobalDataPtr != nullptr);
170   }
171 
172 
IsAllowedObsolescentFnCall()173   inline bool IsAllowedObsolescentFnCall()
174   {
175     return GlobalManager::ptr("IsAllowedObsolescentFnCall")->ourAllowObsolescentFnsFlag;
176   }
177 
178 
179   GlobalSettings::ResidueSetting DefaultResidueSetting();
180   //-- for Hilbert-Poincare' series --
181   void RegisterDtorForGlobal(void (*dtor)(void*), void* ptr);
182 
183 
GlobalManagerDtorFailed()184   inline bool GlobalManagerDtorFailed()
185   {
186     return GlobalManager::DtorFailed;
187   }
188 
189 
190   void MakeGlobalHPPowerList(const DenseUPolyRing& HSRing);
191   int HPPowerListMaxDeg();
192   ConstRefRingElem HPPowerList(int exp);
193   void CopyHPPower(RingElem& res, int exp);
GlobalGMPSliceSize()194   inline std::size_t GlobalGMPSliceSize() { return GlobalManager::GMPSliceSize; }
GlobalGMPPoolPtr()195   inline MemPool* GlobalGMPPoolPtr() { return GlobalManager::GMPPoolPtr; }
196   RandomSource& GlobalRandomSource();
197   void RegisterDtorForGlobal(void (*dtor)());
198 
199 } // end of namespace CoCoA
200 
201 
202 
203 // RCS header/log in the next few lines.
204 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/GlobalManager.H,v 1.31 2019/03/19 11:07:07 abbott Exp $
205 // $Log: GlobalManager.H,v $
206 // Revision 1.31  2019/03/19 11:07:07  abbott
207 // Summary: Replaced 0 by nullptr where appropriate
208 //
209 // Revision 1.30  2019/03/18 17:56:49  abbott
210 // Summary: Changed 0 into nullptr where appropriate
211 //
212 // Revision 1.29  2019/03/04 10:19:28  abbott
213 // Summary: Changed auto_ptr into unqiue_ptr
214 //
215 // Revision 1.28  2017/07/08 19:05:51  abbott
216 // Summary: major revision to interrupt mechanism
217 //
218 // Revision 1.27  2017/03/13 12:17:58  abbott
219 // Summary: Removed CPPFLAGS_check stuff; function subsumed by PREPROCESSOR_DEFNS.H
220 //
221 // Revision 1.26  2017/03/01 17:16:23  abbott
222 // Summary: Added automatic check for some CPP flags (THREADSAFE_HACK)
223 //
224 // Revision 1.25  2016/11/18 18:07:15  abbott
225 // Summary: Changed name of InterruptFlag to InterruptSignalReceived (since it is not a flag)
226 //
227 // Revision 1.24  2016/11/04 20:38:56  abbott
228 // Summary: Added stuff to allow user to enable/disable calling of obsolescent fns
229 //
230 // Revision 1.23  2016/11/03 12:29:58  abbott
231 // Summary: Added file for obsolescent fns; also there is a global flag saying whether to give error if calling one.
232 //
233 // Revision 1.22  2016/09/21 14:24:39  abbott
234 // Summary: Added GlobalManagerDtorFailed (and global var GlobalManager::DtorFailed)
235 //
236 // Revision 1.21  2015/11/30 21:57:15  abbott
237 // Summary: New mem gn DtorError to print out "imminent disaster"
238 //
239 // Revision 1.20  2015/11/04 10:06:52  abbott
240 // Summary: Added RegisterDtorForGlobal
241 //
242 // Revision 1.19  2015/09/02 11:39:25  abbott
243 // Summary: Added IsInitialized
244 //
245 // Revision 1.18  2015/06/29 10:24:29  abbott
246 // Summary: Added GlobalManager::ourInterruptFlag; cleaner impl
247 // Author: JAA
248 //
249 // Revision 1.17  2015/05/20 15:36:59  abbott
250 // Summary: Removed the interrupt flag specifier from GlobalSettings
251 // Author: JAA
252 //
253 // Revision 1.16  2015/05/20 14:49:12  abbott
254 // Summary: Added fns for specifying the interrupt flag to monitor
255 // Author: JAA
256 //
257 // Revision 1.15  2014/07/01 12:40:14  bigatti
258 // -- added CopyHPPower
259 //
260 // Revision 1.14  2013/06/17 08:54:02  abbott
261 // Added RegisterDtorForGlobal.
262 //
263 // Revision 1.13  2012/12/04 20:04:36  abbott
264 // Includes new unified random header file.
265 //
266 // Revision 1.12  2012/02/08 13:37:35  bigatti
267 // -- changed Z,Q --> ZZ,QQ
268 //
269 // Revision 1.11  2011/05/19 13:54:48  abbott
270 // Replaced DefaultResiduesAreSymm by DefaultResidueSetting.
271 //
272 // Revision 1.10  2011/05/03 10:03:32  abbott
273 // Added GlobalRandomSource.
274 // Internally added GlobalManager::ptr to allow neater implementations.
275 //
276 // Revision 1.9  2010/11/11 17:45:08  abbott
277 // Moved GMPMemMgr so that it is a nested class inside GlobalManager.
278 //
279 // Revision 1.8  2010/11/05 17:39:14  bigatti
280 // -- fixed name for HPPowerList function declaration
281 //
282 // Revision 1.7  2010/10/29 09:36:04  bigatti
283 // -- added globals for Hilbert-Poincare' series
284 //
285 // Revision 1.6  2010/10/27 20:58:45  abbott
286 // Major reorganization of GlobalManager and GMPAllocator.
287 //
288 // Revision 1.5  2010/10/22 14:03:04  abbott
289 // Major change to GMPAllocator -- it is now set/activated by the GlobalManager.
290 // This is a Friday afternoon check-in... hope to check in cleaner code in the
291 // next few days.
292 //
293 // Revision 1.4  2010/09/30 14:28:23  abbott
294 // Replaced auto_ptrs to RingZ and RingQ by direct values; ctor changed accordingly.
295 //
296 // Dtor now checks that ref counts in RingZ and RingQ are correct; if not, a rude
297 // message is printed on cerr (and the program will probably crash after the
298 // GlobalManager has been destroyed).
299 //
300 // Revision 1.3  2009/05/14 09:39:29  abbott
301 // Added possibility to specify "symmetric" or "non-negative" residues
302 // in quotients of ZZ.  Affects printing of elements in quotients of ZZ
303 // (also changed printing of elements in general quotient rings).
304 // Consequent changes in several tests.
305 //
306 // Revision 1.2  2007/10/30 17:14:12  abbott
307 // Changed licence from GPL-2 only to GPL-3 or later.
308 // New version for such an important change.
309 //
310 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
311 // Imported files
312 //
313 // Revision 1.2  2007/03/05 21:33:13  cocoa
314 // Improved/cleaned GlobalManager; added doc too.
315 //
316 // Revision 1.1  2007/03/03 14:02:11  bigatti
317 // -- "foundations" renamed into "GlobalManager"
318 //
319 // Revision 1.1  2007/03/02 16:46:28  cocoa
320 // New foundations object which calls ctors and dtors of global objects.
321 //
322 
323 #endif
324