This is a proposed fix for the numpunct facet for stdcxx-1056:
0. Number of reported race conditions is now 0 (zero).
1. No memory leaks in stdcxx (there are memory leaks reported in either
libc or glibc, but there's nothing we can do about these anyway).
2. This fix preserves perfect forwarding in the _numpunct.h header file.
3. This fix eliminates code from facet.cpp and locale_body.cpp which
was creating unnecessary overhead, with the potential of causing
memory corruption, while providing no discernable benefit.
More specifically:
It is not true that there was no eviction policy of cached locales or
facets in stdcxx. Not only cache eviction code existed, and still exists
today, but cache cleanups and resizing were performed periodically,
either when an object's reference count dropped to 0 (zero), or whenever
the number of cached objects fell below sizeof(cache) / 2.
In the latter case, both the facet cache and the locale cache performed
a new allocation of the cache array, followed by a memcopy and a delete[]
of the old cache array.
First, the default size of the facets and locales caches was too small:
it was set to 8. I raised this to 32. A direct consequence of this
insufficient default size of 8 was that the cache had to resize itself
very soon after program startup. This cache resize operation consists of:
allocate memory for a new cache, copy the existing cached objects
from the old cache to the new cache, and then delete[] the old cache.
This is a first unnecessary overhead.
Second, and as I mentioned above, whenever the number of cached objects
fell below sizeof(cache) / 2, the cache resized itself, by performing
the same sequence of operations as described above.
This is a second unnecessary overhead.
Third, cached objects were automatically evicted whenever their reference
count dropped to 0 (zero). There are two consequences to this eviction
policy: if the program needs to re-use an object (facet or locale) which
has been evicted and subsequently destroyed, this object needs then to be
constructed again later on, and subsequently re-inserted into the cache.
This, in turn, would trigger a cache resize, followed by copying and
delete[] of the old cache buffer.
Object eviction followed by destruction followed by reconstruction is
a third unnecessary overhead. Re-inserting a re-constructed object into,
the cache, followed by a potential cache resize involving allocation of
a new buffer, copying pointers from the old cache to the new cache,
followed by delete[] of the old cache is a fourth unnecessary overhead.
Real-life programs tend to reuse locales and/or facets they have created.
There is no point in destroying and evicting these objects simply because
there may be periods when the object isn't referenced at time. The object
is likely to be needed again, later on.
The fix proposed here eliminates the cache eviction and object destruction
policy completely. Once created, objects remain in the cache, even though
they may reside in the cache with no references. This eliminates the
cache resize / copy / delete[] overhead. It also eliminates the overhead
of re-constructing an evicted / destroyed object, if it is needed again
later.
4. Tests and Analysis Results:
4.1. SunPro 12.3 / Solaris / SPARC / Race Conditions Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.sunpro.solaris-sparc.datarace.er.html/index.html
4.2. SunPro 12.3 / Solaris / SPARC / Heap and Memory Leaks Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.sunpro.solaris-sparc.heapcheck.er.html/index.html
4.3. SunPro 12.3 / Linux / Intel / Race Conditions Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.sunpro.linux-intel.datarace.er.html/index.html
4.4. SunPro 12.3 / Linux / Intel / Heap and Memory Leaks Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.sunpro.linux-intel.heapcheck.er.html/index.html
4.5. Intel 2013 / Linux / Intel / Race Conditions Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.intel.linux.datarace.r007ti3.inspxez
4.6. Intel 2013 / Linux / Intel / Heap and Memory Leaks Test:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/22.locale.numpunct.mt.intel.linux.heapcheck.r008mi1.inspxez
5. Source code for this fix:
http://s247136804.onlinehome.us/stdcxx-1056-20120919/_numpunct.h
http://s247136804.onlinehome.us/stdcxx-1056-20120919/facet.cpp
http://s247136804.onlinehome.us/stdcxx-1056-20120919/locale_body.cpp
http://s247136804.onlinehome.us/stdcxx-1056-20120919/punct.cpp
These files are based on stdcxx 4.2.1.
--
Stefan Teleman
KDE e.V.
[email protected]