GlobalManager

© 2007,2009-2011 John Abbott
GNU Free Documentation License, Version 1.2



CoCoALib Documentation Index

User Documentation for GlobalManager

A GlobalManager object does some very simple management of (certain) global values used by CoCoALib (in particular controlled destruction). So that the operations in CoCoALib can work properly you should create an object of type GlobalManager before using any other feature of CoCoALib. Conversely, the GlobalManager object should be destroyed only after you have finished using CoCoALib features. An easy way to achieve this is to create a local variable of type GlobalManager at the start of a top level procedure (e.g. main). See for instance the CoCoALib example programs.

Once the GlobalManager has been created you can use the following functions:

GlobalManager: user selectable options

The ctor for a GlobalManager has one (optional) argument. This argument is used to specify the global settings. Currently the settings which can be specified are the type of memory manager to use for GMP values (viz. big integers and rationals), and whether elements of rings of the form ZZ/n should be printed as least non-negative residues or as (symmetric) least magnitude residues. The current defaults are to use the system memory mananger and to print symmetric residues.

There are three possibilities for specifying the memory manager for GMP:

WARNING if you store GMP values in global variables, it is safest to use only the GMP default memory manager!

There are two possibilities for specifying the printing convention for elements of rings of the form ZZ/n:

To specify more than one global setting the individual specifiers should be combined using operator+. Combining incompatible or redundant specifiers will produce a run-time error. We recommend using the CoCoALib custom allocator (with default slice size) if possible; it may not be possible if you use CoCoALib with another library which uses GMP values. The custom allocator offers slightly better performance, and can be helpful when debugging or fine-tuning code.

An exception will be thrown if you attempt to create more than one GlobalManager object (without having destroyed all earlier GlobalManagers). The exception is of type CoCoA::ErrorInfo and has error code ERR::GlobalManager2. At the moment the ctor for GlobalManager is not threadsafe; it is the user's responsibility to avoid trying to create several instances simultaneously.

The Purpose of the GlobalManager

The concept of GlobalManager was created to handle in a clean and coherent manner (almost) all global values used by CoCoALib; in particular it was prompted by the decision to make the ring of integers a global value (and also the field of rationals). The tricky part was ensuring the orderly destruction of RingZZ and RingQQ before main exits. Recall that C++ normally destroys globals after main has completed, and that the order of destruction of globals cannot easily be governed; destroying values in the wrong order can cause to the program to crash just before it terminates. Another advantage of forcing destruction before main exits is that it makes debugging very much simpler (e.g. the MemPool object inside RingZZImpl will be destroyed while the input and output streams are still functioning, thus allowing the MemPool destructor to report any anomalies). And of course, it is simply good manners to clean up properly at the end of the program.

Maintenance notes for GlobalManager

To implement the restriction that only one GlobalManager may exist at any one time, the first instruction in the ctor checks that the global variable GlobalManager::ourGlobalDataPtr is null. If it is null, it is immediately set to point the object being constructed.

The ctor for GlobalManager is fairly delicate: e.g. the functions it calls cannot use the functions RingZZ() and RingQQ() since they will not work before the GlobalManager is registered.

The two functions MakeUniqueCopyOfRingZZ and MakeUniqueCopyOfRingQQ are supposed to be accessible only to the ctor of GlobalManager; they create the unique copies of those two rings which will be stored in the global data. The functions are defined in RingZZ.C and RingQQ.C respectively but do not appear in the corresponding header files (thus making them "invisible" to other users).

The dtor for GlobalManager checks that RingZZ and RingQQ are not referred to by any other values (e.g. ring elements which have been stored in global variables). A rude message is printed on cerr if the reference counts are too high, and a program crash is likely once the GlobalManager has been destroyed.

GMPMemMgr

The GMPMemMgr class performs the necessary steps for setting the memory manager for GMP values. At the moment there are essentially two choices: use the system memory manager, or use a MemPool to handle the memory for small values. The first parameter to the ctor for GMPMemMgr says which sort of memory manager to use. If the system allocator is chosen, then the ctor does nothing (since the GMP default is the system manager); similarly nothing is done when the GMPMemMgr object is destroyed. The second argument is completely ignored when the system allocator is chosen.

The situation is more complicated if CoCoALib's custom allocator is to be used. The second argument specifies the "slice size" (in bytes) which is to be used -- the implementation may automatically increase this value to the next "convenient" value (see also the documentation for MemPool). The slice size defines what a GMP small value is: it is a value whose GMP internal representation fits into a single slice. The memory for small values is managed by a (global) MemPool, while the memory for larger values is managed by the standard malloc family of functions.

Since the only place a GMPMemMgr object appears is as a data field in a GlobalManager, we have an automatic guarantee that there will be at most one GMPMemMgr object in existence -- this fact is exploited (implicitly) in the ctor and dtor for GMPMemMgr when calling the GMP functions for setting the memory management functions.

Of the alloc/free/realloc functions which are handed to GMP, only CoCoA_GMP_realloc displays any complication. GMP limbs can be stored either in memory supplied by the MemPool belonging to a GMPAllocator object or in system allocated memory; a reallocation could cause the limbs to be moved from one sort of memory to the other.

GlobalSettings

The GlobalSettings class serves only to allow a convenient syntax for specifying the parameters to the GlobalManager ctor. The only mild complication is the operator+ for combining the ctor parameters, where we must check that nonsensical combinations are not built.

Bugs, Shortcomings, etc

2010-09-30 The private copies of RingZZ and RingQQ are now direct members, previously they were owned via auto_ptrs. The new implementation feels cleaner, but has to include the definitions of ring and FractionField.

You cannot print out a GlobalManager object; is this really a bug?

Ctor for GlobalManager is NOT THREADSAFE.

Should the ctor for GlobalManager set the globals which control debugging and verbosity in MemPools?