JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris 11.1 リンカーとライブラリガイド     Oracle Solaris 11.1 Information Library (日本語)
このドキュメントの評価
search filter icon
search icon

ドキュメントの情報

はじめに

パート I リンカーおよび実行時リンカーの使用

1.  Oracle Solaris リンカーの紹介

2.  リンカー

3.  実行時リンカー

4.  共有オブジェクト

パート II クイックリファレンス

5.  リンカーのクイックリファレンス

パート III 詳細情報

6.  直接結合

7.  システムのパフォーマンスを最適化するオブジェクトの構築

8.  mapfile

9.  インタフェースおよびバージョン管理

10.  動的ストリングトークンによる依存関係の確立

11.  拡張性メカニズム

パート IV ELF アプリケーションバイナリインタフェース

12.  オブジェクトファイル形式

13.  プログラムの読み込みと動的リンク

14.  スレッド固有ストレージ (TLS)

C/C++ プログラミングインタフェース

スレッド固有ストレージ (TLS) セクション

スレッド固有ストレージの実行時の割り当て

プログラムの起動

スレッドの作成

起動後の動的読み込み

スレッド固有ストレージブロックの遅延割り当て

スレッド固有ストレージのアクセスモデル

SPARC: スレッド固有変数へのアクセス

SPARC: General Dynamic (GD)

SPARC: Local Dynamic (LD)

32 ビット SPARC: Initial Executable (IE)

64 ビット SPARC: Initial Executable (IE)

SPARC: Local Executable (LE)

SPARC: スレッド固有ストレージの再配置のタイプ

32 ビット x86: スレッド固有変数へのアクセス

32 ビット x86: General Dynamic (GD)

x86: Local Dynamic (LD)

32 ビット x86: Initial Executable (IE)

32 ビット x86: Local Executable (LE)

32 ビット x86: スレッド固有ストレージの再配置のタイプ

x64: スレッド固有変数へのアクセス

x64: General Dynamic (GD)

x64: Local Dynamic (LD)

x64: Initial Executable (IE)

x64: Local Executable (LE)

x64: スレッド固有ストレージの再配置のタイプ

パート V 付録

A.  リンカーとライブラリのアップデートおよび新機能

B.  System V Release 4 (バージョン 1) Mapfile

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

スレッド固有ストレージの実行時の割り当て

TLS は、プログラムの存続中に、次の 3 つの機会に作成されます。

スレッド固有データストレージは、図 14-1 に示すように実行時に配置されます。

図 14-1 スレッド固有ストレージの実行時のレイアウト

image:スレッド固有ストレージの実行時のレイアウト。

プログラムの起動

プログラムの起動時に、実行システムはメインスレッド用の TLS を作成します。

まず実行時リンカーが、読み込まれたすべての動的オブジェクト (動的な実行可能ファイルを含む) の TLS テンプレートを論理的に結合し、単一の静的なテンプレートとしてまとめます。各動的オブジェクトの TLS テンプレートには、結合されたテンプレート内のオフセット tlsoffsetm が次のように割り当てられます。

tlssizem+1 は動的オブジェクト m の割り当てテンプレートのサイズで、 alignm+1 は整列です。ここで、1 <= m <= M であり、M は読み込まれる動的オブジェクトの合計数です。round(offset, align) 関数は、align の次の倍数に丸められたオフセットを返します。

次に、実行時リンカーは、起動時の TLS に必要な割り当てサイズの tlssizeS を計算します。このサイズは、tlsoffset M512 バイトを加えた値に等しくなります。この加算により、静的な TLS 参照のバックアップ予約が得られます。静的な TLS 参照を作成し、プロセスの初期化後に読み込まれる共有オブジェクトは、このバックアップ予約に割り当てられます。ただし、この予約のサイズは固定および限定されています。また、この予約が対応しているのは、初期化されていない TLS データ項目用のストレージの提供だけです。柔軟性を最大限高めるため、動的な TLS モデルを使用して、共有オブジェクトがスレッドローカル変数を参照するようにしてください。

計算された TLS サイズ tlssizeS に関連付けられる静的な TLS 領域は、スレッドポインタ tpt の直前に配置されます。TLS データに対するアクセスは、tpt からの減算にもとづいて行われます。

静的な TLS 領域は、初期化レコードのリンクリストに関連付けられます。このリスト内の各レコードは、読み込まれた動的オブジェクトごとにその TLS 初期化イメージを記述するものです。各レコードには、次のフィールドが含まれています。

スレッドライブラリは、この情報を使用して初期スレッドにストレージを割り当てます。このストレージが初期化され、初期スレッド用に動的な TLS ベクトルが作成されます。

スレッドの作成

