56 votes

Comment effectuer des opérations atomiques sur Linux?

Tous les OS Modernes offre aujourd'hui quelques opérations atomiques:

  • Windows a Interlocked* API
  • FreeBSD a <machine/atomic.h>
  • Solaris a <atomic.h>
  • Mac OS X a <libkern/OSAtomic.h>

Rien de tel pour Linux?

  • J'ai besoin de travailler sur la plupart des Linux pris en charge les plates-formes, y compris: x86, x86_64 et les bras.
  • J'en ai besoin pour travailler sur au moins GCC et Intel Compilateur.
  • Je n'ai pas besoin d'utiliser la 3ème par la bibliothèque comme glib ou qt.
  • J'en ai besoin pour travailler en C++ (C pas obligatoire)

Questions:

  • GCC atomique les builtins __sync_* ne sont pas pris en charge sur toutes les plateformes (BRAS) et ne sont pas pris en charge par le compilateur Intel.
  • Autant que je sache, <asm/atomic.h> ne doit pas être utilisé dans l'espace utilisateur et je n'ai pas réussi du tout. Aussi, je ne sais pas si cela pourrait fonctionner avec les processeurs Intel compilateur.

Toutes les suggestions?

Je sais qu'il y a de nombreuses questions, mais certains d'entre eux du point de __sync* ce qui n'est pas possible pour moi (BRAS) et un point d' asm/atomic.h.

Peut-être il ya une ligne bibliothèque de l'assemblée qui fait cela pour GCC (ICC soutient gcc assemblée)?

Edit:

Il y a une solution très partielle pour les opérations d'ajout seulement (permet de mettre en œuvre atomique en vente libre, mais pas de blocage de libre-structures qui nécessitent des CAS):

Si vous utilisez libstc++ (Intel Compilateur utilise libstdc++), alors vous pouvez utiliser __gnu_cxx::__exchange_and_add que définie à l' <ext/atomicity.h> ou <bits/atomicity.h>. Dépend de la version de compilateur.

Cependant, je voudrais encore voir quelque chose qui prend en charge les SAE.

19voto

Noah Watkins Points 2179

Des projets sont à l'aide de ceci:

http://packages.debian.org/source/sid/libatomic-ops

Si vous voulez des opérations simples comme CAS, ne pouvez-vous pas tout simplement utiliser l'arc des implémentations spécifiques hors du noyau, et de faire de l'arche de contrôles dans l'espace utilisateur avec les autotools/cmake? Aussi loin que l'octroi de licences va, même si le noyau est en GPL, je pense qu'il est possible de soutenir que la assembly en ligne de ces opérations est fourni par Intel/AMD, pas que le noyau a une licence. Ils ont juste arriver à être dans une forme aisément accessible dans le source du noyau.

13voto

kevinarpe Points 2902

Cette question est de trois ans maintenant, mais les normes récentes (depuis 2011) de C & C++ maintenant spécifier les opérations atomiques:

Quel que soit, votre plate-forme ou le compilateur ne peut pas soutenir ces nouvelles têtes et des fonctionnalités.

3voto

asveikau Points 16871

Darn. J'allais suggérer la GCC primitives, puis vous avez dit qu'ils étaient hors de portée. :-)

Dans ce cas, je ferais une #ifdef pour chaque architecture/compilateur combinaison que vous aimez et le code de l'asm inline. Et peut-être vérifier pour __GNUC__ ou d'une même macro et d'utiliser GCC primitives s'ils sont disponibles, parce qu'il se sent tellement plus droit à l'utilisation de ceux-ci. :-)

Vous allez avoir beaucoup de duplication et il peut être difficile de vérifier l'exactitude, mais cela semble être la façon dont beaucoup de projets à faire, et j'ai eu de bons résultats avec elle.

Certains pièges qui ont peu de moi dans le passé: lorsque vous utilisez GCC, n'oubliez pas les "asm " et clobbers pour volatile et , etc.

1voto

Luc Hermitte Points 14171

Coup de pouce, qui a non intrusive de licence, et d'autres cadres offrent déjà un portable atomique compteurs -- tant qu'ils sont pris en charge sur la plate-forme cible.

Troisième partie les bibliothèques sont bonnes pour nous. Et si, pour d'étranges raisons pour lesquelles votre entreprise ne vous interdit de les utiliser, vous pouvez toujours avoir un oeil à la façon de procéder (tant que le permis et des licences pour votre usage) pour mettre en œuvre ce que vous cherchez.

1voto

Jens Gustedt Points 40410

J'ai récemment fait une mise en œuvre d'une telle chose et j'ai été confronté aux mêmes difficultés que vous. Ma solution a été de essentiellement les suivantes:

  • essayez de détecter la gcc avec les builtins la fonction macro
  • si ne sont pas disponibles juste en œuvre quelque chose comme cmpxch avec __asm__ pour les autres architectures (ARM est un peu plus compliqué que cela). Juste le faire pour une taille possible, l'e.g sizeof(int).
  • mettre en œuvre toutes les autres fonctionnalités sur le dessus de cela un ou deux primitives avec inline fonctions

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X