Thread local storage

Einer der Gründe, warum ich auf meinem Weg zu C++ außerhalb von Betriebssystemen stolpere, liegt am “thread local storage”.

Denn wo werden Exception-Daten abgelegt?
Offenbar genau dort!

Und was mir fehlt ist ein funktionierender Nachbau von __tls_get_addr.


Egal wie “free-standing” man sein Projekt kompiliert, ein Linux-GCC mischt zwangsläufig Linux-Standards in den Code. Und das betrifft vor allem C++ Exceptions und das dazugehörige Runtime-Type-Information (RTTI) System.

Wenn nämlich in einem Thread eine Exception fliegt, muss der Callstack rückabgewickelt werden, bis zum letzten installierten Exception Handler und auf dem Weg dorthin müssen alle herumliegenden Objekte freigegeben werden.

Das erfordert den Zugriff auf zwei OS-nahe Ressourcen:

  • Die ELF-Sections mit Cleanup-Codes, die an das Speicherlayout angepasst sind
  • Der Thread-local-storage, in dem die gültigen Exception Handler verlinkt sind.

Beide Ressourcen erfordern eine tiefe Kenntnis und “Konformität” zu den Strukturen, wie Linux und die jeweilige C-Lib damit umgehen.
Und das ist unter Windows leider auch nicht anders.

Noch krasser wird die Geschichte, weil die neueren C-Standards ab C11 mit der _Thread_local Speicherklasse einem jeden Datentypen ermöglichen, zum Thread gehören zu können und im Hintergrund nötige Anpassungen machen.

Offiziell erreicht man den Thread-local-storage über entsprechende APIs, wie pthread_key_create() und pthread_get/setspecific() oder TlsAlloc und TlsSetValue unter Windows.

Doch wie sich zeigt umgehen die internen Funktionen des GCC die POSIX API und wollen mit APIs wie __tls_get_addr() arbeiten und nutzen dann ihr Geheimwissen und adressieren die Unterfelder dann direkt.

Ich habe nun länger nach Infos zu all diesen Details gesucht und interessante Dinge über den TCB (thread control block) und den DTV (dynamic thread vector) gelesen
… aber geholfen hat mir das leider nicht.

Fazit: Keinen Thread-local-storage nutzen!

Was ich mit C++ Exception machen soll, weiß ich noch nicht, aber ich habe zumindest gelernt, dass der leichtsinnige Einsatz von _Thread_local kontraproduktiv sein kann.

Für mein UEFI Thema führt offenbar wirklich kein Weg daran vorbei, den GCC und seine Kernbibliotheken neu zu bauen, denn dort hat man ein paar Möglichkeiten, die Arbeitsweise zu beeinflussen.
Es gibt schließlich auch Mikrocontroller-Zielplattformen, die all den Schnickschnack auch nicht unterstützen.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!