各 TLS 参照は、次のアクセスモデルのどれかになります。ここでは、もっとも一般的なモデル (しかし最適化の程度はもっとも低い) から順に、もっとも高速なモデル (しかし制限度は高い) へと並んでいます。
このモデルでは、共有オブジェクトまたは動的実行可能ファイルから、すべての TLS 変数を参照できます。このモデルでは、TLS ブロックが特定のスレッドからはじめて参照される時まで、このブロックの割り当てを延期することもできます。
このモデルは、GD モデルを最適化したものです。コンパイラが、構築されるオブジェクト内で変数がローカルに結合されているか、あるいは保護されていると判断することがあります。この場合、コンパイラは、動的な tlsoffset を静的に結合してこのモデルを使用するように、リンカーに指示します。このモデルにより、GD モデルを上回る性能が得られます。dtv()0,m のアドレスの確認は、関数ごとに tls_get_addr を 1 度呼び出すだけです。リンク編集時に結合される動的な TLS オフセットは、参照ごとに dtv0,m アドレスに追加されます。
このモデルは、初期の静的な TLS テンプレートの一部として利用できる TLS 変数だけを参照できます。このテンプレートは、プロセスの起動時に使用できるすべての TLS ブロック、および小規模なバックアップ予約で構成されます。プログラムの起動を参照してください。このモデルでは、変数 x の、スレッドポインタからの相対オフセットは、x の GOT エントリ内に保存されます。
このモデルでは、初期プロセスの起動後に、遅延読み込み、フィルタ、dlopen(3C) などによって読み込まれる共有ライブラリから、限定された数の TLS 変数を参照できます。このアクセスは、固定のバックアップ予約から満たされます。この予約で提供できるのは、初期化されていない TLS データ項目用のストレージだけです。柔軟性を最大限高めるため、動的な TLS モデルを使用して、共有オブジェクトがスレッドローカル変数を参照するようにしてください。
このモデルは、動的実行可能ファイルの TLS ブロックの一部である TLS 変数だけを参照できます。リンカーは、動的な再配置や GOT の参照を別途行うことなく、スレッドポインタからの相対オフセットを静的に計算します。このモデルを使用して動的実行可能ファイルの外部に存在する変数を参照することはできません。
リンカーは、妥当と判断する場合は、比較的一般的なアクセスモデルから、より最適化されたモデルへとコードを移行できます。この移行は、独特な TLS 再配置を使用することで行えます。これらの再配置は、更新を要求するだけでなく、どの TLS アクセスモデルが使用されているかの特定もします。
作成されるオブジェクトのタイプとともに TLS アクセスモデルを認識することで、リンカーは変換を実行できます。たとえば、GD アクセスモデルを使用している再配置可能オブジェクトが、動的実行可能ファイルにリンクされているとします。この場合、リンカーは IE アクセスモ デルまたは LE アクセスモデルを使用して参照を適宜移行できます。そのあとで、そのモデルに必要な再配置が行われます。
次の図は、それぞれのアクセスモデルと、あるモデルから別のモデルにどのように移行するかを示しています。
図 14-2 スレッド固有ストレージのアクセスモデルと移行