初期スレッドと、新しく作成されるスレッドに対して、スレッドライブラリは読み込まれる動的オブジェクトごとに新しい TLS ブロックを割り当てます。ブロックは、個別に割り当てられることも、単一の連続ブロックとして割り当てられることもあります。

各スレッド t は関連するスレッドポインタ tpt を持ち、このポインタはスレッド制御ブロック TCB を指します。スレッドポインタ tp には、常に、現在動作しているスレッドの tpt の値が含まれます。

続いてスレッドライブラリは、現在のスレッド t のためにポインタのベクトル dtvt を作成します。各ベクトルの最初の要素には、ベクトルを拡張すべきタイミングを決定するために使用される生成番号 gent が入ります。「スレッド固有ストレージブロックの遅延割り当て」を参照してください。

ベクトル内の残りの各要素 dtvt,m は、動的オブジェクト m に属する TLS 用に予約されたブロックへのポインタです。

起動後動的に読み込まれたオブジェクトについては、スレッドライブラリは TLS ブロックの割り当てを延期します。割り当ては、読み込まれたオブジェクト内で TLS 変数に対して最初の参照が行われる時に発生します。割り当てが延期されたブロックの場合、ポインタ dtvt,m は実装が定める特別な値に設定されます。


注 - 実行時リンカーは、ベクトル内の単一の要素 dtvt,1 を共有するために、すべての起動オブジェクトの TLS テンプレートをグループ化できます。このグループ化によって、前述のオフセット計算や初期化レコードのリストの作成が影響を受けることはありません。しかし、次のセクションでは、M の値 (オブジェクトの合計数) は値 1 から始まっています。


続いて、スレッドライブラリが、新しいストレージブロック内の対応する場所に初期化イメージをコピーします。

起動後の動的読み込み

動的な TLS だけが含まれる共有オブジェクトは、プロセスの起動に続いて無制限に読み込むことができます。実行時リンカーは、初期化レコードのリストを拡張して新しいオブジェクトの初期化テンプレートを含めます。新しいオブジェクトには、インデックス m = M + 1 が与えられます。カウンタ M1 ずつ増えていきます。しかし、新しい TLS ブロックの割り当ては、それらが実際に参照されるまで延期されます。

動的な TLS だけが含まれる共有オブジェクトの読み込みが解除されると、その共有オブジェクトが使用している TLS ブロックは解放されます。

静的な TLS が含まれる共有オブジェクトは、プロセスの起動に続いて一定の制限内で読み込むことができます。静的な TLS 参照を満たすことができるのは、残りのバックアップ TLS 予約からだけです。「プログラムの起動」を参照してください。この予約のサイズは制限されています。また、この予約で提供できるのは、初期化されていない TLS データ項目用のストレージだけです。

静的な TLS を含む共有オブジェクトは、読み込み解除されません。静的な TLS 処理の結果として、共有オブジェクトには削除不可のタグが付けられます。

スレッド固有ストレージブロックの遅延割り当て

動的な TLS モデルでは、スレッド t がオブジェクト m の TLS ブロックにアクセスする必要が生じた場合、コードは dtv t を更新し、TLS ブロックの初期割り当てを行います。スレッドライブラリは、動的な TLS 割り当てが行えるように、次のインタフェースを提供します。

typedef struct {
    unsigned long ti_moduleid;
    unsigned long ti_tlsoffset;
} TLS_index;

extern void *__tls_get_addr(TLS_index *ti);     (SPARC and x64)
extern void *___tls_get_addr(TLS_index *ti);    (32–bit x86)

注 - この関数の SPARC 定義と 64ビットの x86 定義は、同一の関数シグニチャーを持ちます。しかし 32 ビットの x86 バージョンは、スタック上で引数を渡すデフォルトの呼び出し規約を使用しません。代わりに 32 ビットの x86 バージョンは、より効率の良い %eax レジスタによって引数を渡します。この代替呼び出し手法を使用することを示すため、32 ビットの x86 関数名にはその先頭に 3 つの下線が付いています。


tls_get_addr() の両バージョンとも、スレッドごとの生成カウンタ gent を調べ、ベクトルが更新を必要としていないかを確認します。ベクトル dtvt が古い場合、ルーチンがベクトルを更新し、必要に応じ、追加エントリ用のスペースを確保するため再割り当てを行います。続いてこのルーチンは、dtvt,m に対応する TLS ブロックがすでに割り当てられているかを調べます。ベクトルが割り当てられていない場合、このルーチンはブロックの割 り当てと初期化を行います。このルーチンは、実行時リンカーが提供する初期化レコードリスト内の情報を使用します。ポインタ dtv t,m は、割り当てられたブロックを指すように設定されます。ルーチンは、ブロック内の指定されたオフセットへのポインタを返します。