lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <>
Subject Re: [lucy-dev] OFFSET globals
Date Tue, 24 Apr 2012 01:36:54 GMT
On Mon, Apr 23, 2012 at 8:50 AM, Nick Wellnhofer <> wrote:
> There's only a small problem I can see on platforms where we can't hide
> symbols: Between the loading of the DLL and the initialization of the parcel
> there will be a window during which the offsets will become uninitialized.
> This would cause problems with threads.

I'm not sure that we need to worry about that, because it seems that on common
POSIX systems, *variable* symbols are always resolved by the dynamic loader
before the DSO can be used. (On Windows, symbols don't have to be exported
so there's no issue.) Only function symbols are resolved lazily:  [section 1.5.2]

    Due to the way code is generated on some architectures it is possible to
    delay the processing of some relocations until the references in question
    are actually used. This is on many architectures the case for calls to
    functions. All other kinds of relocations always have to be processed
    before the object can be used.


    Perform lazy binding. Only resolve symbols as the code that references
    them is executed. If the symbol is never referenced, then it is never
    resolved. (Lazy binding is only performed for function references;
    references to variables are always immediately bound when the library is


    Each external function reference is resolved when the function is first


    Each external function reference is bound the first time the function is


    Only immediate symbol references are relocated when the object is first
    loaded. Lazy references are not relocated until a given function is called
    for the first time. This value for mode should improve performance, since
    a process might not require all lazy references in any given object.  This
    behavior mimics the normal loading of dependencies during process
    initialization. See NOTES.

These implementations all behave this way despite the fact that POSIX
describes the timing as "implementation-defined":


    Relocations shall be performed at an implementation-defined time, ranging
    from the time of the dlopen() call until the first reference to a given
    symbol occurs. Specifying RTLD_LAZY should improve performance on
    implementations supporting dynamic symbol binding as a process may not
    reference all of the functions in any given object. And, for systems
    supporting dynamic symbol resolution for normal process execution, this
    behavior mimics the normal handling of process execution.

So... that means that before dlopen returns, any OFFSET vars in the DSO will
have been resolved to local copies (which will always be present under your
scheme).  These will hold potentially incorrect values until our bootstrap
routines run, but I don't see a scenario where a *different* thread starts
using the DSO before then -- and of course the thread doing the loading will
execute linearly and finish bootstrapping before use.

Now, I believe we would have a problem if we were exposing *function* symbols,
as a different thread could attempt to lazy load a function symbol in the
window between the return of dlopen and bootstrap completion.  But since our
method invocations are static inline routines, they are not exported as DSO
symbols -- only the OFFSET vars that those static inline routines reference
are at issue.

For totally different reasons, though, it's worth revisiting our
initialization policy for OFFSET vars.  For any DSO other than the Clownfish
core, we should avoid assigning to them in order to save space, as all OFFSET
vars in every extension will have to be bootstrapped anyway.

Marvin Humphrey

View raw message