Solving mt_allocator's static initialization ordering problem
Brad Spencer
spencer@infointeractive.com
Wed Jun 30 15:21:00 GMT 2004
On Wed, Jun 30, 2004 at 01:29:55PM +0200, Paolo Carlini wrote:
> Seems not so bad to me, frankly. In any case, it should be moved *before*
> the lines
>
> if (_S_options._M_force_new)
> return;
You are definately correct about this. Otherwise, GLIBCXX_FORCE_NEW
cannot be taken into account!
Plus, that raises another point, actually. I think we once discussed
changing that to:
if (_S_options._M_force_new) {
_S_init = true;
return;
}
This is because (I think) the code presumes that _M_force_new can
never change after the first call to allocate(). So, if
GLIBCPP_FORCE_NEW is on, there's no need to get all the way to
_S_initialize() on every allocate() call.
I've attached a revised patch which I verified works with
GLIBCXX_FORCE_NEW.
--
------------------------------------------------------------------
Brad Spencer - spencer@infointeractive.com - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company
-------------- next part --------------
2004-06-30 Brad Spencer <spencer@infointeractive.com>
* include/ext/mt_allocator.h: Handle allocations at static
initialization that happen before _S_options is (automatically)
constructed; set _S_init even if _M_force_new is true.
-------------- next part --------------
Index: include/ext/mt_allocator.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/ext/mt_allocator.h,v
retrieving revision 1.31
diff -u -p -r1.31 mt_allocator.h
--- include/ext/mt_allocator.h 18 Jun 2004 23:27:30 -0000 1.31
+++ include/ext/mt_allocator.h 30 Jun 2004 15:03:49 -0000
@@ -488,8 +488,25 @@ namespace __gnu_cxx
__mt_alloc<_Tp>::
_S_initialize()
{
- if (_S_options._M_force_new)
+ // This method is called on the first allocation (when _S_init is still
+ // false) to create the bins.
+
+ // Ensure that the static initialization of _S_options has happened.
+ // This is frighteningly ugly, and depends on (a) _M_align == 0 being an
+ // invalid value that is only present at startup, and (b) the real
+ // static initialization that happens later not actually changing
+ // anything.
+ if (_S_options._M_align == 0) {
+ new (&_S_options) _Tune;
+ }
+
+ // _M_force_new must not change after the first allocate(), which in
+ // turn calls this method, so if it's false, it's false forever and we
+ // don't need to return here ever again.
+ if (_S_options._M_force_new) {
+ _S_init = true;
return;
+ }
// Calculate the number of bins required based on _M_max_bytes.
// _S_bin_size is statically-initialized to one.
More information about the Libstdc++
mailing list