2

I have a piece of C/C++ code that uses __thread keyword for thread local storage but having trouble getting it compiled on 64-bit Solaris Sparc with g++ (version 4.0.2), while it compiles and runs OK on linux with g++34 compiler. Here is an example of source code:

__thread int count = 0;

Compiler info from 'g++ -dumpversion' command returns '4.0.2' and 'g++ -dumpmachine' shows 'sparc-sun-solaris2.8'. 'uname -a' displays 'SunOS devsol1 5.9 Generic_118558-26 sun4u sparc SUNW,UltraAX-i2'.

The error message while running make with g++ is: "error: thread-local storage not supported for this target", and compiler option I am using is

 -m64    -g -fexceptions -fPIC     -I../fincad -I/usr/java_1.6.0_12/include -I/usr/java_1.6.0_12/include/solaris -I/opt/csw/gcc4/lib/sparcv9 -I/opt/csw/gcc4/lib/gcc/sparc-sun-solaris2.8/4.0.2/sparcv9 -I. -I/usr/include -I/usr/include/iso -I/usr/local/include

Any help is very much appreciated as I have being struggling on this over the weekend and am facing a deadline.

Thanks, Charles

VividD
  • 10,456
  • 6
  • 64
  • 111
Charles
  • 21
  • 1
  • 2

3 Answers3

2

You can ignore the gcc-specific thread-specific storage and use posix thead-specific storage. It should work and it's not gnu-specific. There's an example on the sun site.

Here's a condensed example from ibm. Obviously you'd want to use more than one thread.

pthread_key_t   tlsKey = 0;

int main(int argc, char **argv)
  rc = pthread_key_create(&tlsKey, globalDestructor);
  /* The key can now be used from all threads */

  // Each thread can now use the key:
  char *myThreadDataStructure;
  void                 *global;

  myThreadDataStructure = malloc(15);//your data structure
  pthread_setspecific(tlsKey, myThreadDataStructure);   

  /* Get the data back */    

  global  = pthread_getspecific(tlsKey);


  free (myThreadDataStructure);
  rc = pthread_key_delete(tlsKey);
}
alanc
  • 4,102
  • 21
  • 24
Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
  • It works great so far, on both linux and solaris 64-bit environment. Compiles like a charm. Still waiting for test to finish, but it looks very promising. On a side note, how does posix thead-specific storage compares with gnu's in terms of performance. I haven't noticed anything dramatic during my test, but am interested in the aspect. Another commenter mentioned thread_specific_ptr has noticeable performance penalty. – Charles Nov 08 '10 at 16:23
  • Honestly I've never used the gnu extensions. I'd be curious to hear how it works though. – Paul Rubel Nov 08 '10 at 16:42
1

You can try adding the -pthread command-line option to g++: this options means, in GCC parlance: "do everything required for POSIX threading support". This might unlock support for __thread.

Thread-local storage with __thread requires some specific system support, in the compiler but also in the linkers (both the static linker, invoked at the end of the compilation, and the dynamic linker, when the program is executed). I do not know whether your specific combination (a rather old g++ with a rather old Solaris) is supported (some googling shows me that some people can use it with an older gcc [3.4.3] with a newer Solaris [10]). If it is not supported, you can use the POSIX / Single Unix functions pthread_key_create(), pthread_setspecific() and pthread_getspecific(). They are somewhat slower, and not nearly as convenient, as the __thread qualifier, but at least they work.

Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
0

You could implement this in a portable way using thread_specific_ptr from Boost.Thread.

If nothing else, you should be able to work out how to do this on Solaris using that as a reference.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • `thread_specific_ptr` has a high price tag, compared with the traditional TLS (which is almost as fast as accessing a standard global/static variable). – valdo Nov 08 '10 at 14:38