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