This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
On Thu, May 06, 2004 at 12:11:14PM -0300, Brad Spencer wrote:
> I've been trying to the (trunk) mt_allocator within the gcc-3.4.0
> sources (in another email thread) for alignment reasons on SPARC, and
> so far, I haven't had problems there. However, on i686-pc-linux-gnu,
> I've encountered problems with static initialization of the
> mt_allocator's _S_options structure.
>
> For example, using gdb on the following small program will reveal that
> when _S_initialize() runs on line 12, _S_options' constructor appears
> to have not been run. (I don't have a lot of luck setting breakpoints
> on such things, so I am not 100% positive.)
>
> #include <memory>
>
> std::allocator<int *> alloc;
> struct init
> {
> init()
> {
> // Here, alloc._S_options is not initialized, so the constructor
> // makes a broken allocator.
> alloc.allocate(1);
> }
>
> } ini;
>
> int
> main()
> {
> std::allocator<void *> alloc2;
>
> // Here, this _S_options is initialized.
> alloc2.allocate(1);
>
> return 0;
> }
I finally got back to this issue, and started using the head of the
gcc-3.4-branch, which includes the latest mt_allocator changes. The
problem was still happening, but I managed to prove to myself that it
was static initialization order. The nub of the problem is that _Tune
is a class, so its members can't have values before
__static_initialization_and_destruction_0() runs. It looks like this
happens too late:
Breakpoint 2, init (this=0x2ea81) at foo.cc:10
10 alloc.allocate(1);
(gdb) p __gnu_cxx::__mt_alloc<int*>::_S_options
$2 = {
_M_align = 0,
_M_max_bytes = 0,
_M_min_bin = 0,
_M_chunk_size = 0,
_M_max_threads = 0,
_M_freelist_headroom = 0,
_M_force_new = false
}
I tried applying __attribute__((init_priority (101))) in several
places, but those that the compiler accepted seemed to have no
effect. The assembly for __static_initialization_and_destruction_0()
still showed init::init() running before _Tune::Tune().
All I could come up with was this hack of looking to see if
_S_options is still uninitialized in _S_initialize(), and if so,
running an in-place construction to use the default values.
It's ugly, but it does work. Is it safe?
I didn't go any further with change because I hit upon a couple of
questions that I couldn't answer:
1. When exactly are are you allowed to call _S_set_options() and what
exactly will it do? It would seem you have to be after the static
initialization of _S_options, but before the first allocation.
Tricky.
2. Is there a cleaner way to do the same thing without reworking how
the tunable parameters are set? Perhaps things could be changed so
_S_options is _only_ initialized by this lazy init? This
probably depends on the answer to question 1.
--
------------------------------------------------------------------
Brad Spencer - spencer@infointeractive.com - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company
Attachment:
gcc-3.4.1-mt_allocator-lazy-initialization.patch
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |