Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019  2020  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019  2020 
<== Date ==> <== Thread ==>

Subject: RE: c++ static initialization
From: "Jeff Hill" <johill@lanl.gov>
To: "'EPICS Core Talk'" <core-talk@aps.anl.gov>
Date: Thu, 11 Aug 2011 14:10:10 -0600
> > But as Jeff implied, epicsThreadOnce() is essential to coding lazy
> > initialization correctly on an SMP system.
> 
> I would like to see the argument that leads to such a conclusion.

Of course there are some famous discussions on this topic related to SMP (reference: search for "double checked lock optimization" in google).

Otherwise, the compounding issue is that if there is only one thread running during the C++ static initialization (because no user code started one) then mutex locking is not required when testing the init flag, and otherwise it is.

Note that in C++ if one has code like this ...

A & A :: instance ()
{
    static A & a = * new A ();
    return a;
}

Then we don’t have to actually write code for the init flag, and according to the C++ standard in some compiler dependent fashion it is actually implemented for us behind the scenes the first time that A :: instance () is called. Whether the compiler implements this init flag with an SMP safe test-and-set intrinsic is implementation dependent (I have a good guess at what I would do if I was writing the compiler).

Jeff
______________________________________________________
Jeffrey O. Hill           Email        johill@lanl.gov
LANL MS H820              Voice        505 665 1831
Los Alamos NM 87545 USA   FAX          505 665 5107

Message content: TSPA

With sufficient thrust, pigs fly just fine. However, this is
not necessarily a good idea. It is hard to be sure where they
are going to land, and it could be dangerous sitting under them
as they fly overhead. -- RFC 1925


> -----Original Message-----
> From: core-talk-bounces@aps.anl.gov [mailto:core-talk-bounces@aps.anl.gov]
> On Behalf Of Benjamin Franksen
> Sent: Thursday, August 11, 2011 11:58 AM
> To: Andrew Johnson
> Subject: Re: c++ static initialization
> 
> Hi Andrew
> 
> What I would try to avoid at all cost is non-trivial initialization in a
> *constructor* for a static object. I listed lazy initialization as one
> alternative possibility. Just to make sure we re talking about the same
> concept, what I mean is to add some code like
> 
>   if (!this->initialized) this->initialize();
> 
> at the start of each method. I may be wrong but I can't think of any
> subsystem
> where this approach cannot be used instead of calling initialize() from a
> constructor. Remember, when all code in base was written in C we simply
> did
> not *have* the possibility to do anything non-trivial before main (or
> before
> the startup script starts to run); back then there existed exactly the two
> ways to solve the problem that I listed: lazy init, or explicit call to
> init
> during startup.
> 
> Am Donnerstag, 11. August 2011, um 18:10:55 schrieben Sie:
> > On 2011-08-09 Benjamin Franksen wrote:
> > > (1) Static objects should be avoided wherever possible.
> > >
> > > (2) If static objects are used, the constructor should be trivial,
> i.e.
> > > not perform anything except setting members to default values.
> >
> > We can't enforce that as a hard rule — Eric's example of registering
> iocsh
> > commands is one, and there are others.  Maybe we need to document which
> > EPICS APIs /can/ be used in static initialization code and which
> /can't/.
> >
> > On vxWorks and some RTEMS systems the NTPTimeSync and ClockTimeSync
> threads
> > are started from a static initializer, and they also get registered with
> > the taskwd subsystem which lazily starts its own thread as a result:
> 
> As I said, starting threads lazily is not as evil as doing it directly
> from a
> constructor for a static object, i.e. before main() starts.
> 
> > > (3) Non-trivial initialization for complex objects should be done in a
> > >
> > >  regular method either lazily ("Construct On First Use") or by an
> > >  explicit call from some startup routine. The latter has the advantage
> > >  of a well-defined order of initialization; the former is sometimes
> more
> > >  convenient.
> >
> > There is a major thicket here which needs careful examination...
> >
> > > (4) Starting threads inside static initialization is a bad idea and
> > > should
> > >
> > >  not be allowed (see rule 2).
> >
> > I agree that in principle we shouldn't allow calls to
> epicsThreadCreate()
> > from static constructors, but we already have several examples above
> which
> > can't easily be changed, and anything that calls an errlog routine from
> a
> > static constructor will lazily start the errlog thread for some more.
> 
> I recognize that logging is one of the exceptions to my rule (1) but
> (again)
> we can use lazy initialization here.
> 
> > > (5) epicsThreadOnce should also be avoided wherever possible. Using it
> > >
> > >  means objects cannot be freely passed between threads which is
> detriment
> > >  to composability.
> >
> > But as Jeff implied, epicsThreadOnce() is essential to coding lazy
> > initialization correctly on an SMP system.
> 
> I would like to see the argument that leads to such a conclusion.
> 
> > I don't know what the best solution is to all this, but I do know that
> we
> > can't just write down a set of rules without examining all our
> subsystems
> > and making changes to bring them into compliance.
> 
> Of course we would need to make changes to subsystems to make them conform
> to
> stated rules. I would consider this as regular maintenance work, the more
> so
> since the changes needed are mostly mechanical (move the non-trivial stuff
> from
> constructor to extra method, add the code listed above to every method).
> 
> Cheers
> Ben
> 
> ________________________________
> 
> Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
> 
> Mitglied der Hermann von Helmholtz-Gemeinschaft Deutscher
> Forschungszentren e.V.
> 
> Aufsichtsrat: Vorsitzender Prof. Dr. Dr. h.c. mult. Joachim Treusch, stv.
> Vorsitzende Dr. Beatrix Vierkorn-Rudolph
> Geschäftsführer: Prof. Dr. Anke Rita Kaysser-Pyzalla, Dr. Ulrich Breuer
> 
> Sitz Berlin, AG Charlottenburg, 89 HRB 5583
> 
> Postadresse:
> Hahn-Meitner-Platz 1
> D-14109 Berlin
> 
> http://www.helmholtz-berlin.de



References:
c++ static initialization Jeff Hill
Re: c++ static initialization Benjamin Franksen
Re: c++ static initialization Andrew Johnson
Re: c++ static initialization Benjamin Franksen

Navigate by Date:
Prev: Re: c++ static initialization Andrew Johnson
Next: Re: c++ static initialization Benjamin Franksen
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019  2020 
Navigate by Thread:
Prev: Re: c++ static initialization Benjamin Franksen
Next: RE: c++ static initialization Jeff Hill
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019  2020 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·