2010-11-08 7 views
2

J'ai un morceau de code C/C++ qui utilise le mot-clé __thread pour le stockage local de thread, mais qui a du mal à le compiler sur Solaris Sparc 64 bits avec g ++ (version 4.0.2), alors qu'il compile et s'exécute sous Linux avec le compilateur g ++ 34. Voici un exemple de code source:comment compiler thread local de stockage (TLS) sur 64 bits solaris sparc avec g ++

__thread int count = 0; 

information du compilateur de 'g ++ -dumpversion' commande retourne de la 4.0.2 »et 'g ++ -dumpmachine' 'sparc-soleil solaris2.8 montre les chiffres. 'uname -a' affiche 'SunOS devsol1 5.9 Generic_118558-26 sun4u sparc SUNW, UltraAX-i2'.

Le message d'erreur lors de l'exécution de make avec g ++ est: « erreur: stockage thread local non pris en charge pour cet objectif », et l'option du compilateur J'utilise est

-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 

Toute aide est très appréciée comme je avoir du mal à ce sujet au cours du week-end et je suis confronté à une date limite.

Merci, Charles

+0

est-ce que http://www.opengroup.org/onlinepubs/009695399/functions/pthread_setspecific.html fonctionne? – Anycorn

Répondre

0

Vous pourriez mettre en œuvre cette manière portable en utilisant thread_specific_ptr from Boost.Thread. Si rien d'autre, vous devriez être capable de trouver comment faire cela sur Solaris en utilisant cela comme référence.

+0

'thread_specific_ptr' a un prix élevé, comparé au traditionnel TLS (qui est presque aussi rapide que l'accès à une variable standard/statique standard). – valdo

2

Vous pouvez ignorer le stockage spécifique à un thread spécifique à gcc et utiliser le stockage spécifique au thème posix. Cela devrait fonctionner et ce n'est pas spécifique à GNU. Il y a un exemple sur le sun site. Voici un exemple condensé de ibm. Évidemment, vous voudrez utiliser plus d'un 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); 
} 
+0

Cela fonctionne très bien jusqu'à présent, sur les environnements Linux 64 bits et Linux. Compile comme un charme. Toujours en attente d'un test pour terminer, mais cela semble très prometteur. D'un autre côté, comment le stockage spécifique de posix thead se compare-t-il aux gnu en termes de performance. Je n'ai rien remarqué de dramatique pendant mon test, mais je m'intéresse à l'aspect. Un autre commentateur mentionné thread_specific_ptr a une pénalité de performance notable. – Charles

+0

Honnêtement, je n'ai jamais utilisé les extensions GNU. Je serais curieux d'entendre comment cela fonctionne bien. –

1

Vous pouvez essayer d'ajouter l'option de ligne de commande -pthread g ++: cette option signifie, dans le langage GCC: « faire tout le nécessaire pour le support des threads POSIX ». Ce pourrait déverrouiller le support pour __thread.

Le stockage local de threads avec __thread nécessite un support système spécifique, dans le compilateur mais aussi dans les liens (l'éditeur de liens statique, invoqué à la fin de la compilation, et le lieur dynamique, lorsque le programme est exécuté). Je ne sais pas si votre combinaison spécifique (un g ++ assez ancien avec un Solaris plutôt ancien) est supportée (certains googling me montre que certaines personnes peuvent l'utiliser avec un gcc plus ancien [3.4.3] avec un Solaris plus récent [10]). S'il n'est pas pris en charge, vous pouvez utiliser les fonctions POSIX/Single Unix pthread_key_create(), pthread_setspecific() et pthread_getspecific(). Ils sont un peu plus lent, et pas aussi pratique, que le qualificatif __thread, mais au moins ils fonctionnent.

Questions connexes