GlobalManager

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



CoCoALib Documentation Index

!!NEEDS MAJOR REVISION!!

User Documentation for GlobalManager

A GlobalManager object does some very simple management of (certain) global values used by CoCoALib (i.e. controlled initialization and 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 the CoCoALib examples.

The ctor for a GlobalManager has one (optional) argument. This argument is used to specify whether elements of rings of the form ZZ/n should be printed as least non-negative residues or as (symmetric) least magnitude residues. If no preference is specified then the current default is symmetric residues. If you want to pass an argument to the ctor then it should be either UseNonNegResidues or UseSymmResidues

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 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 RingZ and RingQ 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 RingZImpl 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 RingZ() and RingQ() since they will not work before the GlobalManager is registered.

The two functions MakeUniqueCopyOfRingZ and MakeUniqueCopyOfRingQ are supposed to be accessible only to GlobalManager; they create the unique copies of those two rings which will be stored in the global data. The functions are defined in RingZ.C and RingQ.C respectively but do not appear in the corresponding header files (thus supposedly making them "inaccessible" to other users).

The dtor for GlobalManager checks that RingZ and RingQ 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.

Bugs, Shortcomings, etc

20100930 The private copies of RingZ and RingQ 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.

Should the ctor for GlobalManager initialize the CoCoALib i/o streams?

Perhaps the GlobalManager ctor should accept an argument which would cause it to create a GMPAllocator?

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?