This is the mail archive of the cygwin mailing list for the Cygwin 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]

Re: limitations of TLS using GCC's __thread keyword and Cygwin


On 05/09/2012 4:05 AM, VÃclav Zeman wrote:
On 4 September 2012 23:51, Christopher Faylor wrote:
On Tue, Sep 04, 2012 at 10:50:09PM +0200, V??clav Zeman wrote:
On 09/04/2012 04:39 PM, Ryan Johnson wrote:
On 04/09/2012 8:58 AM, V??clav Zeman wrote:
Hi.

I am am porting a library that can use the __thread keyword in its
internals to provide thread local storage. Now, with MSVC there is a
limitation on pre-Vista Windows (see [1]) that DLLs using
__declspec(thread) (MSVC equivalent of GCC's __thread) cannot be
loaded using LoadLibrary() because pre-Vista Windows allocate the TLS
declared that way only on process startup. Vista and later Windows do
not seem to have the limitation. Since Cygwin officially still
supports at least Windows XP, I want to provide a library that works
there as well.

Does Cygwin's GCC and its TLS emulation work around this problem? IOW,
are Cygwin DLLs using TLS declared using __thread keyword safe to be
loaded using LoadLibrary()/dlopen() or are they not safe to be loaded
that way?

[1] http://msdn.microsoft.com/en-us/library/2s9wt68x.aspx

I suspect it's not a problem, but if I were you I'd write a simple
test program to see. Unfortunately, TLS in general seems broken on my
machine when I tried it, but that might be due to my home-brew gcc
being configured wrong or something.
I would have done that already but I do not have any Windows XP machine
to try this on.
I don't believe that __thread is implemented on Cygwin.
Adjust your beliefs. :) It is implemented and it works correct as far
as I can tell. It implements TLS using calls to __emutls* routines.
What I am unclear about is whether the implemention works around the
limitation mentioned in the MSDN link or not.
GCC collects all TLS "slots" into a giant struct and then associates one copy of that struct with each thread. On targets without ABI support for TLS, the association is made using a single posix thread-local key. See gcc sources, libgcc/emutls.c for gory details.

Because the giant-TLS-struct is associated with a single Windows TLS slot, there should be no particular limitations on its use compared with linux.

Note, however, that you can't directly access TLS of a dlopen'd object: dlsym looks for a "normal" variable, failing because it doesn't exist. However, code inside the dlopened object can access its TLS correctly (so you could write a wrapper to return the TLS pointer), and dlopened objects can also correctly access TLS declared in the main object if you link them properly [1].

[1] http://cygwin.com/faq.html#faq.programming.unix-gui

STC attached, compile with:

g++ -Wl,--export-all-symbols,--out-implib,liba.exe.a tls.cpp && g++ -shared ext-tls.cpp liba.exe.a -oext-tls.dll && ./a

Caveat: I'm not completely sure how the dlopen'd file creates its TLS block, because there's no way it can share the same one as the main app. If it needs to create a new Windows TLS slot at load time, you may hit problems under Windows XP; I got some strange behavior running the STC under XP compatability mode on my Win7 machine (though oddly, it was the main object that broke; the dlopen'd object worked correctly).

Ryan

Attachment: tls.cpp
Description: Text document

Attachment: ext-tls.cpp
Description: Text document

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]